@case-framework/survey-assistant 0.4.0 → 0.6.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/README.md +8 -0
- package/dist/attachments-B0hg3vpT.mjs +11 -0
- package/dist/attachments-B0hg3vpT.mjs.map +1 -0
- package/dist/authoring-references-CW38pYzK.mjs +115 -0
- package/dist/authoring-references-CW38pYzK.mjs.map +1 -0
- package/dist/{capabilities-CnsVuJ1k.d.mts → capabilities-DVTfogjv.d.mts} +1 -1
- package/dist/{capabilities-CnsVuJ1k.d.mts.map → capabilities-DVTfogjv.d.mts.map} +1 -1
- package/dist/capabilities-default.d.mts +1 -1
- package/dist/capabilities-default.d.mts.map +1 -1
- package/dist/capabilities-default.mjs +39 -9
- package/dist/capabilities-default.mjs.map +1 -1
- package/dist/{constants-CFUWrRtl.mjs → constants-0UHGFcRJ.mjs} +1 -1
- package/dist/{constants-CFUWrRtl.mjs.map → constants-0UHGFcRJ.mjs.map} +1 -1
- package/dist/{constants-k1b_evIb.d.mts → constants-BMGTgfjv.d.mts} +4 -4
- package/dist/{constants-k1b_evIb.d.mts.map → constants-BMGTgfjv.d.mts.map} +1 -1
- package/dist/{controller-proxy-jWIPOZAv.mjs → controller-proxy-DMTqer6T.mjs} +1 -1
- package/dist/{controller-proxy-jWIPOZAv.mjs.map → controller-proxy-DMTqer6T.mjs.map} +1 -1
- package/dist/{controller-proxy-quQjtA7j.d.mts → controller-proxy-mRvez2qw.d.mts} +3 -3
- package/dist/{controller-proxy-quQjtA7j.d.mts.map → controller-proxy-mRvez2qw.d.mts.map} +1 -1
- package/dist/{digest-Dyjch_sC.d.mts → digest-SJmoYVaK.d.mts} +2 -2
- package/dist/{digest-Dyjch_sC.d.mts.map → digest-SJmoYVaK.d.mts.map} +1 -1
- package/dist/digest.d.mts +1 -1
- package/dist/{engine-BvfUx_Jx.mjs → engine-CQwOAcwK.mjs} +167 -24
- package/dist/engine-CQwOAcwK.mjs.map +1 -0
- package/dist/engine.d.mts +3 -3
- package/dist/engine.mjs +3 -3
- package/dist/{fair-guidance-CEdJYccK.mjs → fair-guidance-CRYCRxQm.mjs} +1 -1
- package/dist/{fair-guidance-CEdJYccK.mjs.map → fair-guidance-CRYCRxQm.mjs.map} +1 -1
- package/dist/{form-authoring-BQh40yDb.mjs → form-authoring-kQDgC5oz.mjs} +1 -1
- package/dist/{form-authoring-BQh40yDb.mjs.map → form-authoring-kQDgC5oz.mjs.map} +1 -1
- package/dist/{index-biZnRl-h.d.mts → index-B0lxsAzx.d.mts} +10 -6
- package/dist/index-B0lxsAzx.d.mts.map +1 -0
- package/dist/{index-BDp6S7r9.d.mts → index-BS-Xjk1h.d.mts} +4 -4
- package/dist/{index-BDp6S7r9.d.mts.map → index-BS-Xjk1h.d.mts.map} +1 -1
- package/dist/{index-r8HVcn5b.d.mts → index-D6nqkz0O.d.mts} +49 -8
- package/dist/{index-r8HVcn5b.d.mts.map → index-D6nqkz0O.d.mts.map} +1 -1
- package/dist/{index-8x1Eqlnz.d.mts → index-DvTqML-0.d.mts} +10 -5
- package/dist/index-DvTqML-0.d.mts.map +1 -0
- package/dist/{lifecycle-DWv5CiSu.d.mts → lifecycle-BmGAIUlv.d.mts} +2 -2
- package/dist/{lifecycle-DWv5CiSu.d.mts.map → lifecycle-BmGAIUlv.d.mts.map} +1 -1
- package/dist/{memory-thread-repository-xBZOog_q.mjs → memory-thread-repository-CjFGVNZh.mjs} +44 -13
- package/dist/{memory-thread-repository-xBZOog_q.mjs.map → memory-thread-repository-CjFGVNZh.mjs.map} +1 -1
- package/dist/protocol.d.mts +4 -4
- package/dist/protocol.mjs +2 -1
- package/dist/{react-CY6N7lVi.mjs → react-Dqlmasrs.mjs} +2 -2
- package/dist/{react-CY6N7lVi.mjs.map → react-Dqlmasrs.mjs.map} +1 -1
- package/dist/react-integration.d.mts +1 -1
- package/dist/react-integration.mjs +1 -1
- package/dist/react.d.mts +2 -2
- package/dist/react.mjs +2 -2
- package/dist/{request-context-DixY5DYu.mjs → request-context-BjTHNcDd.mjs} +2 -2
- package/dist/{request-context-DixY5DYu.mjs.map → request-context-BjTHNcDd.mjs.map} +1 -1
- package/dist/{request-guardrails-h4t6u8mP.mjs → request-guardrails-TmgQtqp4.mjs} +5 -12
- package/dist/request-guardrails-TmgQtqp4.mjs.map +1 -0
- package/dist/server-agent.d.mts +9 -7
- package/dist/server-agent.d.mts.map +1 -1
- package/dist/server-agent.mjs +8 -6
- package/dist/server-agent.mjs.map +1 -1
- package/dist/server-runtime.d.mts +28 -14
- package/dist/server-runtime.d.mts.map +1 -1
- package/dist/server-runtime.mjs +47 -8
- package/dist/server-runtime.mjs.map +1 -1
- package/dist/server-tasks.d.mts +1 -1
- package/dist/server-tasks.mjs +4 -4
- package/dist/server-tools.d.mts +1 -1
- package/dist/server-tools.mjs +1 -1
- package/dist/server.d.mts +7 -7
- package/dist/server.mjs +6 -6
- package/dist/storage-postgres.d.mts +1 -1
- package/dist/storage-postgres.mjs +4 -1
- package/dist/storage-postgres.mjs.map +1 -1
- package/dist/{tasks-BWmTMXoK.d.mts → tasks-DxzD25Zc.d.mts} +16 -4
- package/dist/tasks-DxzD25Zc.d.mts.map +1 -0
- package/dist/{thread-documents-Dvo6XS7o.d.mts → thread-documents-rmd6nyX9.d.mts} +1 -1
- package/dist/{thread-documents-Dvo6XS7o.d.mts.map → thread-documents-rmd6nyX9.d.mts.map} +1 -1
- package/dist/{thread-handlers-D8gkLfU6.d.mts → thread-handlers-AbQbt4sX.d.mts} +13 -6
- package/dist/{thread-handlers-D8gkLfU6.d.mts.map → thread-handlers-AbQbt4sX.d.mts.map} +1 -1
- package/dist/{tools-TXI8bfzZ.mjs → tools-CFh35R4d.mjs} +14 -6
- package/dist/tools-CFh35R4d.mjs.map +1 -0
- package/dist/ui.css +1 -1
- package/dist/ui.d.mts +3 -3
- package/dist/ui.d.mts.map +1 -1
- package/dist/ui.mjs +198 -83
- package/dist/ui.mjs.map +1 -1
- package/docs/integration.md +37 -3
- package/package.json +2 -2
- package/dist/authoring-references-yyYC4Ydi.mjs +0 -98
- package/dist/authoring-references-yyYC4Ydi.mjs.map +0 -1
- package/dist/engine-BvfUx_Jx.mjs.map +0 -1
- package/dist/index-8x1Eqlnz.d.mts.map +0 -1
- package/dist/index-biZnRl-h.d.mts.map +0 -1
- package/dist/request-guardrails-h4t6u8mP.mjs.map +0 -1
- package/dist/tasks-BWmTMXoK.d.mts.map +0 -1
- package/dist/tools-TXI8bfzZ.mjs.map +0 -1
package/dist/ui.mjs
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jt as parseSurveyAssistantError, l as surveyAssistantTurnFinalSchema, n as SURVEY_ASSISTANT_TURN_FINAL_PART_TYPE } from "./protocol-DJUP4gc0.mjs";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { n as isSurveyAssistantAttachmentMediaType, t as SURVEY_ASSISTANT_ATTACHMENT_MEDIA_TYPES } from "./attachments-B0hg3vpT.mjs";
|
|
4
|
+
import { f as unwrapSurveyAssistantToolOutput, i as createSurveyAssistantThreadClient, l as parseSurveyChangeSet, p as isSurveyAssistantTurnActive, r as useSurveyAssistantModelCatalog, t as useSurveyAssistantSession } from "./react-Dqlmasrs.mjs";
|
|
5
|
+
import { o as connectSurveyAssistantThreadLauncher } from "./controller-proxy-DMTqer6T.mjs";
|
|
5
6
|
import { getToolName, isFileUIPart, isReasoningUIPart, isToolUIPart } from "ai";
|
|
6
7
|
import { createContext, createElement, memo, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
7
|
-
import { Collapsible, Select, Slot } from "radix-ui";
|
|
8
|
+
import { Collapsible, Select, Slot, Tooltip } from "radix-ui";
|
|
8
9
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
9
10
|
import { clsx } from "clsx";
|
|
10
11
|
import { twMerge } from "tailwind-merge";
|
|
@@ -123,9 +124,11 @@ const surveyAssistantEnMessages = {
|
|
|
123
124
|
},
|
|
124
125
|
input: {
|
|
125
126
|
placeholder: "Ask about the survey...",
|
|
126
|
-
attachFiles: "Attach
|
|
127
|
-
dropFiles: "Drop
|
|
128
|
-
|
|
127
|
+
attachFiles: "Attach a PDF, PNG, or JPG",
|
|
128
|
+
dropFiles: "Drop a PDF, PNG, or JPG to attach",
|
|
129
|
+
supportedFiles: "Supported: PDF, PNG, and JPG. Export Word documents as PDF.",
|
|
130
|
+
unsupportedFiles: "{filenames} can't be attached. Supported formats: PDF, PNG, and JPG.",
|
|
131
|
+
wordFilesUnsupported: "Word documents aren't supported. Export {filenames} as PDF, then attach the PDF.",
|
|
129
132
|
removeFile: "Remove {filename}",
|
|
130
133
|
send: "Send message",
|
|
131
134
|
stop: "Stop response",
|
|
@@ -338,9 +341,11 @@ const surveyAssistantNlMessages = {
|
|
|
338
341
|
},
|
|
339
342
|
input: {
|
|
340
343
|
placeholder: "Vraag iets over de survey...",
|
|
341
|
-
attachFiles: "
|
|
342
|
-
dropFiles: "Sleep
|
|
343
|
-
|
|
344
|
+
attachFiles: "Een pdf-, png- of jpg-bestand toevoegen",
|
|
345
|
+
dropFiles: "Sleep een pdf-, png- of jpg-bestand hierheen om het toe te voegen",
|
|
346
|
+
supportedFiles: "Ondersteund: pdf, png en jpg. Exporteer Word-documenten als pdf.",
|
|
347
|
+
unsupportedFiles: "{filenames} kan niet worden toegevoegd. Ondersteunde formaten: pdf, png en jpg.",
|
|
348
|
+
wordFilesUnsupported: "Word-documenten worden niet ondersteund. Exporteer {filenames} als pdf en voeg daarna de pdf toe.",
|
|
344
349
|
removeFile: "{filename} verwijderen",
|
|
345
350
|
send: "Bericht verzenden",
|
|
346
351
|
stop: "Antwoord stoppen",
|
|
@@ -771,9 +776,39 @@ const MessageContent = ({ children, className, ...props }) => /* @__PURE__ */ js
|
|
|
771
776
|
children
|
|
772
777
|
});
|
|
773
778
|
//#endregion
|
|
779
|
+
//#region src/ui/internal/tooltip.tsx
|
|
780
|
+
const TooltipProvider = Tooltip.Provider;
|
|
781
|
+
const Tooltip$1 = Tooltip.Root;
|
|
782
|
+
const TooltipTrigger = Tooltip.Trigger;
|
|
783
|
+
const TooltipContent = ({ className, sideOffset = 6, ...props }) => /* @__PURE__ */ jsx(Tooltip.Portal, { children: /* @__PURE__ */ jsx("div", {
|
|
784
|
+
className: "case-survey-assistant case-survey-assistant-portal",
|
|
785
|
+
children: /* @__PURE__ */ jsx(Tooltip.Content, {
|
|
786
|
+
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),
|
|
787
|
+
sideOffset,
|
|
788
|
+
...props
|
|
789
|
+
})
|
|
790
|
+
}) });
|
|
791
|
+
//#endregion
|
|
774
792
|
//#region src/ui/internal/prompt-input.tsx
|
|
775
|
-
const SUPPORTED_FILE_ACCEPT =
|
|
776
|
-
|
|
793
|
+
const SUPPORTED_FILE_ACCEPT = [
|
|
794
|
+
".pdf",
|
|
795
|
+
".png",
|
|
796
|
+
".jpg",
|
|
797
|
+
".jpeg",
|
|
798
|
+
...SURVEY_ASSISTANT_ATTACHMENT_MEDIA_TYPES
|
|
799
|
+
].join(",");
|
|
800
|
+
const WORD_DOCUMENT_MEDIA_TYPES = new Set([
|
|
801
|
+
"application/msword",
|
|
802
|
+
"application/vnd.ms-word",
|
|
803
|
+
"application/vnd.ms-word.document.macroenabled.12",
|
|
804
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
805
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.template"
|
|
806
|
+
]);
|
|
807
|
+
const getUnsupportedAttachmentKind = ({ name, type }) => {
|
|
808
|
+
if (isSurveyAssistantAttachmentMediaType(type)) return null;
|
|
809
|
+
if (WORD_DOCUMENT_MEDIA_TYPES.has(type.toLowerCase()) || /\.(?:doc|docm|docx|dot|dotm|dotx)$/i.test(name)) return "word";
|
|
810
|
+
return "other";
|
|
811
|
+
};
|
|
777
812
|
const formatFileSize = (size) => {
|
|
778
813
|
if (size < 1024 * 1024) return `${Math.max(1, Math.round(size / 1024))} KB`;
|
|
779
814
|
return `${(size / (1024 * 1024)).toFixed(size < 10 * 1024 * 1024 ? 1 : 0)} MB`;
|
|
@@ -801,7 +836,7 @@ const PromptInput = ({ attachmentsDisabled = false, children, className, onDragE
|
|
|
801
836
|
const [uncontrolledValue, setUncontrolledValue] = useState("");
|
|
802
837
|
const [files, setFiles] = useState([]);
|
|
803
838
|
const [isDraggingFiles, setIsDraggingFiles] = useState(false);
|
|
804
|
-
const [
|
|
839
|
+
const [unsupportedFiles, setUnsupportedFiles] = useState([]);
|
|
805
840
|
const fileDragDepthRef = useRef(0);
|
|
806
841
|
const t = useSurveyAssistantTranslation();
|
|
807
842
|
const value = controlledValue ?? uncontrolledValue;
|
|
@@ -811,10 +846,16 @@ const PromptInput = ({ attachmentsDisabled = false, children, className, onDragE
|
|
|
811
846
|
}, [controlledValue, onValueChange]);
|
|
812
847
|
const addFiles = useCallback((fileList) => {
|
|
813
848
|
const nextFiles = Array.from(fileList ?? []);
|
|
814
|
-
const supportedFiles = nextFiles.filter(
|
|
815
|
-
const
|
|
849
|
+
const supportedFiles = nextFiles.filter((file) => getUnsupportedAttachmentKind(file) === null);
|
|
850
|
+
const rejectedFiles = nextFiles.flatMap((file) => {
|
|
851
|
+
const kind = getUnsupportedAttachmentKind(file);
|
|
852
|
+
return kind ? [{
|
|
853
|
+
kind,
|
|
854
|
+
name: file.name
|
|
855
|
+
}] : [];
|
|
856
|
+
});
|
|
816
857
|
setFiles((currentFiles) => [...currentFiles, ...supportedFiles]);
|
|
817
|
-
|
|
858
|
+
setUnsupportedFiles(rejectedFiles);
|
|
818
859
|
}, []);
|
|
819
860
|
const removeFile = useCallback((index) => {
|
|
820
861
|
setFiles((currentFiles) => currentFiles.filter((_, fileIndex) => fileIndex !== index));
|
|
@@ -825,12 +866,12 @@ const PromptInput = ({ attachmentsDisabled = false, children, className, onDragE
|
|
|
825
866
|
files,
|
|
826
867
|
addFiles,
|
|
827
868
|
removeFile,
|
|
828
|
-
|
|
869
|
+
unsupportedFiles
|
|
829
870
|
}), [
|
|
830
871
|
addFiles,
|
|
831
872
|
files,
|
|
832
873
|
removeFile,
|
|
833
|
-
|
|
874
|
+
unsupportedFiles,
|
|
834
875
|
value
|
|
835
876
|
]);
|
|
836
877
|
const handleSubmit = useCallback(async (event) => {
|
|
@@ -843,7 +884,7 @@ const PromptInput = ({ attachmentsDisabled = false, children, className, onDragE
|
|
|
843
884
|
}, event) === false) return;
|
|
844
885
|
setValue("");
|
|
845
886
|
setFiles([]);
|
|
846
|
-
|
|
887
|
+
setUnsupportedFiles([]);
|
|
847
888
|
}, [
|
|
848
889
|
files,
|
|
849
890
|
onSubmit,
|
|
@@ -903,39 +944,48 @@ const PromptInput = ({ attachmentsDisabled = false, children, className, onDragE
|
|
|
903
944
|
});
|
|
904
945
|
};
|
|
905
946
|
const PromptInputBody = ({ children, className, ...props }) => {
|
|
906
|
-
const { files, removeFile,
|
|
947
|
+
const { files, removeFile, unsupportedFiles } = usePromptInput();
|
|
907
948
|
const t = useSurveyAssistantTranslation();
|
|
949
|
+
const unsupportedWordFileNames = unsupportedFiles.filter((file) => file.kind === "word").map((file) => file.name);
|
|
950
|
+
const unsupportedOtherFileNames = unsupportedFiles.filter((file) => file.kind === "other").map((file) => file.name);
|
|
908
951
|
return /* @__PURE__ */ jsxs("div", {
|
|
909
952
|
className: cn("contents", className),
|
|
910
953
|
...props,
|
|
911
|
-
children: [children, (files.length > 0 ||
|
|
954
|
+
children: [children, (files.length > 0 || unsupportedFiles.length > 0) && /* @__PURE__ */ jsxs("div", {
|
|
912
955
|
className: "flex flex-wrap gap-2 px-3 pb-2",
|
|
913
|
-
children: [
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
className: "
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
956
|
+
children: [
|
|
957
|
+
files.map((file, index) => /* @__PURE__ */ jsxs("div", {
|
|
958
|
+
className: "inline-flex max-w-full items-center gap-2 rounded-md border border-border bg-muted px-2 py-1 text-xs",
|
|
959
|
+
children: [
|
|
960
|
+
/* @__PURE__ */ jsx(FileIcon, { className: "size-3.5 shrink-0 text-muted-foreground" }),
|
|
961
|
+
/* @__PURE__ */ jsx("span", {
|
|
962
|
+
className: "min-w-0 truncate",
|
|
963
|
+
children: file.name
|
|
964
|
+
}),
|
|
965
|
+
/* @__PURE__ */ jsx("span", {
|
|
966
|
+
className: "shrink-0 text-muted-foreground",
|
|
967
|
+
children: formatFileSize(file.size)
|
|
968
|
+
}),
|
|
969
|
+
/* @__PURE__ */ jsxs("button", {
|
|
970
|
+
className: "shrink-0 rounded-sm text-muted-foreground hover:text-foreground",
|
|
971
|
+
onClick: () => removeFile(index),
|
|
972
|
+
type: "button",
|
|
973
|
+
children: [/* @__PURE__ */ jsx(XIcon, { className: "size-3.5" }), /* @__PURE__ */ jsx("span", {
|
|
974
|
+
className: "sr-only",
|
|
975
|
+
children: t("input.removeFile", { filename: file.name })
|
|
976
|
+
})]
|
|
977
|
+
})
|
|
978
|
+
]
|
|
979
|
+
}, `${file.name}-${file.lastModified}-${index}`)),
|
|
980
|
+
unsupportedWordFileNames.length > 0 && /* @__PURE__ */ jsx("div", {
|
|
981
|
+
className: "text-destructive text-xs",
|
|
982
|
+
children: t("input.wordFilesUnsupported", { filenames: unsupportedWordFileNames.join(", ") })
|
|
983
|
+
}),
|
|
984
|
+
unsupportedOtherFileNames.length > 0 && /* @__PURE__ */ jsx("div", {
|
|
985
|
+
className: "text-destructive text-xs",
|
|
986
|
+
children: t("input.unsupportedFiles", { filenames: unsupportedOtherFileNames.join(", ") })
|
|
987
|
+
})
|
|
988
|
+
]
|
|
939
989
|
})]
|
|
940
990
|
});
|
|
941
991
|
};
|
|
@@ -964,28 +1014,38 @@ const PromptInputFooter = ({ className, ...props }) => /* @__PURE__ */ jsx("div"
|
|
|
964
1014
|
const PromptInputAttachmentButton = ({ accept = SUPPORTED_FILE_ACCEPT, className, disabled, onChange, ...props }) => {
|
|
965
1015
|
const { addFiles } = usePromptInput();
|
|
966
1016
|
const t = useSurveyAssistantTranslation();
|
|
967
|
-
return /* @__PURE__ */
|
|
968
|
-
|
|
969
|
-
children: [
|
|
970
|
-
|
|
971
|
-
/* @__PURE__ */
|
|
972
|
-
className: "
|
|
973
|
-
children:
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
1017
|
+
return /* @__PURE__ */ jsx(TooltipProvider, {
|
|
1018
|
+
delayDuration: 300,
|
|
1019
|
+
children: /* @__PURE__ */ jsxs(Tooltip$1, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
|
|
1020
|
+
asChild: true,
|
|
1021
|
+
children: /* @__PURE__ */ jsxs("label", {
|
|
1022
|
+
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),
|
|
1023
|
+
children: [
|
|
1024
|
+
/* @__PURE__ */ jsx(PaperclipIcon, { className: "size-4" }),
|
|
1025
|
+
/* @__PURE__ */ jsx("span", {
|
|
1026
|
+
className: "sr-only",
|
|
1027
|
+
children: t("input.attachFiles")
|
|
1028
|
+
}),
|
|
1029
|
+
/* @__PURE__ */ jsx("input", {
|
|
1030
|
+
accept,
|
|
1031
|
+
className: "sr-only",
|
|
1032
|
+
disabled,
|
|
1033
|
+
multiple: true,
|
|
1034
|
+
onChange: (event) => {
|
|
1035
|
+
addFiles(event.currentTarget.files);
|
|
1036
|
+
onChange?.(event);
|
|
1037
|
+
event.currentTarget.value = "";
|
|
1038
|
+
},
|
|
1039
|
+
type: "file",
|
|
1040
|
+
...props
|
|
1041
|
+
})
|
|
1042
|
+
]
|
|
987
1043
|
})
|
|
988
|
-
|
|
1044
|
+
}), /* @__PURE__ */ jsx(TooltipContent, {
|
|
1045
|
+
align: "start",
|
|
1046
|
+
side: "top",
|
|
1047
|
+
children: t("input.supportedFiles")
|
|
1048
|
+
})] })
|
|
989
1049
|
});
|
|
990
1050
|
};
|
|
991
1051
|
const PromptInputSubmit = ({ className, status, onStop, onClick, ...props }) => {
|
|
@@ -1353,7 +1413,7 @@ const Response = ({ children, className, controls = false, plugins, ...props })
|
|
|
1353
1413
|
code: plugins?.code ?? codeHighlighter
|
|
1354
1414
|
}), [plugins]);
|
|
1355
1415
|
return /* @__PURE__ */ jsx(Streamdown, {
|
|
1356
|
-
className: cn("leading-6", "*:first:mt-0 *:last:mb-0", "[&_a]:text-primary [&_a]:underline [&_a]:underline-offset-2", "[&_blockquote]:my-3 [&_blockquote]:border-l-2 [&_blockquote]:border-border [&_blockquote]:pl-3 [&_blockquote]:text-muted-foreground", "[&_h1]:mb-2 [&_h1]:mt-4 [&_h1]:text-base [&_h1]:font-semibold", "[&_h2]:mb-2 [&_h2]:mt-4 [&_h2]:text-sm [&_h2]:font-semibold", "[&_h3]:mb-1.5 [&_h3]:mt-3 [&_h3]:text-sm [&_h3]:font-semibold", "[&_li]:my-1 [&_ol]:my-2 [&_ol]:list-decimal [&_ol]:pl-5 [&_ul]:my-2 [&_ul]:list-disc [&_ul]:pl-5", "[&_p]:my-2", "**:data-[streamdown=code-block]:my-3 **:data-[streamdown=code-block]:gap-0 **:data-[streamdown=code-block]:overflow-hidden **:data-[streamdown=code-block]:rounded-lg **:data-[streamdown=code-block]:bg-muted/40 **:data-[streamdown=code-block]:p-0", "**:data-[streamdown=code-block-header]:px-2", "**:data-[streamdown=code-block-body]:rounded-none **:data-[streamdown=code-block-body]:border-0 **:data-[streamdown=code-block-body]:border-t **:data-[streamdown=code-block-body]:bg-background **:data-[streamdown=code-block-body]:p-3", "[&_strong]:font-semibold", "[&_table]:my-3 [&_table]:w-full [&_table]:border-collapse [&_td]:border [&_td]:border-border [&_td]:px-2 [&_td]:py-1 [&_th]:border [&_th]:border-border [&_th]:px-2 [&_th]:py-1 [&_th]:text-left [&_th]:font-semibold", className),
|
|
1416
|
+
className: cn("leading-6", "*:first:mt-0 *:last:mb-0", "[&_a]:text-primary [&_a]:underline [&_a]:underline-offset-2", "[&_blockquote]:my-3 [&_blockquote]:border-l-2 [&_blockquote]:border-border [&_blockquote]:pl-3 [&_blockquote]:text-muted-foreground", "[&_h1]:mb-2 [&_h1]:mt-4 [&_h1]:text-base [&_h1]:font-semibold", "[&_h2]:mb-2 [&_h2]:mt-4 [&_h2]:text-sm [&_h2]:font-semibold", "[&_h3]:mb-1.5 [&_h3]:mt-3 [&_h3]:text-sm [&_h3]:font-semibold", "[&_li]:my-1 [&_ol]:my-2 [&_ol]:list-decimal [&_ol]:pl-5 [&_ul]:my-2 [&_ul]:list-disc [&_ul]:pl-5", "[&_p]:my-2", "**:data-[streamdown=inline-code]:text-[length:inherit] **:data-[streamdown=inline-code]:leading-[inherit]", "**:data-[streamdown=code-block]:my-3 **:data-[streamdown=code-block]:gap-0 **:data-[streamdown=code-block]:overflow-hidden **:data-[streamdown=code-block]:rounded-lg **:data-[streamdown=code-block]:bg-muted/40 **:data-[streamdown=code-block]:p-0", "**:data-[streamdown=code-block-header]:px-2", "**:data-[streamdown=code-block-body]:rounded-none **:data-[streamdown=code-block-body]:border-0 **:data-[streamdown=code-block-body]:border-t **:data-[streamdown=code-block-body]:bg-background **:data-[streamdown=code-block-body]:p-3", "[&_strong]:font-semibold", "[&_table]:my-3 [&_table]:w-full [&_table]:border-collapse [&_td]:border [&_td]:border-border [&_td]:px-2 [&_td]:py-1 [&_th]:border [&_th]:border-border [&_th]:px-2 [&_th]:py-1 [&_th]:text-left [&_th]:font-semibold", className),
|
|
1357
1417
|
controls,
|
|
1358
1418
|
plugins: responsePlugins,
|
|
1359
1419
|
...props,
|
|
@@ -1408,6 +1468,13 @@ const getPersistedMessageTurnStatus = (message) => {
|
|
|
1408
1468
|
}
|
|
1409
1469
|
};
|
|
1410
1470
|
//#endregion
|
|
1471
|
+
//#region src/ui/initial-thread-load.ts
|
|
1472
|
+
const getSurveyAssistantInitialThreadLoadState = ({ error, hasSelectedThread, loading }) => {
|
|
1473
|
+
if (loading) return "loading";
|
|
1474
|
+
if (!hasSelectedThread) return error ? "error" : "loading";
|
|
1475
|
+
return null;
|
|
1476
|
+
};
|
|
1477
|
+
//#endregion
|
|
1411
1478
|
//#region src/ui/survey-assistant-panel.tsx
|
|
1412
1479
|
const isRootSurveyItem = (item) => typeof item.config === "object" && item.config !== null && item.config.isRoot === true;
|
|
1413
1480
|
const getAssistantEmptyStateContext = (controller) => {
|
|
@@ -1902,7 +1969,7 @@ const SurveyAssistantHeaderIdentity = ({ indicatorClassName, status, title }) =>
|
|
|
1902
1969
|
})]
|
|
1903
1970
|
})]
|
|
1904
1971
|
});
|
|
1905
|
-
const SurveyAssistantChatPanel = ({ api, applyPolicy, controller, embedded = false, hasEarlierMessages, initialLaunch, initialMessages, modelId, models, onInitialLaunchHandled, onModelChange, onFirstSubmit, onLoadEarlierMessages, onTurnSettled, onApplyReceipts, onSettleApply, onReviewChangeSets, onTurnActiveChange, resourceId, surveyId, threadControls, threadId, threadTitle }) => {
|
|
1972
|
+
const SurveyAssistantChatPanel = ({ api, applyPolicy, controller, embedded = false, focusPromptOnMount = false, hasEarlierMessages, initialLaunch, initialMessages, modelId, models, onInitialLaunchHandled, onModelChange, onFirstSubmit, onLoadEarlierMessages, onTurnSettled, onApplyReceipts, onSettleApply, onReviewChangeSets, onTurnActiveChange, resourceId, surveyId, threadControls, threadId, threadTitle }) => {
|
|
1906
1973
|
const t = useSurveyAssistantTranslation();
|
|
1907
1974
|
const emptyStateContext = getAssistantEmptyStateContext(controller);
|
|
1908
1975
|
const assistantQuickPrompts = getAssistantQuickPrompts(t, emptyStateContext);
|
|
@@ -2187,6 +2254,7 @@ const SurveyAssistantChatPanel = ({ api, applyPolicy, controller, embedded = fal
|
|
|
2187
2254
|
onSubmit: handleSubmit,
|
|
2188
2255
|
status,
|
|
2189
2256
|
textareaClassName: "min-h-11 max-h-28 px-3 pt-2.5 pb-1.5 transition-colors disabled:placeholder:text-muted-foreground/60",
|
|
2257
|
+
textareaProps: { autoFocus: focusPromptOnMount },
|
|
2190
2258
|
textareaRef: promptTextareaRef
|
|
2191
2259
|
})
|
|
2192
2260
|
})
|
|
@@ -2230,8 +2298,10 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
|
|
|
2230
2298
|
const [editingTitle, setEditingTitle] = useState("");
|
|
2231
2299
|
const [threadError, setThreadError] = useState(null);
|
|
2232
2300
|
const [loadingThread, setLoadingThread] = useState(true);
|
|
2301
|
+
const [threadLoadAttempt, setThreadLoadAttempt] = useState(0);
|
|
2233
2302
|
const [assistantTurnActive, setAssistantTurnActive] = useState(false);
|
|
2234
2303
|
const [initialLaunch, setInitialLaunch] = useState();
|
|
2304
|
+
const [promptFocusThreadId, setPromptFocusThreadId] = useState();
|
|
2235
2305
|
const historyControlsRef = useRef(null);
|
|
2236
2306
|
const loadingAllThreadsRef = useRef(false);
|
|
2237
2307
|
const selectModel = useCallback((modelId) => {
|
|
@@ -2239,6 +2309,7 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
|
|
|
2239
2309
|
onModelChange(modelId);
|
|
2240
2310
|
}, [models, onModelChange]);
|
|
2241
2311
|
const selectThread = useCallback(async (thread, reportError = true) => {
|
|
2312
|
+
setPromptFocusThreadId(void 0);
|
|
2242
2313
|
setLoadingThread(true);
|
|
2243
2314
|
setThreadError(null);
|
|
2244
2315
|
try {
|
|
@@ -2265,6 +2336,7 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
|
|
|
2265
2336
|
setThreadError(null);
|
|
2266
2337
|
try {
|
|
2267
2338
|
const thread = await threadClient.create(launch?.title);
|
|
2339
|
+
setPromptFocusThreadId(launch ? void 0 : thread.id);
|
|
2268
2340
|
setThreads((current) => mergeThreads(current, [thread]));
|
|
2269
2341
|
setSelectedThread(thread);
|
|
2270
2342
|
setInitialMessages([]);
|
|
@@ -2317,8 +2389,14 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
|
|
|
2317
2389
|
selectThread,
|
|
2318
2390
|
storageKey,
|
|
2319
2391
|
t,
|
|
2320
|
-
threadClient
|
|
2392
|
+
threadClient,
|
|
2393
|
+
threadLoadAttempt
|
|
2321
2394
|
]);
|
|
2395
|
+
const retryInitialThreadLoad = useCallback(() => {
|
|
2396
|
+
setThreadError(null);
|
|
2397
|
+
setLoadingThread(true);
|
|
2398
|
+
setThreadLoadAttempt((attempt) => attempt + 1);
|
|
2399
|
+
}, []);
|
|
2322
2400
|
const loadOlderThreads = useCallback(async () => {
|
|
2323
2401
|
if (!nextThreadCursor || loadingOlderThreads) return;
|
|
2324
2402
|
setLoadingOlderThreads(true);
|
|
@@ -2543,6 +2621,13 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
|
|
|
2543
2621
|
commitEditingThread,
|
|
2544
2622
|
historyOpen
|
|
2545
2623
|
]);
|
|
2624
|
+
useEffect(() => {
|
|
2625
|
+
if (!loadingThread && selectedThread?.id === promptFocusThreadId) setPromptFocusThreadId(void 0);
|
|
2626
|
+
}, [
|
|
2627
|
+
loadingThread,
|
|
2628
|
+
promptFocusThreadId,
|
|
2629
|
+
selectedThread?.id
|
|
2630
|
+
]);
|
|
2546
2631
|
useEffect(() => {
|
|
2547
2632
|
const handleFocus = () => {
|
|
2548
2633
|
refreshThreadList(false);
|
|
@@ -2550,20 +2635,49 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
|
|
|
2550
2635
|
window.addEventListener("focus", handleFocus);
|
|
2551
2636
|
return () => window.removeEventListener("focus", handleFocus);
|
|
2552
2637
|
}, [refreshThreadList]);
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
children: /* @__PURE__ */ jsx(SurveyAssistantHeaderIdentity, {
|
|
2558
|
-
indicatorClassName: "animate-pulse bg-blue-500",
|
|
2559
|
-
status: t("panel.loadingChats"),
|
|
2560
|
-
title: t("panel.title")
|
|
2561
|
-
})
|
|
2562
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
2563
|
-
className: "flex min-h-0 flex-1 items-center justify-center text-muted-foreground text-sm",
|
|
2564
|
-
children: [/* @__PURE__ */ jsx(LoaderCircleIcon, { className: "mr-2 size-4 animate-spin" }), t("panel.loadingChats")]
|
|
2565
|
-
})]
|
|
2638
|
+
const initialThreadLoadState = getSurveyAssistantInitialThreadLoadState({
|
|
2639
|
+
error: threadError,
|
|
2640
|
+
hasSelectedThread: Boolean(selectedThread),
|
|
2641
|
+
loading: loadingThread
|
|
2566
2642
|
});
|
|
2643
|
+
if (initialThreadLoadState || !selectedThread) {
|
|
2644
|
+
const initialLoadFailed = initialThreadLoadState === "error";
|
|
2645
|
+
return /* @__PURE__ */ jsxs("aside", {
|
|
2646
|
+
className: cn("flex h-full min-h-0 flex-col overflow-visible bg-background", !embedded && "rounded-xl border border-border shadow-sm"),
|
|
2647
|
+
children: [/* @__PURE__ */ jsx("header", {
|
|
2648
|
+
className: "box-content flex h-9 shrink-0 items-center border-b border-border bg-background px-2.5",
|
|
2649
|
+
children: /* @__PURE__ */ jsx(SurveyAssistantHeaderIdentity, {
|
|
2650
|
+
indicatorClassName: initialLoadFailed ? "bg-destructive" : "animate-pulse bg-blue-500",
|
|
2651
|
+
status: initialLoadFailed ? t("panel.controlsUnavailable") : t("panel.loadingChats"),
|
|
2652
|
+
title: t("panel.title")
|
|
2653
|
+
})
|
|
2654
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
2655
|
+
className: "flex min-h-0 flex-1 items-center justify-center p-6 text-sm",
|
|
2656
|
+
children: initialLoadFailed ? /* @__PURE__ */ jsxs("div", {
|
|
2657
|
+
className: "max-w-sm text-center",
|
|
2658
|
+
children: [
|
|
2659
|
+
/* @__PURE__ */ jsx("div", {
|
|
2660
|
+
className: "font-medium text-foreground",
|
|
2661
|
+
children: t("panel.controlsUnavailable")
|
|
2662
|
+
}),
|
|
2663
|
+
/* @__PURE__ */ jsx("div", {
|
|
2664
|
+
className: "mt-1 text-muted-foreground",
|
|
2665
|
+
children: threadError
|
|
2666
|
+
}),
|
|
2667
|
+
/* @__PURE__ */ jsx("button", {
|
|
2668
|
+
className: "mt-3 rounded-md border border-border bg-background px-3 py-1.5 font-medium text-foreground hover:bg-muted",
|
|
2669
|
+
onClick: retryInitialThreadLoad,
|
|
2670
|
+
type: "button",
|
|
2671
|
+
children: t("errors.retry")
|
|
2672
|
+
})
|
|
2673
|
+
]
|
|
2674
|
+
}) : /* @__PURE__ */ jsxs("div", {
|
|
2675
|
+
className: "flex items-center text-muted-foreground",
|
|
2676
|
+
children: [/* @__PURE__ */ jsx(LoaderCircleIcon, { className: "mr-2 size-4 animate-spin" }), t("panel.loadingChats")]
|
|
2677
|
+
})
|
|
2678
|
+
})]
|
|
2679
|
+
});
|
|
2680
|
+
}
|
|
2567
2681
|
const normalizedThreadSearch = threadSearch.trim().toLocaleLowerCase();
|
|
2568
2682
|
const visibleThreads = normalizedThreadSearch ? threads.filter((thread) => thread.title.toLocaleLowerCase().includes(normalizedThreadSearch)) : threads;
|
|
2569
2683
|
const threadControls = /* @__PURE__ */ jsxs("div", {
|
|
@@ -2685,6 +2799,7 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
|
|
|
2685
2799
|
children: [/* @__PURE__ */ createElement(SurveyAssistantChatPanel, {
|
|
2686
2800
|
...sessionProps,
|
|
2687
2801
|
embedded,
|
|
2802
|
+
focusPromptOnMount: selectedThread.id === promptFocusThreadId,
|
|
2688
2803
|
hasEarlierMessages: Boolean(nextMessageCursor),
|
|
2689
2804
|
initialLaunch: initialLaunch?.input,
|
|
2690
2805
|
initialMessages,
|