@case-framework/survey-assistant 0.1.0 → 0.2.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 (113) hide show
  1. package/README.md +71 -11
  2. package/dist/{authoring-references-X6uRaWuf.mjs → authoring-references-DYuOAdVx.mjs} +26 -2
  3. package/dist/authoring-references-DYuOAdVx.mjs.map +1 -0
  4. package/dist/{capabilities-B6tvE7fK.mjs → capabilities-DZ0a_o2y.mjs} +2 -2
  5. package/dist/{capabilities-B6tvE7fK.mjs.map → capabilities-DZ0a_o2y.mjs.map} +1 -1
  6. package/dist/{capabilities-DvSKtjAw.d.mts → capabilities-DlC1l6qy.d.mts} +4 -1
  7. package/dist/capabilities-DlC1l6qy.d.mts.map +1 -0
  8. package/dist/capabilities-default.d.mts +1 -1
  9. package/dist/capabilities-default.d.mts.map +1 -1
  10. package/dist/capabilities-default.mjs +6 -3
  11. package/dist/capabilities-default.mjs.map +1 -1
  12. package/dist/{constants-Jw0k8ojS.d.mts → constants-56jf_4ls.d.mts} +36 -9
  13. package/dist/constants-56jf_4ls.d.mts.map +1 -0
  14. package/dist/{controller-proxy-BRDusFiO.d.mts → controller-proxy-2VH0b_5E.d.mts} +29 -4
  15. package/dist/controller-proxy-2VH0b_5E.d.mts.map +1 -0
  16. package/dist/{controller-proxy-Duxo2IFE.mjs → controller-proxy-ClsY4lFI.mjs} +74 -5
  17. package/dist/controller-proxy-ClsY4lFI.mjs.map +1 -0
  18. package/dist/{digest-BsoVq49o.d.mts → digest-BvXpeWcR.d.mts} +2 -2
  19. package/dist/{digest-BsoVq49o.d.mts.map → digest-BvXpeWcR.d.mts.map} +1 -1
  20. package/dist/digest.d.mts +1 -1
  21. package/dist/{engine-sPvuixWg.mjs → engine-DQrCO_ur.mjs} +392 -50
  22. package/dist/engine-DQrCO_ur.mjs.map +1 -0
  23. package/dist/engine.d.mts +2 -2
  24. package/dist/engine.mjs +2 -2
  25. package/dist/{index-MpEMQzTm.d.mts → index-B_x2IYi7.d.mts} +5 -1
  26. package/dist/index-B_x2IYi7.d.mts.map +1 -0
  27. package/dist/{index-BWNHkpkh.d.mts → index-C_x686M7.d.mts} +27 -5
  28. package/dist/index-C_x686M7.d.mts.map +1 -0
  29. package/dist/{index-TFtvBiSQ.d.mts → index-DVxVyhAu.d.mts} +31 -9
  30. package/dist/index-DVxVyhAu.d.mts.map +1 -0
  31. package/dist/{index-CUqbBjkc.d.mts → index-DZ6KBwVR.d.mts} +16 -3
  32. package/dist/index-DZ6KBwVR.d.mts.map +1 -0
  33. package/dist/{memory-thread-repository-CJkkVE2-.mjs → memory-thread-repository-Cm1BJyRw.mjs} +110 -41
  34. package/dist/memory-thread-repository-Cm1BJyRw.mjs.map +1 -0
  35. package/dist/{protocol-DV0ka9WT.mjs → protocol-7EEgcYja.mjs} +70 -97
  36. package/dist/protocol-7EEgcYja.mjs.map +1 -0
  37. package/dist/protocol.d.mts +3 -3
  38. package/dist/protocol.mjs +2 -2
  39. package/dist/{react-VuYe-cPh.mjs → react-B_5smfiK.mjs} +145 -38
  40. package/dist/react-B_5smfiK.mjs.map +1 -0
  41. package/dist/react-integration.d.mts +2 -2
  42. package/dist/react-integration.mjs +2 -2
  43. package/dist/react.d.mts +3 -3
  44. package/dist/react.mjs +3 -3
  45. package/dist/references/assistant-operations.md +6 -0
  46. package/dist/references/core-rules.md +6 -0
  47. package/dist/references/embedded-forms.md +21 -14
  48. package/dist/references/expressions.md +3 -0
  49. package/dist/references/item-types.md +37 -10
  50. package/dist/references/source-material-surveys.md +9 -1
  51. package/dist/references/survey-data-model.md +13 -0
  52. package/dist/request-context-BDBw4-Gw.mjs +79 -0
  53. package/dist/request-context-BDBw4-Gw.mjs.map +1 -0
  54. package/dist/request-guardrails-h4t6u8mP.mjs +129 -0
  55. package/dist/request-guardrails-h4t6u8mP.mjs.map +1 -0
  56. package/dist/server-agent.d.mts +6 -2
  57. package/dist/server-agent.d.mts.map +1 -1
  58. package/dist/server-agent.mjs +39 -24
  59. package/dist/server-agent.mjs.map +1 -1
  60. package/dist/server-runtime.d.mts +21 -5
  61. package/dist/server-runtime.d.mts.map +1 -1
  62. package/dist/server-runtime.mjs +98 -32
  63. package/dist/server-runtime.mjs.map +1 -1
  64. package/dist/server-tasks.d.mts +2 -78
  65. package/dist/server-tasks.mjs +103 -46
  66. package/dist/server-tasks.mjs.map +1 -1
  67. package/dist/server-tools.d.mts +1 -1
  68. package/dist/server-tools.mjs +1 -1
  69. package/dist/server.d.mts +89 -21
  70. package/dist/server.d.mts.map +1 -1
  71. package/dist/server.mjs +136 -5
  72. package/dist/server.mjs.map +1 -0
  73. package/dist/storage-postgres.d.mts +12 -2
  74. package/dist/storage-postgres.d.mts.map +1 -1
  75. package/dist/storage-postgres.mjs +11 -6
  76. package/dist/storage-postgres.mjs.map +1 -1
  77. package/dist/tasks-COQnhSeT.d.mts +140 -0
  78. package/dist/tasks-COQnhSeT.d.mts.map +1 -0
  79. package/dist/{thread-documents-DamIq9Od.d.mts → thread-documents-BlxNjc7S.d.mts} +21 -5
  80. package/dist/thread-documents-BlxNjc7S.d.mts.map +1 -0
  81. package/dist/{thread-handlers-DpynUc64.d.mts → thread-handlers-l79JBl5m.d.mts} +38 -5
  82. package/dist/thread-handlers-l79JBl5m.d.mts.map +1 -0
  83. package/dist/{tools-Hz2p7vyv.mjs → tools-DDXaJ8Za.mjs} +257 -38
  84. package/dist/tools-DDXaJ8Za.mjs.map +1 -0
  85. package/dist/ui.d.mts +5 -3
  86. package/dist/ui.d.mts.map +1 -1
  87. package/dist/ui.mjs +91 -12
  88. package/dist/ui.mjs.map +1 -1
  89. package/docs/integration.md +234 -0
  90. package/package.json +9 -7
  91. package/dist/authoring-references-Cy8J-DWt.d.mts +0 -48
  92. package/dist/authoring-references-Cy8J-DWt.d.mts.map +0 -1
  93. package/dist/authoring-references-X6uRaWuf.mjs.map +0 -1
  94. package/dist/capabilities-DvSKtjAw.d.mts.map +0 -1
  95. package/dist/constants-Jw0k8ojS.d.mts.map +0 -1
  96. package/dist/controller-proxy-BRDusFiO.d.mts.map +0 -1
  97. package/dist/controller-proxy-Duxo2IFE.mjs.map +0 -1
  98. package/dist/engine-sPvuixWg.mjs.map +0 -1
  99. package/dist/index-BWNHkpkh.d.mts.map +0 -1
  100. package/dist/index-CUqbBjkc.d.mts.map +0 -1
  101. package/dist/index-MpEMQzTm.d.mts.map +0 -1
  102. package/dist/index-TFtvBiSQ.d.mts.map +0 -1
  103. package/dist/memory-thread-repository-CJkkVE2-.mjs.map +0 -1
  104. package/dist/protocol-DV0ka9WT.mjs.map +0 -1
  105. package/dist/react-VuYe-cPh.mjs.map +0 -1
  106. package/dist/request-context-jcmXT_Q2.mjs +0 -44
  107. package/dist/request-context-jcmXT_Q2.mjs.map +0 -1
  108. package/dist/request-guardrails-C59IWnH8.mjs +0 -73
  109. package/dist/request-guardrails-C59IWnH8.mjs.map +0 -1
  110. package/dist/server-tasks.d.mts.map +0 -1
  111. package/dist/thread-documents-DamIq9Od.d.mts.map +0 -1
  112. package/dist/thread-handlers-DpynUc64.d.mts.map +0 -1
  113. package/dist/tools-Hz2p7vyv.mjs.map +0 -1
