@case-framework/survey-assistant 0.2.2 → 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/{authoring-references-DYuOAdVx.mjs → authoring-references-yyYC4Ydi.mjs} +9 -3
- package/dist/authoring-references-yyYC4Ydi.mjs.map +1 -0
- package/dist/{capabilities-DlC1l6qy.d.mts → capabilities-CnsVuJ1k.d.mts} +12 -4
- package/dist/capabilities-CnsVuJ1k.d.mts.map +1 -0
- package/dist/capabilities-default.d.mts +1 -1
- package/dist/capabilities-default.d.mts.map +1 -1
- package/dist/capabilities-default.mjs +38 -4
- package/dist/capabilities-default.mjs.map +1 -1
- package/dist/{constants-D-5m_KGB.d.mts → constants-DrGZXtQf.d.mts} +12 -7
- package/dist/constants-DrGZXtQf.d.mts.map +1 -0
- package/dist/{controller-proxy-0WJZUZYx.mjs → controller-proxy-CpkQRezb.mjs} +3 -2
- package/dist/controller-proxy-CpkQRezb.mjs.map +1 -0
- package/dist/{controller-proxy-Hkuub9dt.d.mts → controller-proxy-DmBdzqKs.d.mts} +5 -2
- package/dist/controller-proxy-DmBdzqKs.d.mts.map +1 -0
- package/dist/{digest-BvXpeWcR.d.mts → digest-Dyjch_sC.d.mts} +2 -2
- package/dist/{digest-BvXpeWcR.d.mts.map → digest-Dyjch_sC.d.mts.map} +1 -1
- package/dist/digest.d.mts +1 -1
- package/dist/{engine-0AJrv0hI.mjs → engine-CWTuN3o2.mjs} +866 -663
- package/dist/engine-CWTuN3o2.mjs.map +1 -0
- package/dist/engine.d.mts +3 -3
- package/dist/engine.mjs +3 -3
- package/dist/fair-guidance-CEdJYccK.mjs +21 -0
- package/dist/fair-guidance-CEdJYccK.mjs.map +1 -0
- package/dist/form-authoring-DCd9XfXf.mjs +155 -0
- package/dist/form-authoring-DCd9XfXf.mjs.map +1 -0
- package/dist/{index-JXH-t2EJ.d.mts → index-Bo4dHAo8.d.mts} +68 -6
- package/dist/index-Bo4dHAo8.d.mts.map +1 -0
- package/dist/{index-MEOL9_Gr.d.mts → index-D4OitUg4.d.mts} +5 -430
- package/dist/index-D4OitUg4.d.mts.map +1 -0
- package/dist/{index-BcyfBeDj.d.mts → index-DZk20e3k.d.mts} +44 -22
- package/dist/index-DZk20e3k.d.mts.map +1 -0
- package/dist/{index-CneD8ibB.d.mts → index-Dxgg0-D_.d.mts} +12 -3
- package/dist/index-Dxgg0-D_.d.mts.map +1 -0
- package/dist/lifecycle-DWv5CiSu.d.mts +523 -0
- package/dist/lifecycle-DWv5CiSu.d.mts.map +1 -0
- package/dist/{memory-thread-repository-1ocPOda8.mjs → memory-thread-repository-acbz6HZJ.mjs} +181 -26
- package/dist/memory-thread-repository-acbz6HZJ.mjs.map +1 -0
- package/dist/{protocol-DpCYmCjr.mjs → protocol-DATvkr1S.mjs} +125 -6
- package/dist/protocol-DATvkr1S.mjs.map +1 -0
- package/dist/protocol.d.mts +4 -3
- package/dist/protocol.mjs +2 -2
- package/dist/{react-DXK5zWNo.mjs → react-Br5YE8H-.mjs} +132 -12
- package/dist/react-Br5YE8H-.mjs.map +1 -0
- 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/references/assistant-operations.md +13 -18
- package/dist/references/embedded-forms.md +41 -2
- package/dist/references/expressions.md +17 -9
- package/dist/references/fair-by-design.md +80 -0
- package/dist/references/item-types.md +19 -3
- package/dist/references/localization.md +7 -4
- package/dist/references/source-material-surveys.md +6 -4
- package/dist/{request-context-BBzU3VdG.mjs → request-context-BEjnaaFr.mjs} +10 -5
- package/dist/request-context-BEjnaaFr.mjs.map +1 -0
- package/dist/server-agent.d.mts +44 -22
- package/dist/server-agent.d.mts.map +1 -1
- package/dist/server-agent.mjs +71 -14
- package/dist/server-agent.mjs.map +1 -1
- package/dist/server-runtime.d.mts +22 -11
- package/dist/server-runtime.d.mts.map +1 -1
- package/dist/server-runtime.mjs +47 -19
- package/dist/server-runtime.mjs.map +1 -1
- package/dist/server-tasks.d.mts +1 -1
- package/dist/server-tasks.mjs +6 -4
- package/dist/server-tasks.mjs.map +1 -1
- package/dist/server-tools.d.mts +1 -1
- package/dist/server-tools.mjs +1 -1
- package/dist/server.d.mts +16 -7
- package/dist/server.d.mts.map +1 -1
- package/dist/server.mjs +4 -4
- package/dist/storage-postgres.d.mts +1 -1
- package/dist/{tasks-DcfQNJwO.d.mts → tasks-DQgL449A.d.mts} +8 -4
- package/dist/tasks-DQgL449A.d.mts.map +1 -0
- package/dist/{thread-documents-BlxNjc7S.d.mts → thread-documents-Dvo6XS7o.d.mts} +1 -1
- package/dist/{thread-documents-BlxNjc7S.d.mts.map → thread-documents-Dvo6XS7o.d.mts.map} +1 -1
- package/dist/{thread-handlers-uddXwQjp.d.mts → thread-handlers-CeYl45xG.d.mts} +9 -4
- package/dist/thread-handlers-CeYl45xG.d.mts.map +1 -0
- package/dist/{tools-wgLen05n.mjs → tools-Dg9HZrYU.mjs} +404 -78
- package/dist/tools-Dg9HZrYU.mjs.map +1 -0
- package/dist/ui.css +2 -2
- package/dist/ui.d.mts +94 -10
- package/dist/ui.d.mts.map +1 -1
- package/dist/ui.mjs +343 -112
- package/dist/ui.mjs.map +1 -1
- package/docs/integration.md +74 -6
- package/package.json +25 -19
- package/dist/authoring-references-DYuOAdVx.mjs.map +0 -1
- package/dist/capabilities-DKbNCnBf.mjs +0 -66
- package/dist/capabilities-DKbNCnBf.mjs.map +0 -1
- package/dist/capabilities-DlC1l6qy.d.mts.map +0 -1
- package/dist/constants-D-5m_KGB.d.mts.map +0 -1
- package/dist/controller-proxy-0WJZUZYx.mjs.map +0 -1
- package/dist/controller-proxy-Hkuub9dt.d.mts.map +0 -1
- package/dist/engine-0AJrv0hI.mjs.map +0 -1
- package/dist/index-BcyfBeDj.d.mts.map +0 -1
- package/dist/index-CneD8ibB.d.mts.map +0 -1
- package/dist/index-JXH-t2EJ.d.mts.map +0 -1
- package/dist/index-MEOL9_Gr.d.mts.map +0 -1
- package/dist/memory-thread-repository-1ocPOda8.mjs.map +0 -1
- package/dist/protocol-DpCYmCjr.mjs.map +0 -1
- package/dist/react-DXK5zWNo.mjs.map +0 -1
- package/dist/request-context-BBzU3VdG.mjs.map +0 -1
- package/dist/tasks-DcfQNJwO.d.mts.map +0 -1
- package/dist/thread-handlers-uddXwQjp.d.mts.map +0 -1
- package/dist/tools-wgLen05n.mjs.map +0 -1
package/dist/ui.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
3
|
-
import { f as unwrapSurveyAssistantToolOutput, i as createSurveyAssistantThreadClient, l as parseSurveyChangeSet, p as isSurveyAssistantTurnActive, r as useSurveyAssistantModelCatalog, t as useSurveyAssistantSession } from "./react-
|
|
4
|
-
import { o as connectSurveyAssistantThreadLauncher } from "./controller-proxy-
|
|
2
|
+
import { jt as parseSurveyAssistantError, l as surveyAssistantTurnFinalSchema, n as SURVEY_ASSISTANT_TURN_FINAL_PART_TYPE } from "./protocol-DATvkr1S.mjs";
|
|
3
|
+
import { f as unwrapSurveyAssistantToolOutput, i as createSurveyAssistantThreadClient, l as parseSurveyChangeSet, p as isSurveyAssistantTurnActive, r as useSurveyAssistantModelCatalog, t as useSurveyAssistantSession } from "./react-Br5YE8H-.mjs";
|
|
4
|
+
import { o as connectSurveyAssistantThreadLauncher } from "./controller-proxy-CpkQRezb.mjs";
|
|
5
5
|
import { getToolName, isFileUIPart, isReasoningUIPart, isToolUIPart } from "ai";
|
|
6
6
|
import { createContext, createElement, memo, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
7
7
|
import { Collapsible, Select, Slot } from "radix-ui";
|
|
@@ -15,6 +15,7 @@ import { createLocalizationTranslator, mergeLocalizationCatalogs } from "@case-f
|
|
|
15
15
|
import { cva } from "class-variance-authority";
|
|
16
16
|
import { StickToBottom, useStickToBottomContext } from "use-stick-to-bottom";
|
|
17
17
|
import { Streamdown } from "streamdown";
|
|
18
|
+
import { bundledLanguages } from "shiki/langs";
|
|
18
19
|
//#region src/ui/internal/collapsible.tsx
|
|
19
20
|
function Collapsible$1({ ...props }) {
|
|
20
21
|
return /* @__PURE__ */ jsx(Collapsible.Root, {
|
|
@@ -114,7 +115,25 @@ const surveyAssistantEnMessages = {
|
|
|
114
115
|
startConversation: "Start a conversation to see messages here",
|
|
115
116
|
scrollToLatest: "Scroll to latest message",
|
|
116
117
|
working: "Working...",
|
|
117
|
-
stopped: "Stopped"
|
|
118
|
+
stopped: "Stopped",
|
|
119
|
+
incomplete: "Response interrupted"
|
|
120
|
+
},
|
|
121
|
+
turn: {
|
|
122
|
+
failedTitle: "The assistant did not complete this turn.",
|
|
123
|
+
abortedTitle: "The turn was stopped.",
|
|
124
|
+
reasons: {
|
|
125
|
+
clientAbort: "The request was stopped by the client.",
|
|
126
|
+
firstResponseTimeout: "No meaningful response arrived before the initial deadline.",
|
|
127
|
+
idleTimeout: "The assistant stopped producing activity.",
|
|
128
|
+
maxDuration: "The one-hour execution ceiling was reached.",
|
|
129
|
+
maxSteps: "The assistant reached its tool-step limit before finishing.",
|
|
130
|
+
lengthLimit: "The model reached its output-length limit.",
|
|
131
|
+
contentFilter: "The provider stopped the response because of its content policy.",
|
|
132
|
+
providerError: "The model provider reported an error.",
|
|
133
|
+
streamError: "The response stream ended with an error.",
|
|
134
|
+
incompleteResponse: "The response ended without a normal completion.",
|
|
135
|
+
unknown: "The response ended before completion."
|
|
136
|
+
}
|
|
118
137
|
},
|
|
119
138
|
status: {
|
|
120
139
|
applying: "Applying changes",
|
|
@@ -282,7 +301,25 @@ const surveyAssistantNlMessages = {
|
|
|
282
301
|
startConversation: "Start een gesprek om hier berichten te zien",
|
|
283
302
|
scrollToLatest: "Naar het nieuwste bericht scrollen",
|
|
284
303
|
working: "Bezig...",
|
|
285
|
-
stopped: "Gestopt"
|
|
304
|
+
stopped: "Gestopt",
|
|
305
|
+
incomplete: "Antwoord onderbroken"
|
|
306
|
+
},
|
|
307
|
+
turn: {
|
|
308
|
+
failedTitle: "De assistent heeft deze beurt niet voltooid.",
|
|
309
|
+
abortedTitle: "De beurt is gestopt.",
|
|
310
|
+
reasons: {
|
|
311
|
+
clientAbort: "Het verzoek is door de client gestopt.",
|
|
312
|
+
firstResponseTimeout: "Er kwam geen betekenisvol antwoord vóór de eerste tijdslimiet.",
|
|
313
|
+
idleTimeout: "De assistent produceerde geen activiteit meer.",
|
|
314
|
+
maxDuration: "De maximale uitvoertijd van één uur is bereikt.",
|
|
315
|
+
maxSteps: "De assistent bereikte de limiet voor hulpmiddelstappen voordat hij klaar was.",
|
|
316
|
+
lengthLimit: "Het model bereikte de maximale antwoordlengte.",
|
|
317
|
+
contentFilter: "De provider stopte het antwoord vanwege het inhoudsbeleid.",
|
|
318
|
+
providerError: "De modelprovider meldde een fout.",
|
|
319
|
+
streamError: "De antwoordstream eindigde met een fout.",
|
|
320
|
+
incompleteResponse: "Het antwoord eindigde zonder normale voltooiing.",
|
|
321
|
+
unknown: "Het antwoord eindigde voordat het voltooid was."
|
|
322
|
+
}
|
|
286
323
|
},
|
|
287
324
|
status: {
|
|
288
325
|
applying: "Wijzigingen toepassen",
|
|
@@ -671,7 +708,7 @@ const Message = ({ className, from, ...props }) => /* @__PURE__ */ jsx("div", {
|
|
|
671
708
|
...props
|
|
672
709
|
});
|
|
673
710
|
const MessageContent = ({ children, className, ...props }) => /* @__PURE__ */ jsx("div", {
|
|
674
|
-
className: cn("w-fit min-w-0 max-w-full break-words text-sm", "group-data-[role=user]:whitespace-pre-wrap group-data-[role=user]:rounded-xl group-data-[role=user]:border group-data-[role=user]:border-blue-200/70 group-data-[role=user]:bg-blue-50 group-data-[role=user]:px-3 group-data-[role=user]:py-2 group-data-[role=user]:text-foreground group-data-[role=user]:shadow-xs dark:group-data-[role=user]:border-blue-800/60 dark:group-data-[role=user]:bg-blue-950/50", "group-data-[role=assistant]:text-foreground", className),
|
|
711
|
+
className: cn("w-fit min-w-0 max-w-full break-words text-sm", "group-data-[role=user]:whitespace-pre-wrap group-data-[role=user]:rounded-xl group-data-[role=user]:border group-data-[role=user]:border-blue-200/70 group-data-[role=user]:bg-blue-50/80 group-data-[role=user]:px-3 group-data-[role=user]:py-2 group-data-[role=user]:text-foreground group-data-[role=user]:shadow-xs dark:group-data-[role=user]:border-blue-800/60 dark:group-data-[role=user]:bg-blue-950/50", "group-data-[role=assistant]:text-foreground", className),
|
|
675
712
|
...props,
|
|
676
713
|
children
|
|
677
714
|
});
|
|
@@ -702,13 +739,18 @@ const usePromptInput = () => {
|
|
|
702
739
|
if (!context) throw new Error("PromptInput components must be used within PromptInput.");
|
|
703
740
|
return context;
|
|
704
741
|
};
|
|
705
|
-
const PromptInput = ({ attachmentsDisabled = false, children, className, onDragEnter, onDragLeave, onDragOver, onDrop, onPaste, onSubmit, ...props }) => {
|
|
706
|
-
const [
|
|
742
|
+
const PromptInput = ({ attachmentsDisabled = false, children, className, onDragEnter, onDragLeave, onDragOver, onDrop, onPaste, onSubmit, onValueChange, value: controlledValue, ...props }) => {
|
|
743
|
+
const [uncontrolledValue, setUncontrolledValue] = useState("");
|
|
707
744
|
const [files, setFiles] = useState([]);
|
|
708
745
|
const [isDraggingFiles, setIsDraggingFiles] = useState(false);
|
|
709
746
|
const [unsupportedFileNames, setUnsupportedFileNames] = useState([]);
|
|
710
747
|
const fileDragDepthRef = useRef(0);
|
|
711
748
|
const t = useSurveyAssistantTranslation();
|
|
749
|
+
const value = controlledValue ?? uncontrolledValue;
|
|
750
|
+
const setValue = useCallback((nextValue) => {
|
|
751
|
+
if (controlledValue === void 0) setUncontrolledValue(nextValue);
|
|
752
|
+
onValueChange?.(nextValue);
|
|
753
|
+
}, [controlledValue, onValueChange]);
|
|
712
754
|
const addFiles = useCallback((fileList) => {
|
|
713
755
|
const nextFiles = Array.from(fileList ?? []);
|
|
714
756
|
const supportedFiles = nextFiles.filter(isSupportedFile);
|
|
@@ -910,23 +952,6 @@ const PromptInputSubmit = ({ className, status, onStop, onClick, ...props }) =>
|
|
|
910
952
|
});
|
|
911
953
|
};
|
|
912
954
|
//#endregion
|
|
913
|
-
//#region src/ui/internal/tool-technical-details.ts
|
|
914
|
-
const formatOmittedLength = (length) => length.toLocaleString("en-US");
|
|
915
|
-
const stringifyToolTechnicalDetails = (value) => JSON.stringify(value, function redactEmbeddedBinary(key, currentValue) {
|
|
916
|
-
const parent = this && typeof this === "object" ? this : void 0;
|
|
917
|
-
if (key === "data" && typeof currentValue === "string" && parent?.type === "embedded" && parent.encoding === "base64") return `[embedded base64 omitted: ${formatOmittedLength(currentValue.length)} characters]`;
|
|
918
|
-
if (typeof currentValue === "string" && currentValue.length > 512 && /^data:[^;,]+;base64,/.test(currentValue)) return `[base64 data URL omitted: ${formatOmittedLength(currentValue.length)} characters]`;
|
|
919
|
-
return currentValue;
|
|
920
|
-
}, 2);
|
|
921
|
-
//#endregion
|
|
922
|
-
//#region src/ui/internal/response.tsx
|
|
923
|
-
const Response = ({ children, className, controls = false, ...props }) => /* @__PURE__ */ jsx(Streamdown, {
|
|
924
|
-
className: cn("leading-6", "[&>:first-child]:mt-0 [&>:last-child]: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", "[&_code]:rounded-md [&_code]:bg-muted [&_code]:px-1 [&_code]:py-0.5 [&_code]:font-mono [&_code]:text-[0.85em]", "[&_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", "[&_pre]:my-3 [&_pre]:overflow-x-auto [&_pre]:rounded-lg [&_pre]:border [&_pre]:bg-muted [&_pre]:p-3", "[&_pre_code]:bg-transparent [&_pre_code]:p-0", "[&_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),
|
|
925
|
-
controls,
|
|
926
|
-
...props,
|
|
927
|
-
children
|
|
928
|
-
});
|
|
929
|
-
//#endregion
|
|
930
955
|
//#region src/ui/internal/select.tsx
|
|
931
956
|
function Select$1({ ...props }) {
|
|
932
957
|
return /* @__PURE__ */ jsx(Select.Root, {
|
|
@@ -1001,6 +1026,88 @@ function SelectScrollDownButton({ className, ...props }) {
|
|
|
1001
1026
|
});
|
|
1002
1027
|
}
|
|
1003
1028
|
//#endregion
|
|
1029
|
+
//#region src/ui/survey-assistant-prompt-input.tsx
|
|
1030
|
+
const SurveyAssistantModelSelect = ({ disabled = false, modelId, models, onModelChange }) => {
|
|
1031
|
+
const t = useSurveyAssistantTranslation();
|
|
1032
|
+
const selectedModelLabel = models.find((model) => model.id === modelId)?.label ?? modelId ?? t("input.defaultModel");
|
|
1033
|
+
if (models.length > 1) return /* @__PURE__ */ jsxs(Select$1, {
|
|
1034
|
+
disabled,
|
|
1035
|
+
onValueChange: onModelChange,
|
|
1036
|
+
value: modelId ?? "",
|
|
1037
|
+
children: [/* @__PURE__ */ jsxs(SelectTrigger, {
|
|
1038
|
+
"aria-label": t("input.model"),
|
|
1039
|
+
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",
|
|
1040
|
+
size: "sm",
|
|
1041
|
+
title: modelId,
|
|
1042
|
+
children: [/* @__PURE__ */ jsx(BotIcon, { className: "size-3.5" }), /* @__PURE__ */ jsx(SelectValue, {})]
|
|
1043
|
+
}), /* @__PURE__ */ jsx(SelectContent, {
|
|
1044
|
+
align: "end",
|
|
1045
|
+
className: "min-w-52 rounded-lg border-border p-0 shadow-lg",
|
|
1046
|
+
position: "popper",
|
|
1047
|
+
children: models.map((model) => /* @__PURE__ */ jsx(SelectItem, {
|
|
1048
|
+
className: "min-h-9 rounded-md px-2 py-2 text-xs focus:bg-muted",
|
|
1049
|
+
title: model.id,
|
|
1050
|
+
value: model.id,
|
|
1051
|
+
children: model.label
|
|
1052
|
+
}, model.id))
|
|
1053
|
+
})]
|
|
1054
|
+
});
|
|
1055
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1056
|
+
className: "flex h-8 min-w-0 max-w-48 items-center gap-1.5 px-2 text-muted-foreground text-xs",
|
|
1057
|
+
title: modelId,
|
|
1058
|
+
children: [/* @__PURE__ */ jsx(BotIcon, { className: "size-3.5 shrink-0" }), /* @__PURE__ */ jsx("span", {
|
|
1059
|
+
className: "truncate",
|
|
1060
|
+
children: selectedModelLabel
|
|
1061
|
+
})]
|
|
1062
|
+
});
|
|
1063
|
+
};
|
|
1064
|
+
const SurveyAssistantPromptInput = ({ attachmentsDisabled = false, attachmentButtonClassName, className, disabled = false, footerClassName, formProps, modelDisabled = false, modelId, models, onModelChange, onStop, onSubmit, onValueChange, placeholder, status, textareaClassName, textareaProps, textareaRef, value }) => {
|
|
1065
|
+
const t = useSurveyAssistantTranslation();
|
|
1066
|
+
const canStop = Boolean(onStop) && (status === "submitted" || status === "streaming");
|
|
1067
|
+
return /* @__PURE__ */ jsxs(PromptInput, {
|
|
1068
|
+
...formProps,
|
|
1069
|
+
attachmentsDisabled: attachmentsDisabled || disabled,
|
|
1070
|
+
className: cn("rounded-xl border-border bg-background shadow-sm", className),
|
|
1071
|
+
onSubmit,
|
|
1072
|
+
onValueChange,
|
|
1073
|
+
value,
|
|
1074
|
+
children: [/* @__PURE__ */ jsx(PromptInputBody, { children: /* @__PURE__ */ jsx(PromptInputTextarea, {
|
|
1075
|
+
...textareaProps,
|
|
1076
|
+
className: cn("min-h-20 px-3 py-2 disabled:cursor-not-allowed disabled:text-muted-foreground", textareaClassName),
|
|
1077
|
+
disabled,
|
|
1078
|
+
placeholder: placeholder ?? t("input.placeholder"),
|
|
1079
|
+
ref: textareaRef
|
|
1080
|
+
}) }), /* @__PURE__ */ jsxs(PromptInputFooter, {
|
|
1081
|
+
className: cn("justify-between border-0 px-1.5 pt-0 pb-1.5", footerClassName),
|
|
1082
|
+
children: [/* @__PURE__ */ jsx(PromptInputAttachmentButton, {
|
|
1083
|
+
className: attachmentButtonClassName,
|
|
1084
|
+
disabled: attachmentsDisabled || disabled
|
|
1085
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
1086
|
+
className: "flex min-w-0 items-center justify-end gap-1",
|
|
1087
|
+
children: [/* @__PURE__ */ jsx(SurveyAssistantModelSelect, {
|
|
1088
|
+
disabled: disabled || modelDisabled,
|
|
1089
|
+
modelId,
|
|
1090
|
+
models,
|
|
1091
|
+
onModelChange
|
|
1092
|
+
}), /* @__PURE__ */ jsx(PromptInputSubmit, {
|
|
1093
|
+
disabled: disabled && !canStop,
|
|
1094
|
+
onStop,
|
|
1095
|
+
status
|
|
1096
|
+
})]
|
|
1097
|
+
})]
|
|
1098
|
+
})]
|
|
1099
|
+
});
|
|
1100
|
+
};
|
|
1101
|
+
//#endregion
|
|
1102
|
+
//#region src/ui/internal/tool-technical-details.ts
|
|
1103
|
+
const formatOmittedLength = (length) => length.toLocaleString("en-US");
|
|
1104
|
+
const stringifyToolTechnicalDetails = (value) => JSON.stringify(value, function redactEmbeddedBinary(key, currentValue) {
|
|
1105
|
+
const parent = this && typeof this === "object" ? this : void 0;
|
|
1106
|
+
if (key === "data" && typeof currentValue === "string" && parent?.type === "embedded" && parent.encoding === "base64") return `[embedded base64 omitted: ${formatOmittedLength(currentValue.length)} characters]`;
|
|
1107
|
+
if (typeof currentValue === "string" && currentValue.length > 512 && /^data:[^;,]+;base64,/.test(currentValue)) return `[base64 data URL omitted: ${formatOmittedLength(currentValue.length)} characters]`;
|
|
1108
|
+
return currentValue;
|
|
1109
|
+
}, 2);
|
|
1110
|
+
//#endregion
|
|
1004
1111
|
//#region src/ui/internal/code-block.tsx
|
|
1005
1112
|
const isItalic = (fontStyle) => fontStyle && fontStyle & 1;
|
|
1006
1113
|
const isBold = (fontStyle) => fontStyle && fontStyle & 2;
|
|
@@ -1172,6 +1279,30 @@ const CodeBlock = ({ code, language, showLineNumbers = false, className, childre
|
|
|
1172
1279
|
});
|
|
1173
1280
|
};
|
|
1174
1281
|
//#endregion
|
|
1282
|
+
//#region src/ui/internal/response.tsx
|
|
1283
|
+
const highlightedLanguages = Object.keys(bundledLanguages);
|
|
1284
|
+
const codeHighlighter = {
|
|
1285
|
+
getSupportedLanguages: () => highlightedLanguages,
|
|
1286
|
+
getThemes: () => ["github-light", "github-dark"],
|
|
1287
|
+
highlight: ({ code, language }, callback) => highlightCode(code, language, callback),
|
|
1288
|
+
name: "shiki",
|
|
1289
|
+
supportsLanguage: (language) => language in bundledLanguages,
|
|
1290
|
+
type: "code-highlighter"
|
|
1291
|
+
};
|
|
1292
|
+
const Response = ({ children, className, controls = false, plugins, ...props }) => {
|
|
1293
|
+
const responsePlugins = useMemo(() => ({
|
|
1294
|
+
...plugins,
|
|
1295
|
+
code: plugins?.code ?? codeHighlighter
|
|
1296
|
+
}), [plugins]);
|
|
1297
|
+
return /* @__PURE__ */ jsx(Streamdown, {
|
|
1298
|
+
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),
|
|
1299
|
+
controls,
|
|
1300
|
+
plugins: responsePlugins,
|
|
1301
|
+
...props,
|
|
1302
|
+
children
|
|
1303
|
+
});
|
|
1304
|
+
};
|
|
1305
|
+
//#endregion
|
|
1175
1306
|
//#region src/ui/internal/message-timing.ts
|
|
1176
1307
|
const isRecord$1 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1177
1308
|
const asTimestamp = (value) => {
|
|
@@ -1198,6 +1329,9 @@ const getPartTimestamps = (part) => {
|
|
|
1198
1329
|
* time here keeps restored chats informative without a second timing store.
|
|
1199
1330
|
*/
|
|
1200
1331
|
const getPersistedMessageDurationSeconds = (message) => {
|
|
1332
|
+
const turnFinalPart = message.parts.find((part) => part.type === SURVEY_ASSISTANT_TURN_FINAL_PART_TYPE);
|
|
1333
|
+
const turnFinal = surveyAssistantTurnFinalSchema.safeParse(turnFinalPart && "data" in turnFinalPart ? turnFinalPart.data : void 0);
|
|
1334
|
+
if (turnFinal.success && turnFinal.data.durationMs !== void 0) return Math.max(1, Math.ceil(turnFinal.data.durationMs / 1e3));
|
|
1201
1335
|
if (!isRecord$1(message.metadata)) return void 0;
|
|
1202
1336
|
const startedAt = asTimestamp(message.metadata.createdAt);
|
|
1203
1337
|
if (startedAt === void 0) return void 0;
|
|
@@ -1206,6 +1340,16 @@ const getPersistedMessageDurationSeconds = (message) => {
|
|
|
1206
1340
|
return Math.max(1, Math.ceil((completedAt - startedAt) / 1e3));
|
|
1207
1341
|
};
|
|
1208
1342
|
//#endregion
|
|
1343
|
+
//#region src/ui/internal/message-turn-status.ts
|
|
1344
|
+
const getPersistedMessageTurnStatus = (message) => {
|
|
1345
|
+
for (let index = message.parts.length - 1; index >= 0; index -= 1) {
|
|
1346
|
+
const part = message.parts[index];
|
|
1347
|
+
if (part?.type !== SURVEY_ASSISTANT_TURN_FINAL_PART_TYPE || !("data" in part)) continue;
|
|
1348
|
+
const parsed = surveyAssistantTurnFinalSchema.safeParse(part.data);
|
|
1349
|
+
if (parsed.success) return parsed.data.status;
|
|
1350
|
+
}
|
|
1351
|
+
};
|
|
1352
|
+
//#endregion
|
|
1209
1353
|
//#region src/ui/survey-assistant-panel.tsx
|
|
1210
1354
|
const getAssistantQuickPrompts = (t) => [
|
|
1211
1355
|
{
|
|
@@ -1283,7 +1427,7 @@ const SurveyAssistantToolOutputSummary = ({ applyResult, output }) => {
|
|
|
1283
1427
|
const statusLabel = status === "applied" ? t("changes.applied") : status === "stale" ? t("changes.stale") : status === "failed" ? t("changes.failed") : isValid ? t("changes.prepared") : t("changes.rejected");
|
|
1284
1428
|
const statusMessage = applyResult?.message ?? unwrappedOutput.summary;
|
|
1285
1429
|
return /* @__PURE__ */ jsxs("div", {
|
|
1286
|
-
className: cn("relative rounded-md border px-2.5 py-2 text-xs", isPositiveStatus ? "border-emerald-200/
|
|
1430
|
+
className: cn("relative rounded-md border px-2.5 py-2 text-xs", isPositiveStatus ? "border-emerald-200/70 bg-emerald-50/40 text-emerald-950" : status === "stale" ? "border-amber-200/70 bg-amber-50/40 text-amber-900" : "border-red-200/70 bg-red-50/40 text-red-900"),
|
|
1287
1431
|
children: [
|
|
1288
1432
|
/* @__PURE__ */ jsxs("div", {
|
|
1289
1433
|
className: "flex items-center gap-2 font-medium",
|
|
@@ -1373,7 +1517,7 @@ const getStoppedToolStatusMeta = (t) => ({
|
|
|
1373
1517
|
label: t("activity.stopped"),
|
|
1374
1518
|
stepStatus: "complete"
|
|
1375
1519
|
});
|
|
1376
|
-
const SurveyAssistantToolStep = ({ applyResultsByChangeId,
|
|
1520
|
+
const SurveyAssistantToolStep = ({ applyResultsByChangeId, terminalTurnStatus, part, isLast }) => {
|
|
1377
1521
|
const t = useSurveyAssistantTranslation();
|
|
1378
1522
|
const toolStatusMeta = getToolStatusMeta(t);
|
|
1379
1523
|
const toolName = getToolName(part);
|
|
@@ -1381,8 +1525,21 @@ const SurveyAssistantToolStep = ({ applyResultsByChangeId, isAborted, part, isLa
|
|
|
1381
1525
|
const errorText = getToolErrorText(part);
|
|
1382
1526
|
const changeSet = output === void 0 ? null : getChangeSet(output);
|
|
1383
1527
|
const applyResult = changeSet ? applyResultsByChangeId[changeSet.id] : void 0;
|
|
1528
|
+
const changeHasError = changeSet?.status === "rejected" || applyResult?.status === "rejected" || applyResult?.status === "failed";
|
|
1384
1529
|
const title = changeSet ? toolName === "survey_expression" ? t("activity.expressionChange") : t("activity.surveyChange") : getToolTitle(t, toolName, part.state);
|
|
1385
|
-
const meta =
|
|
1530
|
+
const meta = terminalTurnStatus && toolStatusMeta[part.state].stepStatus === "active" ? terminalTurnStatus === "aborted" ? getStoppedToolStatusMeta(t) : {
|
|
1531
|
+
icon: /* @__PURE__ */ jsx(XCircleIcon, { className: "size-3 text-red-600" }),
|
|
1532
|
+
label: t("activity.failed"),
|
|
1533
|
+
stepStatus: "complete"
|
|
1534
|
+
} : changeHasError ? {
|
|
1535
|
+
icon: /* @__PURE__ */ jsx(XCircleIcon, { className: "size-3 text-red-900" }),
|
|
1536
|
+
label: null,
|
|
1537
|
+
stepStatus: "complete"
|
|
1538
|
+
} : applyResult?.status === "stale" ? {
|
|
1539
|
+
icon: /* @__PURE__ */ jsx(ClockIcon, { className: "size-3 text-amber-600" }),
|
|
1540
|
+
label: null,
|
|
1541
|
+
stepStatus: "complete"
|
|
1542
|
+
} : toolStatusMeta[part.state];
|
|
1386
1543
|
const metaTitle = meta.label ?? (part.state === "output-denied" ? t("activity.skipped") : part.state === "output-error" ? t("activity.failed") : meta.stepStatus === "active" ? t("activity.workingShort") : t("activity.done"));
|
|
1387
1544
|
const [detailsOpen, setDetailsOpen] = useState(part.state === "output-error");
|
|
1388
1545
|
const hasDetails = part.input !== void 0 || output !== void 0 || Boolean(errorText);
|
|
@@ -1413,16 +1570,16 @@ const SurveyAssistantToolStep = ({ applyResultsByChangeId, isAborted, part, isLa
|
|
|
1413
1570
|
onOpenChange: setDetailsOpen,
|
|
1414
1571
|
open: detailsOpen,
|
|
1415
1572
|
children: [/* @__PURE__ */ jsxs(CollapsibleTrigger, {
|
|
1416
|
-
className: "flex items-center gap-1 text-muted-foreground
|
|
1573
|
+
className: "-ml-1 flex items-center gap-0.5 rounded px-1 py-0.5 text-[11px] text-muted-foreground/80 transition-colors hover:bg-background/60 hover:text-foreground",
|
|
1417
1574
|
children: [/* @__PURE__ */ jsx(ChevronRightIcon, { className: cn("size-3 transition-transform", detailsOpen && "rotate-90") }), t(detailsOpen ? "activity.hideTechnicalDetails" : "activity.technicalDetails")]
|
|
1418
1575
|
}), /* @__PURE__ */ jsxs(CollapsibleContent, {
|
|
1419
|
-
className: "mt-
|
|
1576
|
+
className: "mt-1.5 space-y-1.5",
|
|
1420
1577
|
children: [part.input !== void 0 && /* @__PURE__ */ jsx(CodeBlock, {
|
|
1421
|
-
className: "border-border/
|
|
1578
|
+
className: "border-border/60 bg-background/70 [&_code]:text-xs [&_pre]:p-2.5 [&_pre]:text-xs",
|
|
1422
1579
|
code: stringifyToolTechnicalDetails(part.input),
|
|
1423
1580
|
language: "json"
|
|
1424
1581
|
}), (output !== void 0 || errorText) && /* @__PURE__ */ jsx(CodeBlock, {
|
|
1425
|
-
className: cn("bg-
|
|
1582
|
+
className: cn("bg-background/70 [&_code]:text-xs [&_pre]:p-2.5 [&_pre]:text-xs", errorText ? "border-destructive/25" : "border-border/60"),
|
|
1426
1583
|
code: errorText ?? stringifyToolTechnicalDetails(output),
|
|
1427
1584
|
language: "json"
|
|
1428
1585
|
})]
|
|
@@ -1508,7 +1665,7 @@ const buildMessageBlocks = (parts) => {
|
|
|
1508
1665
|
flushChain();
|
|
1509
1666
|
return blocks;
|
|
1510
1667
|
};
|
|
1511
|
-
const SurveyAssistantMessageParts = ({ applyResultsByChangeId,
|
|
1668
|
+
const SurveyAssistantMessageParts = ({ applyResultsByChangeId, isLastMessage, isStreaming, message, showProgress, terminalTurnStatus }) => {
|
|
1512
1669
|
const blocks = useMemo(() => buildMessageBlocks(message.parts), [message.parts]);
|
|
1513
1670
|
const persistedDuration = useMemo(() => getPersistedMessageDurationSeconds(message), [message]);
|
|
1514
1671
|
const lastPart = message.parts.at(-1);
|
|
@@ -1522,11 +1679,9 @@ const SurveyAssistantMessageParts = ({ applyResultsByChangeId, isAborted, isLast
|
|
|
1522
1679
|
}, block.key);
|
|
1523
1680
|
return /* @__PURE__ */ jsx("span", { children: block.text }, block.key);
|
|
1524
1681
|
}
|
|
1525
|
-
if (block.type === "file") return /* @__PURE__ */ jsxs("
|
|
1526
|
-
className: "inline-flex max-w-full items-center gap-2 rounded-md border border-border bg-muted px-2 py-1 text-xs
|
|
1527
|
-
|
|
1528
|
-
rel: "noreferrer",
|
|
1529
|
-
target: "_blank",
|
|
1682
|
+
if (block.type === "file") return /* @__PURE__ */ jsxs("span", {
|
|
1683
|
+
className: "inline-flex max-w-full items-center gap-2 rounded-md border border-border bg-muted px-2 py-1 text-xs",
|
|
1684
|
+
title: getFilePartLabel(block.part),
|
|
1530
1685
|
children: [
|
|
1531
1686
|
/* @__PURE__ */ jsx(FileIcon, { className: "size-3.5 shrink-0 text-muted-foreground" }),
|
|
1532
1687
|
/* @__PURE__ */ jsx("span", {
|
|
@@ -1557,9 +1712,10 @@ const SurveyAssistantMessageParts = ({ applyResultsByChangeId, isAborted, isLast
|
|
|
1557
1712
|
const isChainActive = isLastMessage && isStreaming && isLastBlock;
|
|
1558
1713
|
return /* @__PURE__ */ jsxs(ChainOfThought, {
|
|
1559
1714
|
autoClose: true,
|
|
1560
|
-
className: "w-full rounded-md bg-muted/
|
|
1715
|
+
className: "w-full rounded-md bg-muted/60 px-2 py-1.5",
|
|
1561
1716
|
defaultDuration: persistedDuration,
|
|
1562
1717
|
defaultOpen: isChainActive,
|
|
1718
|
+
duration: isChainActive ? void 0 : persistedDuration,
|
|
1563
1719
|
isStreaming: isChainActive,
|
|
1564
1720
|
children: [/* @__PURE__ */ jsx(ChainOfThoughtHeader, { className: "text-xs font-medium" }), /* @__PURE__ */ jsxs(ChainOfThoughtContent, {
|
|
1565
1721
|
className: "relative mt-2",
|
|
@@ -1574,9 +1730,9 @@ const SurveyAssistantMessageParts = ({ applyResultsByChangeId, isAborted, isLast
|
|
|
1574
1730
|
}, entry.key);
|
|
1575
1731
|
return /* @__PURE__ */ jsx(SurveyAssistantToolStep, {
|
|
1576
1732
|
applyResultsByChangeId,
|
|
1577
|
-
isAborted,
|
|
1578
1733
|
isLast: isLastEntry,
|
|
1579
|
-
part: entry.part
|
|
1734
|
+
part: entry.part,
|
|
1735
|
+
terminalTurnStatus
|
|
1580
1736
|
}, entry.key);
|
|
1581
1737
|
})]
|
|
1582
1738
|
})]
|
|
@@ -1585,6 +1741,33 @@ const SurveyAssistantMessageParts = ({ applyResultsByChangeId, isAborted, isLast
|
|
|
1585
1741
|
};
|
|
1586
1742
|
const SurveyAssistantTurnOutcomeNotice = (outcome) => {
|
|
1587
1743
|
const t = useSurveyAssistantTranslation();
|
|
1744
|
+
if (outcome.status === "failed" || outcome.status === "aborted") {
|
|
1745
|
+
const reason = (() => {
|
|
1746
|
+
switch (outcome.terminationReason) {
|
|
1747
|
+
case "client-abort": return t("turn.reasons.clientAbort");
|
|
1748
|
+
case "first-response-timeout": return t("turn.reasons.firstResponseTimeout");
|
|
1749
|
+
case "idle-timeout": return t("turn.reasons.idleTimeout");
|
|
1750
|
+
case "max-duration": return t("turn.reasons.maxDuration");
|
|
1751
|
+
case "max-steps": return t("turn.reasons.maxSteps");
|
|
1752
|
+
case "length-limit": return t("turn.reasons.lengthLimit");
|
|
1753
|
+
case "content-filter": return t("turn.reasons.contentFilter");
|
|
1754
|
+
case "provider-error": return t("turn.reasons.providerError");
|
|
1755
|
+
case "stream-error": return t("turn.reasons.streamError");
|
|
1756
|
+
case "incomplete-response": return t("turn.reasons.incompleteResponse");
|
|
1757
|
+
default: return t("turn.reasons.unknown");
|
|
1758
|
+
}
|
|
1759
|
+
})();
|
|
1760
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1761
|
+
className: cn("rounded-lg border px-3 py-2 text-xs", outcome.status === "aborted" ? "border-border bg-muted/50 text-foreground" : "border-destructive/20 bg-destructive/5 text-foreground"),
|
|
1762
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
1763
|
+
className: "font-medium",
|
|
1764
|
+
children: t(outcome.status === "aborted" ? "turn.abortedTitle" : "turn.failedTitle")
|
|
1765
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
1766
|
+
className: "mt-1 text-muted-foreground",
|
|
1767
|
+
children: reason
|
|
1768
|
+
})]
|
|
1769
|
+
});
|
|
1770
|
+
}
|
|
1588
1771
|
const description = outcome.status === "blocked" ? t(outcome.blockedChangeSetCount === 1 ? "changes.blocked" : "changes.blockedPlural", { count: outcome.blockedChangeSetCount }) : t(outcome.appliedChangeSetCount === 1 ? "changes.partial" : "changes.partialPlural", {
|
|
1589
1772
|
applied: outcome.appliedChangeSetCount,
|
|
1590
1773
|
failed: outcome.failedChangeSetCount
|
|
@@ -1642,9 +1825,9 @@ const SurveyAssistantChatPanel = ({ api, applyPolicy, controller, embedded = fal
|
|
|
1642
1825
|
surveyId,
|
|
1643
1826
|
threadId
|
|
1644
1827
|
});
|
|
1828
|
+
const hasSubmittedMessageRef = useRef((initialMessages?.length ?? 0) > 0);
|
|
1645
1829
|
const showAssistantError = Boolean(authorizationError) || Boolean(error);
|
|
1646
1830
|
const assistantErrorPresentation = getAssistantErrorPresentation(authorizationError ?? error, t);
|
|
1647
|
-
const selectedModelLabel = models.find((model) => model.id === modelId)?.label ?? modelId ?? t("input.defaultModel");
|
|
1648
1831
|
const lastMessage = messages.at(-1);
|
|
1649
1832
|
const isAssistantTurnActive = isSurveyAssistantTurnActive({
|
|
1650
1833
|
isStreaming,
|
|
@@ -1691,7 +1874,7 @@ const SurveyAssistantChatPanel = ({ api, applyPolicy, controller, embedded = fal
|
|
|
1691
1874
|
onTurnSettled
|
|
1692
1875
|
]);
|
|
1693
1876
|
const showPendingAssistantRow = isAssistantTurnActive && (!lastMessage || lastMessage.role !== "assistant");
|
|
1694
|
-
const sessionStatusLabel = state === "applying" ? t("status.applying") : state === "applied" ? t("status.applied") : state === "aborted" ? t("status.stopped") : isAssistantTurnActive ? getStreamingProgressLabel(t, lastMessage) : showAssistantError ? t("status.attention") : t("status.ready");
|
|
1877
|
+
const sessionStatusLabel = state === "applying" ? t("status.applying") : state === "applied" ? t("status.applied") : state === "aborted" ? t("status.stopped") : isAssistantTurnActive ? getStreamingProgressLabel(t, lastMessage) : showAssistantError || state === "failed" ? t("status.attention") : t("status.ready");
|
|
1695
1878
|
const handleSubmit = useCallback((message) => {
|
|
1696
1879
|
if (isAssistantTurnActive) return false;
|
|
1697
1880
|
const submittedFromFocusedPrompt = document.activeElement === promptTextareaRef.current;
|
|
@@ -1701,7 +1884,10 @@ const SurveyAssistantChatPanel = ({ api, applyPolicy, controller, embedded = fal
|
|
|
1701
1884
|
});
|
|
1702
1885
|
if (accepted) {
|
|
1703
1886
|
shouldRestorePromptFocusRef.current = submittedFromFocusedPrompt;
|
|
1704
|
-
|
|
1887
|
+
if (!hasSubmittedMessageRef.current) {
|
|
1888
|
+
hasSubmittedMessageRef.current = true;
|
|
1889
|
+
onFirstSubmit(message.text);
|
|
1890
|
+
}
|
|
1705
1891
|
}
|
|
1706
1892
|
return accepted;
|
|
1707
1893
|
}, [
|
|
@@ -1715,18 +1901,24 @@ const SurveyAssistantChatPanel = ({ api, applyPolicy, controller, embedded = fal
|
|
|
1715
1901
|
}), [handleSubmit]);
|
|
1716
1902
|
useEffect(() => {
|
|
1717
1903
|
if (!initialLaunch) return;
|
|
1904
|
+
if (initialLaunch.modelId) onModelChange(initialLaunch.modelId);
|
|
1718
1905
|
if (submit({
|
|
1719
1906
|
files: initialLaunch.files ?? [],
|
|
1907
|
+
modelId: initialLaunch.modelId,
|
|
1720
1908
|
text: initialLaunch.prompt,
|
|
1721
1909
|
uiContext: initialLaunch.uiContext
|
|
1722
1910
|
})) {
|
|
1723
|
-
|
|
1911
|
+
if (!hasSubmittedMessageRef.current) {
|
|
1912
|
+
hasSubmittedMessageRef.current = true;
|
|
1913
|
+
onFirstSubmit(initialLaunch.prompt);
|
|
1914
|
+
}
|
|
1724
1915
|
onInitialLaunchHandled();
|
|
1725
1916
|
}
|
|
1726
1917
|
}, [
|
|
1727
1918
|
initialLaunch,
|
|
1728
1919
|
onFirstSubmit,
|
|
1729
1920
|
onInitialLaunchHandled,
|
|
1921
|
+
onModelChange,
|
|
1730
1922
|
submit
|
|
1731
1923
|
]);
|
|
1732
1924
|
return /* @__PURE__ */ jsxs("aside", {
|
|
@@ -1734,15 +1926,15 @@ const SurveyAssistantChatPanel = ({ api, applyPolicy, controller, embedded = fal
|
|
|
1734
1926
|
className: cn("flex h-full min-h-0 flex-col overflow-visible bg-background", !embedded && "rounded-xl border border-border shadow-sm"),
|
|
1735
1927
|
children: [
|
|
1736
1928
|
/* @__PURE__ */ jsxs("header", {
|
|
1737
|
-
className: "box-content flex h-9 shrink-0 items-center justify-between gap-2 border-b border-border bg-
|
|
1929
|
+
className: "box-content flex h-9 shrink-0 items-center justify-between gap-2 border-b border-border bg-background px-2.5",
|
|
1738
1930
|
children: [/* @__PURE__ */ jsx(SurveyAssistantHeaderIdentity, {
|
|
1739
|
-
indicatorClassName: showAssistantError ? "bg-destructive" : isAssistantTurnActive ? "animate-pulse bg-blue-500" : state === "aborted" ? "bg-muted-foreground" : "bg-emerald-500",
|
|
1931
|
+
indicatorClassName: showAssistantError || state === "failed" ? "bg-destructive" : isAssistantTurnActive ? "animate-pulse bg-blue-500" : state === "aborted" ? "bg-muted-foreground" : "bg-emerald-500",
|
|
1740
1932
|
status: sessionStatusLabel,
|
|
1741
1933
|
title: threadTitle
|
|
1742
1934
|
}), threadControls]
|
|
1743
1935
|
}),
|
|
1744
1936
|
/* @__PURE__ */ jsxs(Conversation, {
|
|
1745
|
-
className: "min-h-0",
|
|
1937
|
+
className: "min-h-0 bg-(--surface-bg-color)",
|
|
1746
1938
|
children: [/* @__PURE__ */ jsx(ConversationContent, {
|
|
1747
1939
|
className: "gap-3 px-3 py-2.5",
|
|
1748
1940
|
children: messages.length === 0 ? /* @__PURE__ */ jsx(ConversationEmptyState, {
|
|
@@ -1765,7 +1957,7 @@ const SurveyAssistantChatPanel = ({ api, applyPolicy, controller, embedded = fal
|
|
|
1765
1957
|
/* @__PURE__ */ jsx("div", {
|
|
1766
1958
|
className: "mt-4 flex flex-col gap-1.5",
|
|
1767
1959
|
children: assistantQuickPrompts.map(({ label, description, icon: Icon, prompt }) => /* @__PURE__ */ jsxs("button", {
|
|
1768
|
-
className: "group flex w-full items-center gap-2.5 rounded-lg border border-border bg-
|
|
1960
|
+
className: "group flex w-full items-center gap-2.5 rounded-lg border border-border bg-popover px-2.5 py-2 text-left shadow-xs transition-colors hover:border-foreground/20 hover:bg-muted/60",
|
|
1769
1961
|
onClick: () => handleQuickPrompt(prompt),
|
|
1770
1962
|
type: "button",
|
|
1771
1963
|
children: [
|
|
@@ -1791,6 +1983,8 @@ const SurveyAssistantChatPanel = ({ api, applyPolicy, controller, embedded = fal
|
|
|
1791
1983
|
})
|
|
1792
1984
|
}) : /* @__PURE__ */ jsxs(Fragment, { children: [messages.map((message, index) => {
|
|
1793
1985
|
const isLastMessage = index === messages.length - 1;
|
|
1986
|
+
const persistedTurnStatus = getPersistedMessageTurnStatus(message);
|
|
1987
|
+
const terminalTurnStatus = persistedTurnStatus === "aborted" || persistedTurnStatus === "failed" ? persistedTurnStatus : isLastMessage && (state === "aborted" || state === "failed") ? state : void 0;
|
|
1794
1988
|
const shouldShowProgress = isAssistantTurnActive && isLastMessage && message.role === "assistant";
|
|
1795
1989
|
return /* @__PURE__ */ jsx(Message, {
|
|
1796
1990
|
className: "max-w-[96%] gap-1",
|
|
@@ -1799,17 +1993,17 @@ const SurveyAssistantChatPanel = ({ api, applyPolicy, controller, embedded = fal
|
|
|
1799
1993
|
className: cn(message.role === "assistant" && "w-full space-y-2"),
|
|
1800
1994
|
children: hasRenderableParts(message) ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(SurveyAssistantMessageParts, {
|
|
1801
1995
|
applyResultsByChangeId,
|
|
1802
|
-
isAborted: state === "aborted",
|
|
1803
1996
|
isLastMessage,
|
|
1804
1997
|
isStreaming: isAssistantTurnActive,
|
|
1805
1998
|
message,
|
|
1806
|
-
showProgress: shouldShowProgress
|
|
1807
|
-
|
|
1999
|
+
showProgress: shouldShowProgress,
|
|
2000
|
+
terminalTurnStatus
|
|
2001
|
+
}), isLastMessage && latestTurnOutcome && /* @__PURE__ */ jsx(SurveyAssistantTurnOutcomeNotice, { ...latestTurnOutcome })] }) : shouldShowProgress ? /* @__PURE__ */ jsx(SurveyAssistantProgressIndicator, { message }) : isLastMessage && latestTurnOutcome ? /* @__PURE__ */ jsx(SurveyAssistantTurnOutcomeNotice, { ...latestTurnOutcome }) : state === "aborted" ? /* @__PURE__ */ jsx("span", {
|
|
1808
2002
|
className: "text-muted-foreground text-sm",
|
|
1809
2003
|
children: t("conversation.stopped")
|
|
1810
2004
|
}) : /* @__PURE__ */ jsx("span", {
|
|
1811
2005
|
className: "text-muted-foreground text-sm",
|
|
1812
|
-
children: t("conversation.
|
|
2006
|
+
children: t("conversation.incomplete")
|
|
1813
2007
|
})
|
|
1814
2008
|
})
|
|
1815
2009
|
}, message.id);
|
|
@@ -1860,58 +2054,21 @@ const SurveyAssistantChatPanel = ({ api, applyPolicy, controller, embedded = fal
|
|
|
1860
2054
|
})]
|
|
1861
2055
|
}),
|
|
1862
2056
|
/* @__PURE__ */ jsx("div", {
|
|
1863
|
-
className: "shrink-0 border-t border-border bg-
|
|
1864
|
-
children: /* @__PURE__ */
|
|
1865
|
-
"
|
|
1866
|
-
|
|
1867
|
-
|
|
2057
|
+
className: "shrink-0 border-t border-border bg-background p-2",
|
|
2058
|
+
children: /* @__PURE__ */ jsx(SurveyAssistantPromptInput, {
|
|
2059
|
+
attachmentButtonClassName: "size-8",
|
|
2060
|
+
className: cn("rounded-xl border-border bg-popover shadow-sm transition-colors", isAssistantTurnActive && "border-border/60 bg-muted/50 shadow-none"),
|
|
2061
|
+
disabled: isAssistantTurnActive,
|
|
2062
|
+
footerClassName: cn("transition-colors", isAssistantTurnActive && "bg-muted/30"),
|
|
2063
|
+
formProps: { "aria-busy": isAssistantTurnActive },
|
|
2064
|
+
modelId,
|
|
2065
|
+
models,
|
|
2066
|
+
onModelChange,
|
|
2067
|
+
onStop: stop,
|
|
1868
2068
|
onSubmit: handleSubmit,
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
placeholder: t("input.placeholder"),
|
|
1873
|
-
ref: promptTextareaRef
|
|
1874
|
-
}) }), /* @__PURE__ */ jsxs(PromptInputFooter, {
|
|
1875
|
-
className: cn("justify-between border-0 px-1.5 pt-0 pb-1.5 transition-colors", isAssistantTurnActive && "bg-muted/30"),
|
|
1876
|
-
children: [/* @__PURE__ */ jsx(PromptInputAttachmentButton, {
|
|
1877
|
-
className: "size-8",
|
|
1878
|
-
disabled: isAssistantTurnActive
|
|
1879
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
1880
|
-
className: "flex min-w-0 items-center justify-end gap-1",
|
|
1881
|
-
children: [models.length > 1 && modelId ? /* @__PURE__ */ jsxs(Select$1, {
|
|
1882
|
-
disabled: isAssistantTurnActive,
|
|
1883
|
-
onValueChange: onModelChange,
|
|
1884
|
-
value: modelId,
|
|
1885
|
-
children: [/* @__PURE__ */ jsxs(SelectTrigger, {
|
|
1886
|
-
"aria-label": t("input.model"),
|
|
1887
|
-
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",
|
|
1888
|
-
size: "sm",
|
|
1889
|
-
title: modelId,
|
|
1890
|
-
children: [/* @__PURE__ */ jsx(BotIcon, { className: "size-3.5" }), /* @__PURE__ */ jsx(SelectValue, {})]
|
|
1891
|
-
}), /* @__PURE__ */ jsx(SelectContent, {
|
|
1892
|
-
align: "end",
|
|
1893
|
-
className: "min-w-52 rounded-lg border-border p-0 shadow-lg",
|
|
1894
|
-
position: "popper",
|
|
1895
|
-
children: models.map((model) => /* @__PURE__ */ jsx(SelectItem, {
|
|
1896
|
-
className: "min-h-9 rounded-md px-2 py-2 text-xs focus:bg-muted",
|
|
1897
|
-
title: model.id,
|
|
1898
|
-
value: model.id,
|
|
1899
|
-
children: model.label
|
|
1900
|
-
}, model.id))
|
|
1901
|
-
})]
|
|
1902
|
-
}) : /* @__PURE__ */ jsxs("div", {
|
|
1903
|
-
className: "flex h-8 min-w-0 max-w-48 items-center gap-1.5 px-2 text-muted-foreground text-xs",
|
|
1904
|
-
title: modelId,
|
|
1905
|
-
children: [/* @__PURE__ */ jsx(BotIcon, { className: "size-3.5 shrink-0" }), /* @__PURE__ */ jsx("span", {
|
|
1906
|
-
className: "truncate",
|
|
1907
|
-
children: selectedModelLabel
|
|
1908
|
-
})]
|
|
1909
|
-
}), /* @__PURE__ */ jsx(PromptInputSubmit, {
|
|
1910
|
-
onStop: stop,
|
|
1911
|
-
status
|
|
1912
|
-
})]
|
|
1913
|
-
})]
|
|
1914
|
-
})]
|
|
2069
|
+
status,
|
|
2070
|
+
textareaClassName: "min-h-11 max-h-28 px-3 pt-2.5 pb-1.5 transition-colors disabled:placeholder:text-muted-foreground/60",
|
|
2071
|
+
textareaRef: promptTextareaRef
|
|
1915
2072
|
})
|
|
1916
2073
|
})
|
|
1917
2074
|
]
|
|
@@ -1924,7 +2081,7 @@ const createThreadTitle = (text, fallback) => {
|
|
|
1924
2081
|
const words = normalized.split(" ").slice(0, 8).join(" ");
|
|
1925
2082
|
return words.length > 64 ? `${words.slice(0, 61).trimEnd()}...` : words;
|
|
1926
2083
|
};
|
|
1927
|
-
const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], onConfirmDeleteThread, onModelChange = () => {}, resourceId, selectedThreadStorageKey, surveyId, threadApi, threadClient: providedThreadClient, threadLauncher, ...sessionProps }) => {
|
|
2084
|
+
const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], onConfirmDeleteThread, onModelChange = () => {}, onTurnActiveChange: onAssistantTurnActiveChange, resourceId, selectedThreadStorageKey, surveyId, threadApi, threadClient: providedThreadClient, threadLauncher, ...sessionProps }) => {
|
|
1928
2085
|
const t = useSurveyAssistantTranslation();
|
|
1929
2086
|
const threadClient = useMemo(() => providedThreadClient ?? createSurveyAssistantThreadClient(threadApi), [providedThreadClient, threadApi]);
|
|
1930
2087
|
const storageKey = selectedThreadStorageKey === false ? null : selectedThreadStorageKey ?? `${SELECTED_THREAD_STORAGE_KEY}:${encodeURIComponent(resourceId)}${surveyId ? `:${encodeURIComponent(surveyId)}` : ""}`;
|
|
@@ -1936,6 +2093,7 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
|
|
|
1936
2093
|
const [editingTitle, setEditingTitle] = useState("");
|
|
1937
2094
|
const [threadError, setThreadError] = useState(null);
|
|
1938
2095
|
const [loadingThread, setLoadingThread] = useState(true);
|
|
2096
|
+
const [assistantTurnActive, setAssistantTurnActive] = useState(false);
|
|
1939
2097
|
const [initialLaunch, setInitialLaunch] = useState();
|
|
1940
2098
|
const historyControlsRef = useRef(null);
|
|
1941
2099
|
const selectModel = useCallback((modelId) => {
|
|
@@ -2062,6 +2220,14 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
|
|
|
2062
2220
|
setEditingThreadId(null);
|
|
2063
2221
|
setEditingTitle("");
|
|
2064
2222
|
}, []);
|
|
2223
|
+
const handleTurnActiveChange = useCallback((active) => {
|
|
2224
|
+
setAssistantTurnActive(active);
|
|
2225
|
+
onAssistantTurnActiveChange?.(active);
|
|
2226
|
+
if (active) {
|
|
2227
|
+
cancelEditingThread();
|
|
2228
|
+
setHistoryOpen(false);
|
|
2229
|
+
}
|
|
2230
|
+
}, [cancelEditingThread, onAssistantTurnActiveChange]);
|
|
2065
2231
|
const commitEditingThread = useCallback(async () => {
|
|
2066
2232
|
if (!editingThreadId) return;
|
|
2067
2233
|
const thread = threads.find((item) => item.id === editingThreadId);
|
|
@@ -2094,10 +2260,9 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
|
|
|
2094
2260
|
threads
|
|
2095
2261
|
]);
|
|
2096
2262
|
const handleFirstSubmit = useCallback((text) => {
|
|
2097
|
-
if (!selectedThread ||
|
|
2263
|
+
if (!selectedThread || selectedThread.titleMode === "manual") return;
|
|
2098
2264
|
setAutomaticTitle(selectedThread, createThreadTitle(text, t("threads.newChat")));
|
|
2099
2265
|
}, [
|
|
2100
|
-
initialMessages.length,
|
|
2101
2266
|
selectedThread,
|
|
2102
2267
|
setAutomaticTitle,
|
|
2103
2268
|
t
|
|
@@ -2176,7 +2341,7 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
|
|
|
2176
2341
|
if (loadingThread || !selectedThread) return /* @__PURE__ */ jsxs("aside", {
|
|
2177
2342
|
className: cn("flex h-full min-h-0 flex-col overflow-visible bg-background", !embedded && "rounded-xl border border-border shadow-sm"),
|
|
2178
2343
|
children: [/* @__PURE__ */ jsx("header", {
|
|
2179
|
-
className: "box-content flex h-9 shrink-0 items-center border-b border-border bg-
|
|
2344
|
+
className: "box-content flex h-9 shrink-0 items-center border-b border-border bg-background px-2.5",
|
|
2180
2345
|
children: /* @__PURE__ */ jsx(SurveyAssistantHeaderIdentity, {
|
|
2181
2346
|
indicatorClassName: "animate-pulse bg-blue-500",
|
|
2182
2347
|
status: t("panel.loadingChats"),
|
|
@@ -2193,7 +2358,8 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
|
|
|
2193
2358
|
children: [
|
|
2194
2359
|
/* @__PURE__ */ jsx("button", {
|
|
2195
2360
|
"aria-label": t("threads.newChat"),
|
|
2196
|
-
className: "flex size-8 items-center justify-center rounded-lg text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
2361
|
+
className: "flex size-8 items-center justify-center rounded-lg text-muted-foreground hover:bg-muted hover:text-foreground disabled:pointer-events-none disabled:opacity-50",
|
|
2362
|
+
disabled: assistantTurnActive,
|
|
2197
2363
|
onClick: () => void createThread(),
|
|
2198
2364
|
title: t("threads.newChat"),
|
|
2199
2365
|
type: "button",
|
|
@@ -2202,7 +2368,8 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
|
|
|
2202
2368
|
/* @__PURE__ */ jsx("button", {
|
|
2203
2369
|
"aria-expanded": historyOpen,
|
|
2204
2370
|
"aria-label": t("threads.history"),
|
|
2205
|
-
className: "flex size-8 items-center justify-center rounded-lg text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
2371
|
+
className: "flex size-8 items-center justify-center rounded-lg text-muted-foreground hover:bg-muted hover:text-foreground disabled:pointer-events-none disabled:opacity-50",
|
|
2372
|
+
disabled: assistantTurnActive,
|
|
2206
2373
|
onClick: toggleHistory,
|
|
2207
2374
|
title: t("threads.history"),
|
|
2208
2375
|
type: "button",
|
|
@@ -2286,13 +2453,14 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
|
|
|
2286
2453
|
onModelChange: selectModel,
|
|
2287
2454
|
onFirstSubmit: handleFirstSubmit,
|
|
2288
2455
|
onTurnSettled: handleTurnSettled,
|
|
2456
|
+
onTurnActiveChange: handleTurnActiveChange,
|
|
2289
2457
|
resourceId,
|
|
2290
2458
|
surveyId,
|
|
2291
2459
|
threadControls,
|
|
2292
2460
|
threadId: selectedThread.id,
|
|
2293
2461
|
threadTitle: selectedThread.title
|
|
2294
2462
|
}), threadError && /* @__PURE__ */ jsxs("div", {
|
|
2295
|
-
className: "absolute right-3 bottom-3 left-3 z-40 rounded-lg border border-destructive/20 bg-
|
|
2463
|
+
className: "absolute right-3 bottom-3 left-3 z-40 rounded-lg border border-destructive/20 bg-popover px-3 py-2 text-xs shadow-lg",
|
|
2296
2464
|
children: [
|
|
2297
2465
|
/* @__PURE__ */ jsx("div", {
|
|
2298
2466
|
className: "font-medium",
|
|
@@ -2324,6 +2492,69 @@ const SurveyAssistantPanel = ({ language, localizations, ...props }) => /* @__PU
|
|
|
2324
2492
|
})
|
|
2325
2493
|
});
|
|
2326
2494
|
//#endregion
|
|
2495
|
+
//#region src/ui/survey-assistant-thread-launcher-prompt.tsx
|
|
2496
|
+
const SurveyAssistantThreadLauncherPromptContent = ({ className, disabled = false, modelCatalogApi, modelStorageKey, onError, onModelCatalogError, onSubmitted, onValueChange, placeholder, textareaClassName, textareaProps, textareaRef, threadLauncher, uiContext, value }) => {
|
|
2497
|
+
const catalog = useSurveyAssistantModelCatalog({
|
|
2498
|
+
api: modelCatalogApi,
|
|
2499
|
+
storageKey: modelStorageKey
|
|
2500
|
+
});
|
|
2501
|
+
const [submitting, setSubmitting] = useState(false);
|
|
2502
|
+
useEffect(() => {
|
|
2503
|
+
if (catalog.error) onModelCatalogError?.(catalog.error);
|
|
2504
|
+
}, [catalog.error, onModelCatalogError]);
|
|
2505
|
+
const submit = useCallback(async ({ files, text }) => {
|
|
2506
|
+
if (disabled || submitting) return false;
|
|
2507
|
+
setSubmitting(true);
|
|
2508
|
+
try {
|
|
2509
|
+
await threadLauncher.startThread({
|
|
2510
|
+
files,
|
|
2511
|
+
modelId: catalog.modelId,
|
|
2512
|
+
prompt: text,
|
|
2513
|
+
uiContext
|
|
2514
|
+
});
|
|
2515
|
+
onSubmitted();
|
|
2516
|
+
return true;
|
|
2517
|
+
} catch (error) {
|
|
2518
|
+
onError?.(error);
|
|
2519
|
+
return false;
|
|
2520
|
+
} finally {
|
|
2521
|
+
setSubmitting(false);
|
|
2522
|
+
}
|
|
2523
|
+
}, [
|
|
2524
|
+
catalog.modelId,
|
|
2525
|
+
disabled,
|
|
2526
|
+
onError,
|
|
2527
|
+
onSubmitted,
|
|
2528
|
+
submitting,
|
|
2529
|
+
threadLauncher,
|
|
2530
|
+
uiContext
|
|
2531
|
+
]);
|
|
2532
|
+
return /* @__PURE__ */ jsx(SurveyAssistantPromptInput, {
|
|
2533
|
+
attachmentsDisabled: submitting,
|
|
2534
|
+
className,
|
|
2535
|
+
disabled: disabled || submitting,
|
|
2536
|
+
modelDisabled: catalog.loading || submitting,
|
|
2537
|
+
modelId: catalog.modelId,
|
|
2538
|
+
models: catalog.models,
|
|
2539
|
+
onModelChange: catalog.selectModel,
|
|
2540
|
+
onSubmit: submit,
|
|
2541
|
+
onValueChange,
|
|
2542
|
+
placeholder,
|
|
2543
|
+
textareaClassName,
|
|
2544
|
+
textareaProps,
|
|
2545
|
+
textareaRef,
|
|
2546
|
+
value
|
|
2547
|
+
});
|
|
2548
|
+
};
|
|
2549
|
+
const SurveyAssistantThreadLauncherPrompt = ({ language, localizations, ...props }) => /* @__PURE__ */ jsx("div", {
|
|
2550
|
+
className: "case-survey-assistant",
|
|
2551
|
+
children: /* @__PURE__ */ jsx(SurveyAssistantLocalizationProvider, {
|
|
2552
|
+
language,
|
|
2553
|
+
localizations,
|
|
2554
|
+
children: /* @__PURE__ */ jsx(SurveyAssistantThreadLauncherPromptContent, { ...props })
|
|
2555
|
+
})
|
|
2556
|
+
});
|
|
2557
|
+
//#endregion
|
|
2327
2558
|
//#region src/ui/connected-survey-assistant-panel.tsx
|
|
2328
2559
|
const ConnectedSurveyAssistantPanel = ({ modelCatalogApi, modelStorageKey, onModelCatalogError, onModelChange, ...props }) => {
|
|
2329
2560
|
const catalog = useSurveyAssistantModelCatalog({
|
|
@@ -2342,6 +2573,6 @@ const ConnectedSurveyAssistantPanel = ({ modelCatalogApi, modelStorageKey, onMod
|
|
|
2342
2573
|
});
|
|
2343
2574
|
};
|
|
2344
2575
|
//#endregion
|
|
2345
|
-
export { ConnectedSurveyAssistantPanel, SurveyAssistantLocalizationProvider, SurveyAssistantPanel, defaultSurveyAssistantLocalizations, surveyAssistantEnMessages, surveyAssistantNlMessages, useSurveyAssistantTranslation };
|
|
2576
|
+
export { ConnectedSurveyAssistantPanel, SurveyAssistantLocalizationProvider, SurveyAssistantPanel, SurveyAssistantPromptInput, SurveyAssistantThreadLauncherPrompt, defaultSurveyAssistantLocalizations, surveyAssistantEnMessages, surveyAssistantNlMessages, useSurveyAssistantTranslation };
|
|
2346
2577
|
|
|
2347
2578
|
//# sourceMappingURL=ui.mjs.map
|