package/dist/ui.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  "use client";
2
- import { Dt as parseSurveyAssistantError } from "./protocol-DV0ka9WT.mjs";
3
- import { f as unwrapSurveyAssistantToolOutput, i as createSurveyAssistantThreadClient, l as parseSurveyChangeSet, p as isSurveyAssistantTurnActive, r as useSurveyAssistantModelCatalog, t as useSurveyAssistantSession } from "./react-VuYe-cPh.mjs";
2
+ import { kt as parseSurveyAssistantError } from "./protocol-7EEgcYja.mjs";
3
+ import { f as unwrapSurveyAssistantToolOutput, i as createSurveyAssistantThreadClient, l as parseSurveyChangeSet, p as isSurveyAssistantTurnActive, r as useSurveyAssistantModelCatalog, t as useSurveyAssistantSession } from "./react-B_5smfiK.mjs";
4
+ import { o as connectSurveyAssistantThreadLauncher } from "./controller-proxy-ClsY4lFI.mjs";
4
5
  import { getToolName, isFileUIPart, isReasoningUIPart, isToolUIPart } from "ai";
5
6
  import { createContext, createElement, memo, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
6
7
  import { Collapsible, Select, Slot } from "radix-ui";
@@ -14,7 +15,6 @@ import { createLocalizationTranslator, mergeLocalizationCatalogs } from "@case-f
14
15
  import { cva } from "class-variance-authority";
15
16
  import { StickToBottom, useStickToBottomContext } from "use-stick-to-bottom";
16
17
  import { Streamdown } from "streamdown";
17
- import { createHighlighter } from "shiki";
18
18
  //#region src/ui/internal/collapsible.tsx
19
19
  function Collapsible$1({ ...props }) {
20
20
  return /* @__PURE__ */ jsx(Collapsible.Root, {
@@ -1041,10 +1041,10 @@ const getTokensCacheKey = (code, language) => {
1041
1041
  const getHighlighter = (language) => {
1042
1042
  const cached = highlighterCache.get(language);
1043
1043
  if (cached) return cached;
1044
- const highlighterPromise = createHighlighter({
1044
+ const highlighterPromise = import("shiki").then(({ createHighlighter }) => createHighlighter({
1045
1045
  langs: [language],
1046
1046
  themes: ["github-light", "github-dark"]
1047
- });
1047
+ }));
1048
1048
  highlighterCache.set(language, highlighterPromise);
1049
1049
  return highlighterPromise;
1050
1050
  };
@@ -1227,8 +1227,13 @@ const getAssistantQuickPrompts = (t) => [
1227
1227
  prompt: t("quickActions.refine.prompt")
1228
1228
  }
1229
1229
  ];
1230
+ const isSurveyAssistantAttachmentReferencePart = (part) => {
1231
+ if (part.type !== "data-survey-assistant-attachment" || typeof part.data !== "object" || part.data === null) return false;
1232
+ const data = part.data;
1233
+ return typeof data.filename === "string" && typeof data.mediaType === "string" && typeof data.bytes === "number";
1234
+ };
1230
1235
  const hasRenderableParts = (message) => {
1231
- return message.parts.some((part) => part.type === "text" && part.text.length > 0 || isFileUIPart(part) || isReasoningUIPart(part) && part.text.trim().length > 0 || isToolUIPart(part));
1236
+ return message.parts.some((part) => part.type === "text" && part.text.length > 0 || isFileUIPart(part) || isSurveyAssistantAttachmentReferencePart(part) || isReasoningUIPart(part) && part.text.trim().length > 0 || isToolUIPart(part));
1232
1237
  };
1233
1238
  const getFilePartLabel = (part) => part.filename ?? part.mediaType;
1234
1239
  const getToolOutput = (part) => part.state === "output-available" ? part.output : void 0;
@@ -1489,6 +1494,15 @@ const buildMessageBlocks = (parts) => {
1489
1494
  key: `file-${index}`,
1490
1495
  part
1491
1496
  });
1497
+ return;
1498
+ }
1499
+ if (isSurveyAssistantAttachmentReferencePart(part)) {
1500
+ flushChain();
1501
+ blocks.push({
1502
+ type: "attachment-reference",
1503
+ key: `attachment-reference-${index}`,
1504
+ attachment: part.data
1505
+ });
1492
1506
  }
1493
1507
  });
1494
1508
  flushChain();
@@ -1525,6 +1539,21 @@ const SurveyAssistantMessageParts = ({ applyResultsByChangeId, isAborted, isLast
1525
1539
  })
1526
1540
  ]
1527
1541
  }, block.key);
1542
+ if (block.type === "attachment-reference") return /* @__PURE__ */ jsxs("span", {
1543
+ className: "inline-flex max-w-full items-center gap-2 rounded-md border border-border bg-muted px-2 py-1 text-xs",
1544
+ title: block.attachment.filename,
1545
+ children: [
1546
+ /* @__PURE__ */ jsx(FileIcon, { className: "size-3.5 shrink-0 text-muted-foreground" }),
1547
+ /* @__PURE__ */ jsx("span", {
1548
+ className: "min-w-0 truncate",
1549
+ children: block.attachment.filename
1550
+ }),
1551
+ /* @__PURE__ */ jsx("span", {
1552
+ className: "shrink-0 text-muted-foreground",
1553
+ children: block.attachment.mediaType
1554
+ })
1555
+ ]
1556
+ }, block.key);
1528
1557
  const isChainActive = isLastMessage && isStreaming && isLastBlock;
1529
1558
  return /* @__PURE__ */ jsxs(ChainOfThought, {
1530
1559
  autoClose: true,
@@ -1596,7 +1625,7 @@ const SurveyAssistantHeaderIdentity = ({ indicatorClassName, status, title }) =>
1596
1625
  })]
1597
1626
  })]
1598
1627
  });
1599
- const SurveyAssistantChatPanel = ({ api, applyPolicy = "auto", controller, embedded = false, initialMessages, modelId, models, onModelChange, onFirstSubmit, onTurnSettled, onApplyReceipts, onReviewChangeSets, onTurnActiveChange, resourceId, threadControls, threadId, threadTitle }) => {
1628
+ const SurveyAssistantChatPanel = ({ api, applyPolicy, controller, embedded = false, initialLaunch, initialMessages, modelId, models, onInitialLaunchHandled, onModelChange, onFirstSubmit, onTurnSettled, onApplyReceipts, onSettleApply, onReviewChangeSets, onTurnActiveChange, resourceId, surveyId, threadControls, threadId, threadTitle }) => {
1600
1629
  const t = useSurveyAssistantTranslation();
1601
1630
  const assistantQuickPrompts = getAssistantQuickPrompts(t);
1602
1631
  const { applyResultsByChangeId, authorizationError, dismissError, error, isStreaming, latestTurnOutcome, messages, state, status, stop, submit, retry } = useSurveyAssistantSession({
@@ -1606,9 +1635,11 @@ const SurveyAssistantChatPanel = ({ api, applyPolicy = "auto", controller, embed
1606
1635
  initialMessages,
1607
1636
  modelId,
1608
1637
  onApplyReceipts,
1638
+ onSettleApply,
1609
1639
  onReviewChangeSets,
1610
1640
  onTurnActiveChange,
1611
1641
  resourceId,
1642
+ surveyId,
1612
1643
  threadId
1613
1644
  });
1614
1645
  const showAssistantError = Boolean(authorizationError) || Boolean(error);
@@ -1653,6 +1684,22 @@ const SurveyAssistantChatPanel = ({ api, applyPolicy = "auto", controller, embed
1653
1684
  files: [],
1654
1685
  text: prompt
1655
1686
  }), [handleSubmit]);
1687
+ useEffect(() => {
1688
+ if (!initialLaunch) return;
1689
+ if (submit({
1690
+ files: initialLaunch.files ?? [],
1691
+ text: initialLaunch.prompt,
1692
+ uiContext: initialLaunch.uiContext
1693
+ })) {
1694
+ onFirstSubmit(initialLaunch.prompt);
1695
+ onInitialLaunchHandled();
1696
+ }
1697
+ }, [
1698
+ initialLaunch,
1699
+ onFirstSubmit,
1700
+ onInitialLaunchHandled,
1701
+ submit
1702
+ ]);
1656
1703
  return /* @__PURE__ */ jsxs("aside", {
1657
1704
  "aria-label": t("panel.ariaLabel"),
1658
1705
  className: cn("flex h-full min-h-0 flex-col overflow-visible bg-background", !embedded && "rounded-xl border border-border shadow-sm"),
@@ -1847,10 +1894,10 @@ const createThreadTitle = (text, fallback) => {
1847
1894
  const words = normalized.split(" ").slice(0, 8).join(" ");
1848
1895
  return words.length > 64 ? `${words.slice(0, 61).trimEnd()}...` : words;
1849
1896
  };
1850
- const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], onConfirmDeleteThread, onModelChange = () => {}, resourceId, selectedThreadStorageKey, threadApi, threadClient: providedThreadClient, ...sessionProps }) => {
1897
+ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], onConfirmDeleteThread, onModelChange = () => {}, resourceId, selectedThreadStorageKey, surveyId, threadApi, threadClient: providedThreadClient, threadLauncher, ...sessionProps }) => {
1851
1898
  const t = useSurveyAssistantTranslation();
1852
1899
  const threadClient = useMemo(() => providedThreadClient ?? createSurveyAssistantThreadClient(threadApi), [providedThreadClient, threadApi]);
1853
- const storageKey = selectedThreadStorageKey === false ? null : selectedThreadStorageKey ?? `${SELECTED_THREAD_STORAGE_KEY}:${encodeURIComponent(resourceId)}`;
1900
+ const storageKey = selectedThreadStorageKey === false ? null : selectedThreadStorageKey ?? `${SELECTED_THREAD_STORAGE_KEY}:${encodeURIComponent(resourceId)}${surveyId ? `:${encodeURIComponent(surveyId)}` : ""}`;
1854
1901
  const [threads, setThreads] = useState([]);
1855
1902
  const [selectedThread, setSelectedThread] = useState(null);
1856
1903
  const [initialMessages, setInitialMessages] = useState([]);
@@ -1859,6 +1906,7 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
1859
1906
  const [editingTitle, setEditingTitle] = useState("");
1860
1907
  const [threadError, setThreadError] = useState(null);
1861
1908
  const [loadingThread, setLoadingThread] = useState(true);
1909
+ const [initialLaunch, setInitialLaunch] = useState();
1862
1910
  const historyControlsRef = useRef(null);
1863
1911
  const selectModel = useCallback((modelId) => {
1864
1912
  if (!models.some((model) => model.id === modelId)) return;
@@ -1883,18 +1931,21 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
1883
1931
  t,
1884
1932
  threadClient
1885
1933
  ]);
1886
- const createThread = useCallback(async () => {
1934
+ const createThread = useCallback(async (launch) => {
1887
1935
  setLoadingThread(true);
1888
1936
  setThreadError(null);
1889
1937
  try {
1890
- const thread = await threadClient.create();
1938
+ const thread = await threadClient.create(launch?.title);
1891
1939
  setThreads((current) => [thread, ...current]);
1892
1940
  setSelectedThread(thread);
1893
1941
  setInitialMessages([]);
1894
1942
  setHistoryOpen(false);
1895
1943
  if (storageKey) window.localStorage.setItem(storageKey, thread.id);
1944
+ return thread;
1896
1945
  } catch (error) {
1897
1946
  setThreadError(parseSurveyAssistantError(error).detail ?? t("errors.fallbackDetail"));
1947
+ if (launch) throw error;
1948
+ return null;
1898
1949
  } finally {
1899
1950
  setLoadingThread(false);
1900
1951
  }
@@ -1928,6 +1979,23 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
1928
1979
  t,
1929
1980
  threadClient
1930
1981
  ]);
1982
+ useEffect(() => {
1983
+ if (!threadLauncher || loadingThread) return;
1984
+ return connectSurveyAssistantThreadLauncher(threadLauncher, async (launch) => {
1985
+ const thread = await createThread(launch);
1986
+ if (!thread) throw new Error("The survey assistant thread could not be created.");
1987
+ return new Promise((resolve) => {
1988
+ setInitialLaunch({
1989
+ input: launch,
1990
+ onSubmitted: () => resolve(thread)
1991
+ });
1992
+ });
1993
+ });
1994
+ }, [
1995
+ createThread,
1996
+ loadingThread,
1997
+ threadLauncher
1998
+ ]);
1931
1999
  const renameThread = useCallback(async (thread, title) => {
1932
2000
  const normalized = title.trim();
1933
2001
  if (!normalized || normalized === thread.title) {
@@ -2004,6 +2072,11 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
2004
2072
  setAutomaticTitle,
2005
2073
  t
2006
2074
  ]);
2075
+ const handleInitialLaunchHandled = useCallback(() => {
2076
+ if (!initialLaunch) return;
2077
+ setInitialLaunch(void 0);
2078
+ initialLaunch.onSubmitted();
2079
+ }, [initialLaunch]);
2007
2080
  const refreshThreadList = useCallback(async (reportError) => {
2008
2081
  try {
2009
2082
  const availableThreads = await threadClient.list();
@@ -2174,14 +2247,17 @@ const SurveyAssistantPanelContent = ({ embedded = false, modelId, models = [], o
2174
2247
  children: [/* @__PURE__ */ createElement(SurveyAssistantChatPanel, {
2175
2248
  ...sessionProps,
2176
2249
  embedded,
2250
+ initialLaunch: initialLaunch?.input,
2177
2251
  initialMessages,
2178
2252
  key: selectedThread.id,
2179
2253
  modelId,
2180
2254
  models,
2255
+ onInitialLaunchHandled: handleInitialLaunchHandled,
2181
2256
  onModelChange: selectModel,
2182
2257
  onFirstSubmit: handleFirstSubmit,
2183
2258
  onTurnSettled: handleTurnSettled,
2184
2259
  resourceId,
2260
+ surveyId,
2185
2261
  threadControls,
2186
2262
  threadId: selectedThread.id,
2187
2263
  threadTitle: selectedThread.title
@@ -2211,7 +2287,10 @@ const SurveyAssistantPanel = ({ language, localizations, ...props }) => /* @__PU
2211
2287
  children: /* @__PURE__ */ jsx(SurveyAssistantLocalizationProvider, {
2212
2288
  language,
2213
2289
  localizations,
2214
- children: /* @__PURE__ */ jsx(SurveyAssistantPanelContent, { ...props })
2290
+ children: /* @__PURE__ */ createElement(SurveyAssistantPanelContent, {
2291
+ ...props,
2292
+ key: JSON.stringify([props.resourceId, props.surveyId])
2293
+ })
2215
2294
  })
2216
2295
  });
2217
2296
  //#endregion