@xinghunm/ai-chat 1.4.4 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -46,7 +46,7 @@ __export(src_exports, {
46
46
  module.exports = __toCommonJS(src_exports);
47
47
 
48
48
  // src/components/ai-chat/index.tsx
49
- var import_react21 = require("react");
49
+ var import_react22 = require("react");
50
50
  var import_styled17 = __toESM(require("@emotion/styled"));
51
51
  var import_compass_ui4 = require("@xinghunm/compass-ui");
52
52
 
@@ -96,6 +96,7 @@ var DEFAULT_AI_CHAT_LABELS = {
96
96
  questionnaireMultiSelectHint: "Multiple choice",
97
97
  questionnaireOtherOptionLabel: "Other",
98
98
  questionnaireOtherPlaceholder: "Other",
99
+ questionnaireExpired: "Selection expired.",
99
100
  modelLoading: "Loading models...",
100
101
  modelLoadFailed: "Failed to load models",
101
102
  modelUnavailable: "No model available",
@@ -104,7 +105,9 @@ var DEFAULT_AI_CHAT_LABELS = {
104
105
  removeSkillAriaLabel: "Remove skill",
105
106
  sessionHistoryLoading: "Loading conversations...",
106
107
  sessionHistoryLoadFailed: "Failed to load conversations",
107
- sessionHistoryEmpty: "No conversations yet"
108
+ sessionHistoryEmpty: "No conversations yet",
109
+ questionnaireTitle: "Plan Options",
110
+ questionnaireConfirmInTime: "Please confirm within {{seconds}} seconds"
108
111
  };
109
112
 
110
113
  // src/lib/chat-session.ts
@@ -144,6 +147,42 @@ var mergeOlderHistoryMessages = (sessionId, olderMessages, currentMessages) => {
144
147
  );
145
148
  return [...uniqueOlderMessages, ...currentMessages];
146
149
  };
150
+ var mergeLocalQuestionnaireState = (localMessages, incomingMessages) => {
151
+ if (!localMessages?.length)
152
+ return incomingMessages;
153
+ return incomingMessages.map((incomingMsg) => {
154
+ const localMsg = localMessages.find((lm) => lm.id === incomingMsg.id);
155
+ if (!localMsg)
156
+ return incomingMsg;
157
+ if (localMsg.blocks && !incomingMsg.blocks) {
158
+ return {
159
+ ...incomingMsg,
160
+ blocks: localMsg.blocks
161
+ };
162
+ }
163
+ if (localMsg.blocks && incomingMsg.blocks) {
164
+ const nextBlocks = incomingMsg.blocks.map((incomingBlock, index3) => {
165
+ const localBlock = localMsg.blocks?.[index3];
166
+ const isSameQuestionnaire = incomingBlock.type === "questionnaire" && localBlock?.type === "questionnaire" && (localBlock.questionnaire.questionnaireId === incomingBlock.questionnaire.questionnaireId || Boolean(localBlock.questionnaire.blockKey) && localBlock.questionnaire.blockKey === incomingBlock.questionnaire.blockKey);
167
+ if (isSameQuestionnaire) {
168
+ return {
169
+ ...incomingBlock,
170
+ questionnaire: {
171
+ ...incomingBlock.questionnaire,
172
+ questionnaireId: localBlock.questionnaire.questionnaireId ?? incomingBlock.questionnaire.questionnaireId,
173
+ answers: localBlock.questionnaire.answers ?? incomingBlock.questionnaire.answers,
174
+ status: localBlock.questionnaire.status ?? incomingBlock.questionnaire.status,
175
+ statusMessage: localBlock.questionnaire.statusMessage ?? incomingBlock.questionnaire.statusMessage
176
+ }
177
+ };
178
+ }
179
+ return incomingBlock;
180
+ });
181
+ return { ...incomingMsg, blocks: nextBlocks };
182
+ }
183
+ return incomingMsg;
184
+ });
185
+ };
147
186
  var resolveSessionTitleFromMessage = (message) => {
148
187
  const trimmedContent = message.content.trim();
149
188
  if (trimmedContent) {
@@ -526,10 +565,12 @@ var createChatStore = (initialState) => (0, import_vanilla.createStore)((set, ge
526
565
  },
527
566
  hydrateHistorySessionMessages: (sessionId, messages) => {
528
567
  const state = get();
568
+ const localMessages = state.messagesBySession[sessionId] ?? [];
569
+ const nextMessages = mergeLocalQuestionnaireState(localMessages, messages);
529
570
  set({
530
571
  messagesBySession: {
531
572
  ...state.messagesBySession,
532
- [sessionId]: normalizeHistoryMessages(sessionId, messages)
573
+ [sessionId]: normalizeHistoryMessages(sessionId, nextMessages)
533
574
  },
534
575
  sessionMessageLoadStatusBySession: {
535
576
  ...state.sessionMessageLoadStatusBySession,
@@ -547,10 +588,12 @@ var createChatStore = (initialState) => (0, import_vanilla.createStore)((set, ge
547
588
  },
548
589
  hydrateHistorySessionMessagesPage: (sessionId, page) => {
549
590
  const state = get();
591
+ const localMessages = state.messagesBySession[sessionId] ?? [];
592
+ const nextMessages = mergeLocalQuestionnaireState(localMessages, page.messages);
550
593
  set({
551
594
  messagesBySession: {
552
595
  ...state.messagesBySession,
553
- [sessionId]: normalizeHistoryMessages(sessionId, page.messages)
596
+ [sessionId]: normalizeHistoryMessages(sessionId, nextMessages)
554
597
  },
555
598
  sessionMessageLoadStatusBySession: {
556
599
  ...state.sessionMessageLoadStatusBySession,
@@ -709,7 +752,11 @@ var createChatStore = (initialState) => (0, import_vanilla.createStore)((set, ge
709
752
  hasUpdatedBlock = true;
710
753
  return {
711
754
  ...block,
712
- questionnaire: { ...block.questionnaire, answers: { ...answers } }
755
+ questionnaire: {
756
+ ...block.questionnaire,
757
+ answers: { ...answers },
758
+ status: "submitted"
759
+ }
713
760
  };
714
761
  });
715
762
  if (!hasUpdatedBlock)
@@ -1186,7 +1233,7 @@ var AiChatProvider = (props) => {
1186
1233
  };
1187
1234
 
1188
1235
  // src/components/chat-thread/index.tsx
1189
- var import_react11 = require("react");
1236
+ var import_react12 = require("react");
1190
1237
  var import_styled9 = __toESM(require("@emotion/styled"));
1191
1238
 
1192
1239
  // src/context/use-chat-context.ts
@@ -1207,9 +1254,9 @@ var useChatStore = (selector) => {
1207
1254
  var CHAT_THREAD_SCROLL_TOP_GAP = 16;
1208
1255
 
1209
1256
  // src/components/chat-thread/components/chat-message-item.tsx
1210
- var import_react9 = require("react");
1257
+ var import_react10 = require("react");
1211
1258
  var import_styled7 = __toESM(require("@emotion/styled"));
1212
- var import_react10 = require("@emotion/react");
1259
+ var import_react11 = require("@emotion/react");
1213
1260
  var import_react_markdown = __toESM(require("react-markdown"));
1214
1261
  var import_remark_gfm = __toESM(require("remark-gfm"));
1215
1262
  var import_remark_math = __toESM(require("remark-math"));
@@ -1263,11 +1310,23 @@ var getNextDisplayedUnitCount = ({
1263
1310
  var splitMarkdownBlocks = (content) => content.split(/\n{2,}/).map((block) => block.trim()).filter(Boolean);
1264
1311
 
1265
1312
  // src/components/chat-thread/hooks/use-chat-message-reveal.ts
1313
+ var revealedStreamingMessages = /* @__PURE__ */ new Set();
1314
+ var markMessageAsRevealed = (id) => {
1315
+ if (revealedStreamingMessages.size > 500) {
1316
+ const firstKey = revealedStreamingMessages.keys().next().value;
1317
+ if (firstKey !== void 0) {
1318
+ revealedStreamingMessages.delete(firstKey);
1319
+ }
1320
+ }
1321
+ revealedStreamingMessages.add(id);
1322
+ };
1266
1323
  var createRevealState = ({
1267
1324
  isAssistantStreaming,
1268
- targetUnitCount
1325
+ targetUnitCount,
1326
+ messageId
1269
1327
  }) => {
1270
- const initialDisplayedUnitCount = isAssistantStreaming ? 0 : targetUnitCount;
1328
+ const hasBeenRevealed = revealedStreamingMessages.has(messageId);
1329
+ const initialDisplayedUnitCount = isAssistantStreaming && !hasBeenRevealed ? 0 : targetUnitCount;
1271
1330
  return {
1272
1331
  batchedTargetUnitCount: initialDisplayedUnitCount,
1273
1332
  displayedUnitCount: initialDisplayedUnitCount,
@@ -1277,7 +1336,11 @@ var createRevealState = ({
1277
1336
  var revealReducer = (state, action) => {
1278
1337
  switch (action.type) {
1279
1338
  case "reset-message":
1280
- return createRevealState(action);
1339
+ return createRevealState({
1340
+ isAssistantStreaming: action.isAssistantStreaming,
1341
+ targetUnitCount: action.targetUnitCount,
1342
+ messageId: action.messageId
1343
+ });
1281
1344
  case "commit-batched-target": {
1282
1345
  const nextDisplayedUnitCount = action.role === "assistant" ? getNextDisplayedUnitCount({
1283
1346
  currentUnits: state.displayedUnitCount,
@@ -1334,7 +1397,8 @@ var useChatMessageReveal = (message) => {
1334
1397
  revealReducer,
1335
1398
  {
1336
1399
  isAssistantStreaming,
1337
- targetUnitCount: targetUnits.length
1400
+ targetUnitCount: targetUnits.length,
1401
+ messageId: message.id
1338
1402
  },
1339
1403
  createRevealState
1340
1404
  );
@@ -1366,7 +1430,8 @@ var useChatMessageReveal = (message) => {
1366
1430
  dispatch({
1367
1431
  type: "reset-message",
1368
1432
  isAssistantStreaming,
1369
- targetUnitCount: targetUnits.length
1433
+ targetUnitCount: targetUnits.length,
1434
+ messageId: message.id
1370
1435
  });
1371
1436
  }, [isAssistantStreaming, message.id, targetUnits.length]);
1372
1437
  (0, import_react5.useEffect)(() => {
@@ -1445,6 +1510,11 @@ var useChatMessageReveal = (message) => {
1445
1510
  tone: "settled"
1446
1511
  }
1447
1512
  ];
1513
+ (0, import_react5.useEffect)(() => {
1514
+ if (isAssistantStreaming && displayedUnitCount > 0) {
1515
+ markMessageAsRevealed(message.id);
1516
+ }
1517
+ }, [isAssistantStreaming, displayedUnitCount, message.id]);
1448
1518
  return {
1449
1519
  isAssistantStreaming,
1450
1520
  isFreshBlockActive,
@@ -2035,9 +2105,96 @@ var Value = import_styled3.default.span`
2035
2105
  `;
2036
2106
 
2037
2107
  // src/components/chat-thread/components/questionnaire-card.tsx
2038
- var import_react7 = require("react");
2108
+ var import_react8 = require("react");
2039
2109
  var import_styled4 = __toESM(require("@emotion/styled"));
2040
2110
 
2111
+ // src/components/chat-thread/components/use-countdown-seconds.ts
2112
+ var import_react7 = require("react");
2113
+ var countdownDeadlineByKey = /* @__PURE__ */ new Map();
2114
+ var countdownCleanupTimerByKey = /* @__PURE__ */ new Map();
2115
+ var countdownMountCountByKey = /* @__PURE__ */ new Map();
2116
+ var clearCountdownEntry = (storageKey) => {
2117
+ const cleanupTimerId = countdownCleanupTimerByKey.get(storageKey);
2118
+ if (cleanupTimerId !== void 0) {
2119
+ window.clearTimeout(cleanupTimerId);
2120
+ countdownCleanupTimerByKey.delete(storageKey);
2121
+ }
2122
+ countdownDeadlineByKey.delete(storageKey);
2123
+ };
2124
+ var scheduleCountdownCleanup = (storageKey, deadline) => {
2125
+ const existingCleanupTimerId = countdownCleanupTimerByKey.get(storageKey);
2126
+ if (existingCleanupTimerId !== void 0) {
2127
+ return;
2128
+ }
2129
+ const delayMs = Math.max(0, deadline - Date.now());
2130
+ const cleanupTimerId = window.setTimeout(() => {
2131
+ if ((countdownMountCountByKey.get(storageKey) ?? 0) > 0) {
2132
+ countdownCleanupTimerByKey.delete(storageKey);
2133
+ return;
2134
+ }
2135
+ clearCountdownEntry(storageKey);
2136
+ }, delayMs);
2137
+ countdownCleanupTimerByKey.set(storageKey, cleanupTimerId);
2138
+ };
2139
+ var getCountdownDeadline = (storageKey, initialSeconds) => {
2140
+ const existingDeadline = countdownDeadlineByKey.get(storageKey);
2141
+ if (existingDeadline !== void 0) {
2142
+ return existingDeadline;
2143
+ }
2144
+ const nextDeadline = Date.now() + Math.max(0, initialSeconds) * 1e3;
2145
+ countdownDeadlineByKey.set(storageKey, nextDeadline);
2146
+ scheduleCountdownCleanup(storageKey, nextDeadline);
2147
+ return nextDeadline;
2148
+ };
2149
+ var getRemainingSeconds = (deadline) => Math.max(0, Math.ceil((deadline - Date.now()) / 1e3));
2150
+ var useCountdownSeconds = ({
2151
+ storageKey,
2152
+ initialSeconds,
2153
+ active
2154
+ }) => {
2155
+ const [remainingSeconds, setRemainingSeconds] = (0, import_react7.useState)(
2156
+ () => getRemainingSeconds(getCountdownDeadline(storageKey, initialSeconds))
2157
+ );
2158
+ (0, import_react7.useEffect)(() => {
2159
+ countdownMountCountByKey.set(storageKey, (countdownMountCountByKey.get(storageKey) ?? 0) + 1);
2160
+ return () => {
2161
+ const nextCount = (countdownMountCountByKey.get(storageKey) ?? 1) - 1;
2162
+ if (nextCount <= 0) {
2163
+ countdownMountCountByKey.delete(storageKey);
2164
+ return;
2165
+ }
2166
+ countdownMountCountByKey.set(storageKey, nextCount);
2167
+ };
2168
+ }, [storageKey]);
2169
+ (0, import_react7.useEffect)(() => {
2170
+ setRemainingSeconds(getRemainingSeconds(getCountdownDeadline(storageKey, initialSeconds)));
2171
+ }, [initialSeconds, storageKey]);
2172
+ (0, import_react7.useEffect)(() => {
2173
+ if (active) {
2174
+ return;
2175
+ }
2176
+ clearCountdownEntry(storageKey);
2177
+ }, [active, storageKey]);
2178
+ (0, import_react7.useEffect)(() => {
2179
+ if (remainingSeconds > 0) {
2180
+ return;
2181
+ }
2182
+ clearCountdownEntry(storageKey);
2183
+ }, [remainingSeconds, storageKey]);
2184
+ (0, import_react7.useEffect)(() => {
2185
+ if (!active || remainingSeconds <= 0) {
2186
+ return;
2187
+ }
2188
+ const timeoutId = window.setTimeout(() => {
2189
+ setRemainingSeconds(getRemainingSeconds(getCountdownDeadline(storageKey, initialSeconds)));
2190
+ }, 1e3);
2191
+ return () => {
2192
+ window.clearTimeout(timeoutId);
2193
+ };
2194
+ }, [active, initialSeconds, remainingSeconds, storageKey]);
2195
+ return remainingSeconds;
2196
+ };
2197
+
2041
2198
  // src/components/chat-thread/components/questionnaire-card-helpers.ts
2042
2199
  var OTHER_OPTION_VALUE = "__other__";
2043
2200
  var getQuestionnaireQuestion = (questionnaire) => questionnaire.question;
@@ -2344,7 +2501,10 @@ var DEFAULT_QUESTIONNAIRE_CARD_LABELS = {
2344
2501
  submitFailed: "Failed to submit. Please try again.",
2345
2502
  multiSelectHint: "Multiple choice",
2346
2503
  otherOptionLabel: "Other",
2347
- otherPlaceholder: "Other"
2504
+ otherPlaceholder: "Other",
2505
+ expired: "Selection expired.",
2506
+ questionnaireTitle: "Plan Options",
2507
+ questionnaireConfirmInTime: "Please confirm within {{seconds}} seconds"
2348
2508
  };
2349
2509
  var stopInputClickPropagation = (event) => {
2350
2510
  event.stopPropagation();
@@ -2404,32 +2564,41 @@ var QuestionnaireCardInner = ({
2404
2564
  onSubmit,
2405
2565
  labels
2406
2566
  }) => {
2407
- const questionnaireRef = (0, import_react7.useRef)(questionnaire);
2408
- const otherInputRefs = (0, import_react7.useRef)({});
2409
- const [answers, setAnswers] = (0, import_react7.useState)(
2567
+ const questionnaireRef = (0, import_react8.useRef)(questionnaire);
2568
+ const otherInputRefs = (0, import_react8.useRef)({});
2569
+ const [answers, setAnswers] = (0, import_react8.useState)(
2410
2570
  () => createInitialAnswers(questionnaire)
2411
2571
  );
2412
- const [otherDrafts, setOtherDrafts] = (0, import_react7.useState)(
2572
+ const [otherDrafts, setOtherDrafts] = (0, import_react8.useState)(
2413
2573
  () => createInitialOtherDrafts(questionnaire)
2414
2574
  );
2415
- const [errorMessage, setErrorMessage] = (0, import_react7.useState)(null);
2416
- const [isSubmitting, setIsSubmitting] = (0, import_react7.useState)(false);
2417
- const [isSubmitted, setIsSubmitted] = (0, import_react7.useState)(false);
2418
- const [pendingFocusQuestionId, setPendingFocusQuestionId] = (0, import_react7.useState)(null);
2575
+ const [errorMessage, setErrorMessage] = (0, import_react8.useState)(null);
2576
+ const [isSubmitting, setIsSubmitting] = (0, import_react8.useState)(false);
2577
+ const [isSubmitted, setIsSubmitted] = (0, import_react8.useState)(() => questionnaire.status === "submitted");
2578
+ const [pendingFocusQuestionId, setPendingFocusQuestionId] = (0, import_react8.useState)(null);
2419
2579
  const resolvedLabels = {
2420
2580
  ...DEFAULT_QUESTIONNAIRE_CARD_LABELS,
2421
2581
  ...labels
2422
2582
  };
2423
- const hasExternalFailureStatus = questionnaire.status === "expired" || questionnaire.status === "failed";
2583
+ const remainingSeconds = useCountdownSeconds({
2584
+ storageKey: questionnaire.blockKey ?? `questionnaire:${questionnaire.questionnaireId}`,
2585
+ initialSeconds: questionnaire.timeoutSec ?? 0,
2586
+ active: questionnaire.timeoutSec !== void 0 && questionnaire.timeoutSec > 0 && !isSubmitted && questionnaire.status !== "expired" && questionnaire.status !== "failed" && interactive
2587
+ });
2588
+ const isExpired = questionnaire.status === "expired" || questionnaire.timeoutSec !== void 0 && questionnaire.timeoutSec > 0 && remainingSeconds <= 0;
2589
+ const hasExternalFailureStatus = isExpired || questionnaire.status === "failed";
2424
2590
  const question = getQuestionnaireQuestion(questionnaire);
2425
- const visibleErrorMessage = questionnaire.statusMessage ?? errorMessage;
2426
- const isInteractionLocked = !interactive || isSubmitting || isSubmitted || hasExternalFailureStatus;
2591
+ const visibleErrorMessage = questionnaire.statusMessage ?? (isExpired ? null : errorMessage);
2592
+ const isInteractionLocked = !interactive || isSubmitting || isSubmitted || hasExternalFailureStatus || questionnaire.status === "submitted";
2427
2593
  questionnaireRef.current = questionnaire;
2428
- (0, import_react7.useEffect)(() => {
2594
+ (0, import_react8.useEffect)(() => {
2429
2595
  setAnswers(createInitialAnswers(questionnaireRef.current));
2430
2596
  setOtherDrafts(createInitialOtherDrafts(questionnaireRef.current));
2431
- }, [questionnaire.answers]);
2432
- (0, import_react7.useEffect)(() => {
2597
+ if (questionnaireRef.current.status === "submitted") {
2598
+ setIsSubmitted(true);
2599
+ }
2600
+ }, [questionnaire.answers, questionnaire.status]);
2601
+ (0, import_react8.useEffect)(() => {
2433
2602
  if (!pendingFocusQuestionId || isInteractionLocked) {
2434
2603
  return;
2435
2604
  }
@@ -2679,42 +2848,69 @@ var QuestionnaireCardInner = ({
2679
2848
  }
2680
2849
  };
2681
2850
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Card4, { "data-testid": "questionnaire-card", children: [
2682
- questionnaire.description ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Description, { children: questionnaire.description }) : null,
2683
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(QuestionList, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(QuestionCard, { children: [
2684
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(QuestionLabel, { children: [
2685
- question.label,
2686
- question.required ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Required, { children: "*" }) : null
2687
- ] }),
2688
- question.kind === "multi_select" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(QuestionHint, { children: resolvedLabels.multiSelectHint }) : null,
2689
- renderQuestion(question)
2690
- ] }, question.id) }),
2691
- visibleErrorMessage ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ErrorMessage, { "data-testid": "questionnaire-error", children: visibleErrorMessage }) : null,
2692
- isSubmitted ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SuccessMessage, { "data-testid": "questionnaire-success", children: resolvedLabels.submitted }) : interactive && !hasExternalFailureStatus ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2693
- SubmitButton,
2694
- {
2695
- type: "button",
2696
- "data-testid": "questionnaire-submit",
2697
- disabled: isInteractionLocked,
2698
- onClick: () => {
2699
- void handleSubmit();
2700
- },
2701
- children: isSubmitting ? resolvedLabels.submitting : questionnaire.submitLabel ?? "Submit"
2702
- }
2703
- ) : null
2851
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Header2, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Eyebrow2, { children: resolvedLabels.questionnaireTitle }) }),
2852
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Content, { children: [
2853
+ questionnaire.description ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Description, { children: questionnaire.description }) : null,
2854
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(QuestionList, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(QuestionCard, { children: [
2855
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(QuestionLabel, { children: [
2856
+ question.label,
2857
+ question.required ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Required, { children: "*" }) : null
2858
+ ] }),
2859
+ question.kind === "multi_select" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(QuestionHint, { children: resolvedLabels.multiSelectHint }) : null,
2860
+ renderQuestion(question)
2861
+ ] }, question.id) }),
2862
+ visibleErrorMessage ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ErrorMessage, { "data-testid": "questionnaire-error", children: visibleErrorMessage }) : null,
2863
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Footer, { children: isSubmitted ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SuccessMessage, { "data-testid": "questionnaire-success", children: resolvedLabels.submitted }) : isExpired ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ExpiredTag, { "data-testid": "questionnaire-expired", children: resolvedLabels.expired }) : interactive ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(FooterActionRow, { "data-testid": "questionnaire-card-actions", children: [
2864
+ remainingSeconds > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MetaText, { "data-testid": "questionnaire-countdown", children: resolvedLabels.questionnaireConfirmInTime?.replace(
2865
+ "{{seconds}}",
2866
+ String(remainingSeconds)
2867
+ ) ?? `\u8BF7\u5728 ${remainingSeconds} \u79D2\u5185\u786E\u8BA4` }),
2868
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2869
+ SubmitButton,
2870
+ {
2871
+ type: "button",
2872
+ "data-testid": "questionnaire-submit",
2873
+ disabled: isInteractionLocked,
2874
+ onClick: () => {
2875
+ void handleSubmit();
2876
+ },
2877
+ children: isSubmitting ? resolvedLabels.submitting : questionnaire.submitLabel ?? "Submit"
2878
+ }
2879
+ )
2880
+ ] }) : null })
2881
+ ] })
2704
2882
  ] });
2705
2883
  };
2706
2884
  var QuestionnaireCard = (props) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(QuestionnaireCardInner, { ...props }, getQuestionnaireStateKey(props.questionnaire));
2707
2885
  var Card4 = import_styled4.default.section`
2708
- display: grid;
2709
- gap: 14px;
2710
- padding: 16px;
2711
- border-radius: 20px;
2712
- border: 1px solid rgba(255, 255, 255, 0.08);
2713
- background: rgba(255, 255, 255, 0.03);
2886
+ overflow: hidden;
2887
+ background: var(--bg-primary);
2888
+ border-radius: 16px;
2889
+ border: 1px solid var(--border-hover);
2890
+ `;
2891
+ var Header2 = import_styled4.default.div`
2892
+ display: flex;
2893
+ flex-wrap: wrap;
2894
+ align-items: center;
2895
+ gap: 10px;
2896
+ padding: 22px 12px 16px;
2897
+ border-bottom: 1px solid var(--border-hover);
2898
+ `;
2899
+ var Eyebrow2 = import_styled4.default.div`
2900
+ font-weight: 500;
2901
+ font-size: 16px;
2902
+ color: var(--text-primary);
2903
+ line-height: 22px;
2904
+ `;
2905
+ var Content = import_styled4.default.div`
2906
+ display: flex;
2907
+ flex-direction: column;
2908
+ gap: 16px;
2909
+ padding: 16px 12px;
2714
2910
  `;
2715
2911
  var Description = import_styled4.default.p`
2716
2912
  margin: 0;
2717
- color: rgba(255, 255, 255, 0.72);
2913
+ color: var(--text-secondary);
2718
2914
  font-size: 13px;
2719
2915
  `;
2720
2916
  var QuestionList = import_styled4.default.div`
@@ -2725,11 +2921,11 @@ var QuestionCard = import_styled4.default.div`
2725
2921
  display: grid;
2726
2922
  gap: 10px;
2727
2923
  padding: 12px;
2728
- border-radius: 16px;
2729
- background: rgba(255, 255, 255, 0.04);
2924
+ border-radius: 8px;
2925
+ background: rgba(255, 255, 255, 0.02);
2730
2926
  `;
2731
2927
  var QuestionLabel = import_styled4.default.div`
2732
- color: rgba(255, 255, 255, 0.9);
2928
+ color: var(--text-primary);
2733
2929
  font-size: 14px;
2734
2930
  font-weight: 600;
2735
2931
  `;
@@ -2756,11 +2952,11 @@ var OptionChoiceItem = import_styled4.default.div`
2756
2952
  gap: 12px;
2757
2953
  width: 100%;
2758
2954
  text-align: left;
2759
- border: 1px solid rgba(255, 255, 255, 0.1);
2760
- border-radius: 14px;
2761
- background: rgba(255, 255, 255, 0.03);
2955
+ border: 1px solid var(--border-hover);
2956
+ border-radius: 8px;
2957
+ background: rgba(255, 255, 255, 0.02);
2762
2958
  padding: 2px 12px;
2763
- color: rgba(255, 255, 255, 0.9);
2959
+ color: var(--text-primary);
2764
2960
  cursor: pointer;
2765
2961
  transition:
2766
2962
  border-color 140ms ease,
@@ -2769,8 +2965,8 @@ var OptionChoiceItem = import_styled4.default.div`
2769
2965
  outline: none;
2770
2966
 
2771
2967
  &[data-selected='true'] {
2772
- border-color: rgba(126, 160, 255, 0.42);
2773
- background: linear-gradient(180deg, rgba(82, 114, 255, 0.18) 0%, rgba(82, 114, 255, 0.1) 100%);
2968
+ border-color: rgba(51, 133, 255, 0.42);
2969
+ background: linear-gradient(180deg, rgba(51, 133, 255, 0.18) 0%, rgba(51, 133, 255, 0.1) 100%);
2774
2970
  transform: translateY(-1px);
2775
2971
  }
2776
2972
 
@@ -2779,8 +2975,8 @@ var OptionChoiceItem = import_styled4.default.div`
2779
2975
  }
2780
2976
 
2781
2977
  &:focus-visible {
2782
- border-color: rgba(126, 160, 255, 0.52);
2783
- box-shadow: 0 0 0 1px rgba(126, 160, 255, 0.18);
2978
+ border-color: rgba(51, 133, 255, 0.52);
2979
+ box-shadow: 0 0 0 1px rgba(51, 133, 255, 0.18);
2784
2980
  }
2785
2981
 
2786
2982
  &[tabindex='-1'] {
@@ -2797,16 +2993,16 @@ var OptionChoiceMarker = import_styled4.default.span`
2797
2993
  width: 28px;
2798
2994
  height: 28px;
2799
2995
  border-radius: 8px;
2800
- border: 1px solid rgba(255, 255, 255, 0.14);
2801
- background: rgba(255, 255, 255, 0.04);
2802
- color: rgba(255, 255, 255, 0.65);
2996
+ border: 1px solid var(--border-hover);
2997
+ background: rgba(255, 255, 255, 0.02);
2998
+ color: var(--text-secondary);
2803
2999
  font-size: 12px;
2804
3000
  font-weight: 700;
2805
3001
 
2806
3002
  &[data-selected='true'] {
2807
- border-color: rgba(126, 160, 255, 0.38);
2808
- background: rgba(126, 160, 255, 0.2);
2809
- color: rgba(255, 255, 255, 0.96);
3003
+ border-color: rgba(51, 133, 255, 0.38);
3004
+ background: rgba(51, 133, 255, 0.2);
3005
+ color: var(--text-primary);
2810
3006
  }
2811
3007
  `;
2812
3008
  var OptionChoiceContent = import_styled4.default.span`
@@ -2826,47 +3022,41 @@ var OptionChoiceLabel = import_styled4.default.span`
2826
3022
  `;
2827
3023
  var TextInput = import_styled4.default.input`
2828
3024
  width: 100%;
2829
- border: 1px solid rgba(255, 255, 255, 0.1);
2830
- border-radius: 12px;
3025
+ border: 1px solid var(--border-hover);
3026
+ border-radius: 8px;
2831
3027
  background: rgba(13, 15, 21, 0.55);
2832
- color: rgba(255, 255, 255, 0.92);
3028
+ color: var(--text-primary);
2833
3029
  font-size: 13px;
2834
3030
  padding: 10px 12px;
2835
3031
 
2836
3032
  &::placeholder {
2837
- color: rgba(255, 255, 255, 0.34);
3033
+ color: var(--text-secondary);
3034
+ opacity: 0.5;
2838
3035
  }
2839
3036
  `;
2840
3037
  var InlineOtherInput = import_styled4.default.input`
2841
3038
  width: 100%;
2842
- margin-top: 0;
2843
-
2844
- .compass-input-wrapper {
2845
- min-height: 30px;
2846
- border: 1px solid rgba(255, 255, 255, 0.1);
2847
- border-radius: 10px;
2848
- background: rgba(13, 15, 21, 0.55);
2849
- box-shadow: none;
2850
- padding: 2px 9px;
2851
- }
2852
-
2853
- .compass-input-wrapper:hover {
2854
- border-color: rgba(126, 160, 255, 0.28);
2855
- }
3039
+ border: 1px solid var(--border-hover);
3040
+ border-radius: 6px;
3041
+ background: rgba(13, 15, 21, 0.45);
3042
+ color: var(--text-primary);
3043
+ font-size: 13px;
3044
+ padding: 6px 10px;
3045
+ outline: none;
3046
+ transition: border-color 140ms ease;
2856
3047
 
2857
- .compass-input-wrapper:focus-within {
2858
- border-color: rgba(126, 160, 255, 0.42);
2859
- box-shadow: 0 0 0 1px rgba(126, 160, 255, 0.14);
3048
+ &:hover {
3049
+ border-color: rgba(51, 133, 255, 0.28);
2860
3050
  }
2861
3051
 
2862
- .compass-input-input {
2863
- color: rgba(255, 255, 255, 0.92);
2864
- font-size: 13px;
2865
- line-height: 1.2;
3052
+ &:focus {
3053
+ border-color: rgba(51, 133, 255, 0.42);
3054
+ box-shadow: 0 0 0 1px rgba(51, 133, 255, 0.14);
2866
3055
  }
2867
3056
 
2868
- .compass-input-input::placeholder {
2869
- color: rgba(255, 255, 255, 0.34);
3057
+ &::placeholder {
3058
+ color: var(--text-secondary);
3059
+ opacity: 0.5;
2870
3060
  }
2871
3061
  `;
2872
3062
  var NumberInputRow = import_styled4.default.div`
@@ -2875,32 +3065,80 @@ var NumberInputRow = import_styled4.default.div`
2875
3065
  gap: 10px;
2876
3066
  `;
2877
3067
  var Unit = import_styled4.default.span`
2878
- color: rgba(255, 255, 255, 0.58);
3068
+ color: var(--text-secondary);
2879
3069
  font-size: 12px;
2880
3070
  white-space: nowrap;
2881
3071
  `;
2882
3072
  var ErrorMessage = import_styled4.default.div`
2883
- color: rgba(255, 145, 145, 0.96);
3073
+ font-size: 13px;
3074
+ line-height: 1.5;
3075
+ color: rgba(255, 207, 207, 0.92);
3076
+ `;
3077
+ var Footer = import_styled4.default.div`
3078
+ display: flex;
3079
+ flex-wrap: wrap;
3080
+ align-items: center;
3081
+ justify-content: flex-start;
3082
+ gap: 12px;
3083
+ `;
3084
+ var FooterActionRow = import_styled4.default.div`
3085
+ display: flex;
3086
+ align-items: center;
3087
+ flex-wrap: wrap;
3088
+ gap: 8px;
3089
+ margin-left: auto;
3090
+ justify-content: flex-end;
3091
+ `;
3092
+ var MetaText = import_styled4.default.span`
3093
+ font-weight: 500;
2884
3094
  font-size: 12px;
3095
+ color: var(--text-secondary);
3096
+ line-height: 17px;
3097
+ `;
3098
+ var ExpiredTag = import_styled4.default.span`
3099
+ display: inline-flex;
3100
+ align-items: center;
3101
+ padding: 8px 12px;
3102
+ border-radius: 8px;
3103
+ font-size: 13px;
3104
+ font-weight: 600;
3105
+ background: rgba(255, 255, 255, 0.05);
3106
+ border: 1px solid rgba(255, 255, 255, 0.12);
3107
+ color: rgba(214, 224, 236, 0.9);
2885
3108
  `;
2886
3109
  var SuccessMessage = import_styled4.default.div`
2887
- color: rgba(164, 255, 210, 0.96);
2888
- font-size: 12px;
3110
+ display: inline-flex;
3111
+ align-items: center;
3112
+ padding: 8px 12px;
3113
+ border-radius: 8px;
3114
+ font-size: 13px;
3115
+ font-weight: 600;
3116
+ background: rgba(190, 246, 202, 0.14);
3117
+ border: 1px solid rgba(190, 246, 202, 0.24);
3118
+ color: rgba(227, 255, 233, 0.94);
2889
3119
  `;
2890
3120
  var SubmitButton = import_styled4.default.button`
2891
- justify-self: flex-start;
2892
- border: none;
2893
- border-radius: 999px;
2894
- background: linear-gradient(180deg, #7ea0ff 0%, #4a6fff 100%);
2895
- color: #081127;
2896
- font-size: 12px;
2897
- font-weight: 700;
2898
- padding: 10px 14px;
3121
+ padding: 9px 16px;
3122
+ border-radius: 8px;
3123
+ border: 1px solid transparent;
3124
+ font-weight: 500;
3125
+ font-size: 14px;
3126
+ color: rgba(255, 255, 255, 0.96);
3127
+ background: linear-gradient(180deg, #3385ff 0%, #1f6ef2 100%);
3128
+ line-height: 14px;
2899
3129
  cursor: pointer;
3130
+ transition:
3131
+ transform 160ms ease,
3132
+ opacity 160ms ease;
2900
3133
 
2901
3134
  &:disabled {
2902
- cursor: default;
2903
- opacity: 0.72;
3135
+ cursor: progress;
3136
+ opacity: 0.68;
3137
+ transform: none;
3138
+ }
3139
+
3140
+ &:not(:disabled):hover {
3141
+ transform: translateY(-1px);
2904
3142
  }
2905
3143
  `;
2906
3144
 
@@ -2908,7 +3146,7 @@ var SubmitButton = import_styled4.default.button`
2908
3146
  var import_styled5 = __toESM(require("@emotion/styled"));
2909
3147
  var import_jsx_runtime6 = require("@emotion/react/jsx-runtime");
2910
3148
  var ResultSummaryCard = ({ summary }) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Card5, { "data-testid": "result-summary-card", "data-status": summary.status, children: [
2911
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Eyebrow2, { children: summary.status }),
3149
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Eyebrow3, { children: summary.status }),
2912
3150
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Headline, { children: summary.headline }),
2913
3151
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Details, { children: summary.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Detail, { children: detail }, detail)) })
2914
3152
  ] });
@@ -2928,7 +3166,7 @@ var Card5 = import_styled5.default.section`
2928
3166
  border-color: rgba(255, 122, 122, 0.24);
2929
3167
  }
2930
3168
  `;
2931
- var Eyebrow2 = import_styled5.default.span`
3169
+ var Eyebrow3 = import_styled5.default.span`
2932
3170
  color: rgba(255, 255, 255, 0.58);
2933
3171
  font-size: 11px;
2934
3172
  font-weight: 700;
@@ -2953,7 +3191,7 @@ var Detail = import_styled5.default.li`
2953
3191
 
2954
3192
  // src/components/chat-thread/components/image-viewer.tsx
2955
3193
  var import_styled6 = __toESM(require("@emotion/styled"));
2956
- var import_react8 = require("react");
3194
+ var import_react9 = require("react");
2957
3195
  var import_jsx_runtime7 = require("@emotion/react/jsx-runtime");
2958
3196
  var Overlay = import_styled6.default.div`
2959
3197
  position: fixed;
@@ -2972,8 +3210,8 @@ var Img = import_styled6.default.img`
2972
3210
  border-radius: 4px;
2973
3211
  `;
2974
3212
  var ImageViewer = ({ src, alt, onClose }) => {
2975
- const overlayRef = (0, import_react8.useRef)(null);
2976
- (0, import_react8.useEffect)(() => {
3213
+ const overlayRef = (0, import_react9.useRef)(null);
3214
+ (0, import_react9.useEffect)(() => {
2977
3215
  const handleKey = (e) => {
2978
3216
  if (e.key === "Escape")
2979
3217
  onClose();
@@ -2981,7 +3219,7 @@ var ImageViewer = ({ src, alt, onClose }) => {
2981
3219
  document.addEventListener("keydown", handleKey);
2982
3220
  return () => document.removeEventListener("keydown", handleKey);
2983
3221
  }, [onClose]);
2984
- (0, import_react8.useEffect)(() => {
3222
+ (0, import_react9.useEffect)(() => {
2985
3223
  overlayRef.current?.focus();
2986
3224
  }, []);
2987
3225
  const stopPropagation = (e) => e.stopPropagation();
@@ -3047,10 +3285,10 @@ var useUserMessageCollapse = ({
3047
3285
  freshContent,
3048
3286
  settledContent
3049
3287
  }) => {
3050
- const [isCollapsible, setIsCollapsible] = (0, import_react9.useState)(false);
3051
- const [isExpanded, setIsExpanded] = (0, import_react9.useState)(false);
3052
- const [bodyStackElement, setBodyStackElement] = (0, import_react9.useState)(null);
3053
- const syncCollapseState = (0, import_react9.useCallback)(
3288
+ const [isCollapsible, setIsCollapsible] = (0, import_react10.useState)(false);
3289
+ const [isExpanded, setIsExpanded] = (0, import_react10.useState)(false);
3290
+ const [bodyStackElement, setBodyStackElement] = (0, import_react10.useState)(null);
3291
+ const syncCollapseState = (0, import_react10.useCallback)(
3054
3292
  (element) => {
3055
3293
  const nextCollapsible = enabled && (element?.scrollHeight ?? 0) > USER_MESSAGE_COLLAPSE_HEIGHT_PX;
3056
3294
  setIsCollapsible(nextCollapsible);
@@ -3060,14 +3298,14 @@ var useUserMessageCollapse = ({
3060
3298
  },
3061
3299
  [enabled]
3062
3300
  );
3063
- const bodyStackRef = (0, import_react9.useCallback)(
3301
+ const bodyStackRef = (0, import_react10.useCallback)(
3064
3302
  (node) => {
3065
3303
  setBodyStackElement(node);
3066
3304
  syncCollapseState(node);
3067
3305
  },
3068
3306
  [syncCollapseState]
3069
3307
  );
3070
- (0, import_react9.useLayoutEffect)(() => {
3308
+ (0, import_react10.useLayoutEffect)(() => {
3071
3309
  if (!bodyStackElement) {
3072
3310
  return;
3073
3311
  }
@@ -3087,7 +3325,7 @@ var useUserMessageCollapse = ({
3087
3325
  settledContent,
3088
3326
  syncCollapseState
3089
3327
  ]);
3090
- (0, import_react9.useLayoutEffect)(() => {
3328
+ (0, import_react10.useLayoutEffect)(() => {
3091
3329
  if (!bodyStackElement || !enabled || typeof ResizeObserver === "undefined") {
3092
3330
  return;
3093
3331
  }
@@ -3235,7 +3473,7 @@ var ChatMessageItemView = ({
3235
3473
  renderMessageBlock
3236
3474
  }) => {
3237
3475
  const { labels, messageRenderOrder = "blocks-first" } = useChatContext();
3238
- const [activeImage, setActiveImage] = (0, import_react9.useState)(void 0);
3476
+ const [activeImage, setActiveImage] = (0, import_react10.useState)(void 0);
3239
3477
  const {
3240
3478
  displayedBlocks,
3241
3479
  displayedContent,
@@ -3252,8 +3490,9 @@ var ChatMessageItemView = ({
3252
3490
  const hasMarkdownOnlyBlocks = hasStructuredBlocks && blocks.every((block) => block.type === "markdown");
3253
3491
  const hasTextContent = Boolean(settledContent || freshContent || displayedContent);
3254
3492
  const shouldRenderStructuredBlocks = hasStructuredBlocks && !(isAssistantStreaming && hasMarkdownOnlyBlocks && hasTextContent);
3255
- const canSubmitConfirmation = typeof onConfirmationSubmit === "function";
3256
- const canSubmitQuestionnaire = typeof onQuestionnaireSubmit === "function";
3493
+ const isInteractionDisabled = message.status === "stopped" || message.status === "error";
3494
+ const canSubmitConfirmation = typeof onConfirmationSubmit === "function" && !isInteractionDisabled;
3495
+ const canSubmitQuestionnaire = typeof onQuestionnaireSubmit === "function" && !isInteractionDisabled;
3257
3496
  const shouldShowStreamingCaret = isAssistantStreaming && (!shouldRenderStructuredBlocks || hasTextContent);
3258
3497
  const isUserMessage = message.role === "user";
3259
3498
  const messageRenderMode = isUserMessage ? "plain-text" : "markdown";
@@ -3303,11 +3542,11 @@ var ChatMessageItemView = ({
3303
3542
  `markdown-${index3}`
3304
3543
  );
3305
3544
  case "notice":
3306
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react9.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(NoticeCard, { text: block.text, tone: block.tone }) }, `notice-${index3}`);
3545
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react10.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(NoticeCard, { text: block.text, tone: block.tone }) }, `notice-${index3}`);
3307
3546
  case "parameter_summary":
3308
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react9.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ParameterSummaryCard, { items: block.items }) }, `parameter-summary-${index3}`);
3547
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react10.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ParameterSummaryCard, { items: block.items }) }, `parameter-summary-${index3}`);
3309
3548
  case "confirmation_card":
3310
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react9.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3549
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react10.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3311
3550
  ExecutionConfirmationCard,
3312
3551
  {
3313
3552
  proposal: block.proposal,
@@ -3320,9 +3559,9 @@ var ChatMessageItemView = ({
3320
3559
  }
3321
3560
  ) }, `confirmation-card-${index3}`);
3322
3561
  case "result_summary":
3323
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react9.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ResultSummaryCard, { summary: block.summary }) }, `result-summary-${index3}`);
3562
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react10.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ResultSummaryCard, { summary: block.summary }) }, `result-summary-${index3}`);
3324
3563
  case "questionnaire":
3325
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react9.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3564
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react10.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3326
3565
  QuestionnaireCard,
3327
3566
  {
3328
3567
  questionnaire: block.questionnaire,
@@ -3334,7 +3573,10 @@ var ChatMessageItemView = ({
3334
3573
  submitFailed: labels.questionnaireSubmitFailed,
3335
3574
  multiSelectHint: labels.questionnaireMultiSelectHint,
3336
3575
  otherOptionLabel: labels.questionnaireOtherOptionLabel,
3337
- otherPlaceholder: labels.questionnaireOtherPlaceholder
3576
+ otherPlaceholder: labels.questionnaireOtherPlaceholder,
3577
+ expired: labels.questionnaireExpired,
3578
+ questionnaireTitle: labels.questionnaireTitle,
3579
+ questionnaireConfirmInTime: labels.questionnaireConfirmInTime
3338
3580
  },
3339
3581
  onSubmit: canSubmitQuestionnaire ? (submission) => onQuestionnaireSubmit({
3340
3582
  ...submission,
@@ -3343,7 +3585,7 @@ var ChatMessageItemView = ({
3343
3585
  }
3344
3586
  ) }, block.questionnaire.blockKey ?? `questionnaire-${index3}`);
3345
3587
  case "custom":
3346
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react9.Fragment, { children: renderMessageBlock?.({
3588
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react10.Fragment, { children: renderMessageBlock?.({
3347
3589
  block,
3348
3590
  index: index3,
3349
3591
  message,
@@ -3437,7 +3679,7 @@ var ChatMessageItemView = ({
3437
3679
  })();
3438
3680
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
3439
3681
  /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Bubble, { "data-role": message.role, "data-status": message.status ?? "done", children: [
3440
- shouldRenderHeader ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Header2, { children: [
3682
+ shouldRenderHeader ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Header3, { children: [
3441
3683
  isAssistantStreaming ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
3442
3684
  StreamingIndicator,
3443
3685
  {
@@ -3462,7 +3704,7 @@ var ChatMessageItemView = ({
3462
3704
  ) : null,
3463
3705
  isStoppedAssistant ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(StatusTag, { "data-testid": "chat-message-stopped-tag", children: labels.stoppedResponse }) : null
3464
3706
  ] }) : null,
3465
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Content, { "data-testid": "chat-message-content", children: [
3707
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Content2, { "data-testid": "chat-message-content", children: [
3466
3708
  skills.length ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SkillTagList, { "data-testid": "chat-message-skill-tags", children: skills.map((skill) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SkillTag, { children: skill }, skill)) }) : null,
3467
3709
  shouldRenderStructuredBlocks || hasTextContent ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3468
3710
  ContentStack,
@@ -3510,7 +3752,7 @@ var ChatMessageItemView = ({
3510
3752
  ) : null
3511
3753
  ] });
3512
3754
  };
3513
- var ChatMessageItem = (0, import_react9.memo)(
3755
+ var ChatMessageItem = (0, import_react10.memo)(
3514
3756
  ChatMessageItemView,
3515
3757
  (previousProps, nextProps) => isSameMessage(
3516
3758
  previousProps.message,
@@ -3542,7 +3784,7 @@ var Bubble = import_styled7.default.article`
3542
3784
  border-radius: 16px;
3543
3785
  }
3544
3786
  `;
3545
- var Header2 = import_styled7.default.div`
3787
+ var Header3 = import_styled7.default.div`
3546
3788
  display: flex;
3547
3789
  align-items: center;
3548
3790
  gap: 10px;
@@ -3584,7 +3826,7 @@ var CollapseToggle = import_styled7.default.button`
3584
3826
  color: rgba(255, 255, 255, 0.92);
3585
3827
  }
3586
3828
  `;
3587
- var Content = import_styled7.default.div`
3829
+ var Content2 = import_styled7.default.div`
3588
3830
  color: rgba(255, 255, 255, 0.92);
3589
3831
  font-size: 14px;
3590
3832
  line-height: 1.6;
@@ -3728,7 +3970,7 @@ var AttachmentImage = import_styled7.default.img`
3728
3970
  var TableWrapper = import_styled7.default.div`
3729
3971
  overflow-x: auto;
3730
3972
  `;
3731
- var caretBlink = import_react10.keyframes`
3973
+ var caretBlink = import_react11.keyframes`
3732
3974
  0%, 49% {
3733
3975
  opacity: 1;
3734
3976
  }
@@ -3737,7 +3979,7 @@ var caretBlink = import_react10.keyframes`
3737
3979
  opacity: 0.2;
3738
3980
  }
3739
3981
  `;
3740
- var shimmer = import_react10.keyframes`
3982
+ var shimmer = import_react11.keyframes`
3741
3983
  0%, 100% {
3742
3984
  transform: scale(0.9) rotate(0deg);
3743
3985
  opacity: 0.55;
@@ -3956,24 +4198,24 @@ var ChatThreadView = ({
3956
4198
  onQuestionnaireSubmit,
3957
4199
  renderMessageBlock
3958
4200
  }) => {
3959
- const containerRef = (0, import_react11.useRef)(null);
3960
- const conversationTurns = (0, import_react11.useMemo)(
4201
+ const containerRef = (0, import_react12.useRef)(null);
4202
+ const conversationTurns = (0, import_react12.useMemo)(
3961
4203
  () => groupConversationTurns(historyMessages, streamingMessage),
3962
4204
  [historyMessages, streamingMessage]
3963
4205
  );
3964
4206
  const latestTurn = conversationTurns[conversationTurns.length - 1];
3965
4207
  const latestUserMessageId = latestTurn?.userMessage?.id;
3966
4208
  const latestHistoryMessage = historyMessages[historyMessages.length - 1];
3967
- const latestTurnRef = (0, import_react11.useRef)(null);
3968
- const reservedSpaceFrameRef = (0, import_react11.useRef)(null);
3969
- const isLoadingPreviousRef = (0, import_react11.useRef)(false);
3970
- const isPinnedRef = (0, import_react11.useRef)(true);
3971
- const lastHistoryMessageIdRef = (0, import_react11.useRef)(latestHistoryMessage?.id);
3972
- const lastStreamingMessageIdRef = (0, import_react11.useRef)(streamingMessage?.id);
3973
- const [latestTurnMinHeight, setLatestTurnMinHeight] = (0, import_react11.useState)(0);
3974
- const [isDetached, setIsDetached] = (0, import_react11.useState)(false);
3975
- const [pendingNewMessageCount, setPendingNewMessageCount] = (0, import_react11.useState)(0);
3976
- const measureLatestTurnMinHeight = (0, import_react11.useCallback)(() => {
4209
+ const latestTurnRef = (0, import_react12.useRef)(null);
4210
+ const reservedSpaceFrameRef = (0, import_react12.useRef)(null);
4211
+ const isLoadingPreviousRef = (0, import_react12.useRef)(false);
4212
+ const isPinnedRef = (0, import_react12.useRef)(true);
4213
+ const lastHistoryMessageIdRef = (0, import_react12.useRef)(latestHistoryMessage?.id);
4214
+ const lastStreamingMessageIdRef = (0, import_react12.useRef)(streamingMessage?.id);
4215
+ const [latestTurnMinHeight, setLatestTurnMinHeight] = (0, import_react12.useState)(0);
4216
+ const [isDetached, setIsDetached] = (0, import_react12.useState)(false);
4217
+ const [pendingNewMessageCount, setPendingNewMessageCount] = (0, import_react12.useState)(0);
4218
+ const measureLatestTurnMinHeight = (0, import_react12.useCallback)(() => {
3977
4219
  const container = containerRef.current;
3978
4220
  if (!container)
3979
4221
  return;
@@ -3983,7 +4225,7 @@ var ChatThreadView = ({
3983
4225
  const nextMinHeight = Math.max(0, container.clientHeight - paddingTop - paddingBottom);
3984
4226
  setLatestTurnMinHeight((current) => current === nextMinHeight ? current : nextMinHeight);
3985
4227
  }, []);
3986
- const scrollToBottom = (0, import_react11.useCallback)((force = false) => {
4228
+ const scrollToBottom = (0, import_react12.useCallback)((force = false) => {
3987
4229
  const container = containerRef.current;
3988
4230
  if (!container)
3989
4231
  return false;
@@ -3999,12 +4241,12 @@ var ChatThreadView = ({
3999
4241
  }
4000
4242
  return true;
4001
4243
  }, []);
4002
- const markThreadPinned = (0, import_react11.useCallback)(() => {
4244
+ const markThreadPinned = (0, import_react12.useCallback)(() => {
4003
4245
  isPinnedRef.current = true;
4004
4246
  setIsDetached(false);
4005
4247
  setPendingNewMessageCount(0);
4006
4248
  }, []);
4007
- const scrollToBottomAndPin = (0, import_react11.useCallback)(
4249
+ const scrollToBottomAndPin = (0, import_react12.useCallback)(
4008
4250
  (force = false) => {
4009
4251
  const didScroll = scrollToBottom(force);
4010
4252
  if (!didScroll)
@@ -4013,7 +4255,7 @@ var ChatThreadView = ({
4013
4255
  },
4014
4256
  [markThreadPinned, scrollToBottom]
4015
4257
  );
4016
- const handleLoadPreviousMessages = (0, import_react11.useCallback)(async () => {
4258
+ const handleLoadPreviousMessages = (0, import_react12.useCallback)(async () => {
4017
4259
  const container = containerRef.current;
4018
4260
  if (!container || !onLoadPreviousMessages || isLoadingPreviousMessages) {
4019
4261
  return;
@@ -4038,7 +4280,7 @@ var ChatThreadView = ({
4038
4280
  nextContainer.scrollTop = nextContainer.scrollHeight - previousScrollHeight + previousScrollTop;
4039
4281
  });
4040
4282
  }, [isLoadingPreviousMessages, onLoadPreviousMessages]);
4041
- const handleContainerScroll = (0, import_react11.useCallback)(() => {
4283
+ const handleContainerScroll = (0, import_react12.useCallback)(() => {
4042
4284
  const container = containerRef.current;
4043
4285
  if (!container)
4044
4286
  return;
@@ -4052,7 +4294,7 @@ var ChatThreadView = ({
4052
4294
  setPendingNewMessageCount(0);
4053
4295
  }
4054
4296
  }, [handleLoadPreviousMessages, onLoadPreviousMessages]);
4055
- (0, import_react11.useLayoutEffect)(() => {
4297
+ (0, import_react12.useLayoutEffect)(() => {
4056
4298
  const nextHistoryMessageId = latestHistoryMessage?.id;
4057
4299
  if (lastHistoryMessageIdRef.current === nextHistoryMessageId) {
4058
4300
  return;
@@ -4076,7 +4318,7 @@ var ChatThreadView = ({
4076
4318
  });
4077
4319
  }
4078
4320
  }, [latestHistoryMessage, markThreadPinned, scrollToBottom]);
4079
- (0, import_react11.useLayoutEffect)(() => {
4321
+ (0, import_react12.useLayoutEffect)(() => {
4080
4322
  const nextStreamingMessageId = streamingMessage?.id;
4081
4323
  if (lastStreamingMessageIdRef.current === nextStreamingMessageId) {
4082
4324
  return;
@@ -4091,7 +4333,7 @@ var ChatThreadView = ({
4091
4333
  });
4092
4334
  }
4093
4335
  }, [streamingMessage]);
4094
- (0, import_react11.useLayoutEffect)(() => {
4336
+ (0, import_react12.useLayoutEffect)(() => {
4095
4337
  if (reservedSpaceFrameRef.current !== null) {
4096
4338
  window.cancelAnimationFrame(reservedSpaceFrameRef.current);
4097
4339
  reservedSpaceFrameRef.current = null;
@@ -4121,7 +4363,7 @@ var ChatThreadView = ({
4121
4363
  }
4122
4364
  };
4123
4365
  }, [latestTurn, latestUserMessageId, error2, measureLatestTurnMinHeight, scrollToBottom]);
4124
- (0, import_react11.useLayoutEffect)(() => {
4366
+ (0, import_react12.useLayoutEffect)(() => {
4125
4367
  if (!latestTurn)
4126
4368
  return;
4127
4369
  const handleResize = () => {
@@ -4147,7 +4389,7 @@ var ChatThreadView = ({
4147
4389
  window.removeEventListener("resize", handleResize);
4148
4390
  };
4149
4391
  }, [latestTurn, latestUserMessageId, measureLatestTurnMinHeight, scrollToBottom]);
4150
- (0, import_react11.useLayoutEffect)(() => {
4392
+ (0, import_react12.useLayoutEffect)(() => {
4151
4393
  const latestTurnElement = latestTurnRef.current;
4152
4394
  if (!latestTurnElement || typeof ResizeObserver === "undefined") {
4153
4395
  return;
@@ -4160,7 +4402,7 @@ var ChatThreadView = ({
4160
4402
  observer.disconnect();
4161
4403
  };
4162
4404
  }, [latestTurn, scrollToBottom]);
4163
- (0, import_react11.useLayoutEffect)(() => {
4405
+ (0, import_react12.useLayoutEffect)(() => {
4164
4406
  const latestTurnElement = latestTurnRef.current;
4165
4407
  if (!latestTurnElement || typeof MutationObserver === "undefined") {
4166
4408
  return;
@@ -4267,13 +4509,13 @@ var ChatThread = () => {
4267
4509
  onLoadMoreHistoryMessages,
4268
4510
  labels
4269
4511
  } = useChatContext();
4270
- const handleRetry = (0, import_react11.useCallback)(() => {
4512
+ const handleRetry = (0, import_react12.useCallback)(() => {
4271
4513
  if (!activeSessionId)
4272
4514
  return;
4273
4515
  clearSessionError(activeSessionId);
4274
4516
  void retryRef.current(activeSessionId);
4275
4517
  }, [activeSessionId, clearSessionError, retryRef]);
4276
- const handleQuestionnaireSubmit = (0, import_react11.useCallback)(
4518
+ const handleQuestionnaireSubmit = (0, import_react12.useCallback)(
4277
4519
  async (submission) => {
4278
4520
  const sourceSessionId = activeSessionId;
4279
4521
  if (customQuestionnaireSubmit) {
@@ -4308,7 +4550,7 @@ var ChatThread = () => {
4308
4550
  },
4309
4551
  [activeSessionId, customQuestionnaireSubmit, preferredMode, sendRef, updateQA]
4310
4552
  );
4311
- const handleConfirmation = (0, import_react11.useCallback)(
4553
+ const handleConfirmation = (0, import_react12.useCallback)(
4312
4554
  async (submission) => {
4313
4555
  const sourceSessionId = activeSessionId;
4314
4556
  if (customConfirmationSubmit) {
@@ -4327,7 +4569,7 @@ var ChatThread = () => {
4327
4569
  },
4328
4570
  [activeSessionId, customConfirmationSubmit, preferredMode, sendRef]
4329
4571
  );
4330
- const handleLoadPreviousMessages = (0, import_react11.useCallback)(async () => {
4572
+ const handleLoadPreviousMessages = (0, import_react12.useCallback)(async () => {
4331
4573
  if (!activeSession || !onLoadMoreHistoryMessages || !historyMessagePagination?.hasMorePrevious || !historyMessagePagination.previousCursor || historyMessagePagination.isLoadingPrevious) {
4332
4574
  return;
4333
4575
  }
@@ -4366,13 +4608,14 @@ var ChatThread = () => {
4366
4608
  if (!hasSessions || messages.length === 0 && !streamingMessage) {
4367
4609
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ChatThreadEmptyState, {});
4368
4610
  }
4611
+ const displayError = error2 && !(error2.toLowerCase().includes("plan option timeout") || error2.toLowerCase().includes("plan_option_timeout") || error2.toLowerCase().includes("selection expired") || labels.questionnaireExpired && error2.includes(labels.questionnaireExpired)) ? error2 : void 0;
4369
4612
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
4370
4613
  ChatThreadView,
4371
4614
  {
4372
4615
  activeMode: preferredMode,
4373
4616
  historyMessages: messages,
4374
4617
  streamingMessage,
4375
- error: error2,
4618
+ error: displayError,
4376
4619
  isLoadingPreviousMessages: historyMessagePagination?.isLoadingPrevious,
4377
4620
  previousMessagesError: historyMessagePagination?.error,
4378
4621
  retryButtonLabel: labels.retryButton,
@@ -4521,7 +4764,7 @@ var ScrollToLatestBadge = import_styled9.default.span`
4521
4764
  `;
4522
4765
 
4523
4766
  // src/components/chat-composer/index.tsx
4524
- var import_react17 = require("react");
4767
+ var import_react18 = require("react");
4525
4768
  var import_styled14 = __toESM(require("@emotion/styled"));
4526
4769
 
4527
4770
  // ../../node_modules/.pnpm/@floating-ui+react@0.27.16_react-dom@18.3.1_react@18.3.1/node_modules/@floating-ui/react/dist/floating-ui.react.mjs
@@ -4683,7 +4926,7 @@ function getFrameElement(win) {
4683
4926
 
4684
4927
  // ../../node_modules/.pnpm/@floating-ui+react@0.27.16_react-dom@18.3.1_react@18.3.1/node_modules/@floating-ui/react/dist/floating-ui.react.utils.mjs
4685
4928
  var React = __toESM(require("react"), 1);
4686
- var import_react12 = require("react");
4929
+ var import_react13 = require("react");
4687
4930
 
4688
4931
  // ../../node_modules/.pnpm/@floating-ui+utils@0.2.10/node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs
4689
4932
  var min = Math.min;
@@ -5170,7 +5413,7 @@ function getDocument(node) {
5170
5413
  var isClient = typeof document !== "undefined";
5171
5414
  var noop = function noop2() {
5172
5415
  };
5173
- var index = isClient ? import_react12.useLayoutEffect : noop;
5416
+ var index = isClient ? import_react13.useLayoutEffect : noop;
5174
5417
  var SafeReact = {
5175
5418
  ...React
5176
5419
  };
@@ -6379,12 +6622,12 @@ var computePosition2 = (reference, floating, options) => {
6379
6622
 
6380
6623
  // ../../node_modules/.pnpm/@floating-ui+react-dom@2.1.6_react-dom@18.3.1_react@18.3.1/node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.mjs
6381
6624
  var React2 = __toESM(require("react"), 1);
6382
- var import_react13 = require("react");
6625
+ var import_react14 = require("react");
6383
6626
  var ReactDOM = __toESM(require("react-dom"), 1);
6384
6627
  var isClient2 = typeof document !== "undefined";
6385
6628
  var noop3 = function noop4() {
6386
6629
  };
6387
- var index2 = isClient2 ? import_react13.useLayoutEffect : noop3;
6630
+ var index2 = isClient2 ? import_react14.useLayoutEffect : noop3;
6388
6631
  function deepEqual(a, b) {
6389
6632
  if (a === b) {
6390
6633
  return true;
@@ -7119,10 +7362,10 @@ var resolveSendSession = ({
7119
7362
  };
7120
7363
 
7121
7364
  // src/components/chat-composer/hooks/use-chat-composer.ts
7122
- var import_react15 = require("react");
7365
+ var import_react16 = require("react");
7123
7366
 
7124
7367
  // src/components/chat-composer/hooks/use-composer-attachments.ts
7125
- var import_react14 = require("react");
7368
+ var import_react15 = require("react");
7126
7369
  var SUPPORTED_IMAGE_MIME_TYPES = /* @__PURE__ */ new Set(["image/png", "image/jpeg", "image/webp"]);
7127
7370
  var MAX_COMPOSER_ATTACHMENTS = 10;
7128
7371
  var createObjectUrl = (file) => typeof URL !== "undefined" && typeof URL.createObjectURL === "function" ? URL.createObjectURL(file) : "";
@@ -7136,12 +7379,12 @@ var releaseComposerAttachments = (attachments) => {
7136
7379
  attachments.forEach((attachment) => revokeObjectUrl(attachment.previewUrl));
7137
7380
  };
7138
7381
  var useComposerAttachments = () => {
7139
- const [attachments, setAttachments] = (0, import_react14.useState)([]);
7140
- const attachmentsRef = (0, import_react14.useRef)([]);
7141
- (0, import_react14.useEffect)(() => {
7382
+ const [attachments, setAttachments] = (0, import_react15.useState)([]);
7383
+ const attachmentsRef = (0, import_react15.useRef)([]);
7384
+ (0, import_react15.useEffect)(() => {
7142
7385
  attachmentsRef.current = attachments;
7143
7386
  }, [attachments]);
7144
- (0, import_react14.useEffect)(
7387
+ (0, import_react15.useEffect)(
7145
7388
  () => () => {
7146
7389
  releaseComposerAttachments(attachmentsRef.current);
7147
7390
  },
@@ -7267,7 +7510,7 @@ var useChatComposer = () => {
7267
7510
  const { transport, enableImageAttachments, labels, store } = useChatContext();
7268
7511
  const modelsLoader = transport.getModels;
7269
7512
  const skillsLoader = transport.getSkills;
7270
- const activeSkillsLoaderRef = (0, import_react15.useRef)(skillsLoader);
7513
+ const activeSkillsLoaderRef = (0, import_react16.useRef)(skillsLoader);
7271
7514
  const activeSessionId = useChatStore((s) => s.activeSessionId);
7272
7515
  const preferredMode = useChatStore((s) => s.preferredMode);
7273
7516
  const streamingSessionId = useChatStore(
@@ -7289,16 +7532,16 @@ var useChatComposer = () => {
7289
7532
  const setSessionError = useChatStore((s) => s.setSessionError);
7290
7533
  const clearSessionError = useChatStore((s) => s.clearSessionError);
7291
7534
  const setPreferredMode = useChatStore((s) => s.setPreferredMode);
7292
- const [availableModels, setAvailableModels] = (0, import_react15.useState)([]);
7293
- const [isModelsLoading, setIsModelsLoading] = (0, import_react15.useState)(true);
7294
- const [isModelsError, setIsModelsError] = (0, import_react15.useState)(false);
7295
- const [availableSkills, setAvailableSkills] = (0, import_react15.useState)(
7535
+ const [availableModels, setAvailableModels] = (0, import_react16.useState)([]);
7536
+ const [isModelsLoading, setIsModelsLoading] = (0, import_react16.useState)(true);
7537
+ const [isModelsError, setIsModelsError] = (0, import_react16.useState)(false);
7538
+ const [availableSkills, setAvailableSkills] = (0, import_react16.useState)(
7296
7539
  () => getCachedSkills(skillsLoader).skills
7297
7540
  );
7298
- const [isSkillsLoading, setIsSkillsLoading] = (0, import_react15.useState)(
7541
+ const [isSkillsLoading, setIsSkillsLoading] = (0, import_react16.useState)(
7299
7542
  () => Boolean(skillsLoader) && !getCachedSkills(skillsLoader).resolved
7300
7543
  );
7301
- const fetchModels = (0, import_react15.useCallback)(async () => {
7544
+ const fetchModels = (0, import_react16.useCallback)(async () => {
7302
7545
  setIsModelsLoading(true);
7303
7546
  setIsModelsError(false);
7304
7547
  try {
@@ -7310,16 +7553,16 @@ var useChatComposer = () => {
7310
7553
  setIsModelsLoading(false);
7311
7554
  }
7312
7555
  }, [modelsLoader]);
7313
- (0, import_react15.useEffect)(() => {
7556
+ (0, import_react16.useEffect)(() => {
7314
7557
  void fetchModels();
7315
7558
  }, [fetchModels]);
7316
- (0, import_react15.useEffect)(() => {
7559
+ (0, import_react16.useEffect)(() => {
7317
7560
  activeSkillsLoaderRef.current = skillsLoader;
7318
7561
  const cachedSkills = getCachedSkills(skillsLoader);
7319
7562
  setAvailableSkills(cachedSkills.skills);
7320
7563
  setIsSkillsLoading(Boolean(skillsLoader) && !cachedSkills.resolved);
7321
7564
  }, [skillsLoader]);
7322
- const fetchSkills = (0, import_react15.useCallback)(async () => {
7565
+ const fetchSkills = (0, import_react16.useCallback)(async () => {
7323
7566
  if (!skillsLoader) {
7324
7567
  setAvailableSkills([]);
7325
7568
  setIsSkillsLoading(false);
@@ -7349,35 +7592,35 @@ var useChatComposer = () => {
7349
7592
  }
7350
7593
  }
7351
7594
  }, [skillsLoader]);
7352
- (0, import_react15.useEffect)(() => {
7595
+ (0, import_react16.useEffect)(() => {
7353
7596
  void fetchSkills();
7354
7597
  }, [fetchSkills]);
7355
7598
  const hasModels = availableModels.length > 0;
7356
- const [value, setValue] = (0, import_react15.useState)("");
7357
- const [selectedModel, setSelectedModel] = (0, import_react15.useState)("");
7358
- const [selectedMode, setSelectedModeLocal] = (0, import_react15.useState)(DEFAULT_CHAT_AGENT_MODE);
7359
- const [selectedSkills, setSelectedSkills] = (0, import_react15.useState)([]);
7360
- const [attachmentNotice, setAttachmentNotice] = (0, import_react15.useState)(null);
7599
+ const [value, setValue] = (0, import_react16.useState)("");
7600
+ const [selectedModel, setSelectedModel] = (0, import_react16.useState)("");
7601
+ const [selectedMode, setSelectedModeLocal] = (0, import_react16.useState)(DEFAULT_CHAT_AGENT_MODE);
7602
+ const [selectedSkills, setSelectedSkills] = (0, import_react16.useState)([]);
7603
+ const [attachmentNotice, setAttachmentNotice] = (0, import_react16.useState)(null);
7361
7604
  const { attachments, appendFiles, removeAttachment, takeMessageAttachments } = useComposerAttachments();
7362
- const abortControllerBySessionRef = (0, import_react15.useRef)(/* @__PURE__ */ new Map());
7363
- const stopRequestBySessionRef = (0, import_react15.useRef)(/* @__PURE__ */ new Map());
7364
- const lastRequestBySessionRef = (0, import_react15.useRef)(/* @__PURE__ */ new Map());
7365
- const previousActiveSessionIdRef = (0, import_react15.useRef)(activeSessionId);
7366
- (0, import_react15.useEffect)(() => {
7605
+ const abortControllerBySessionRef = (0, import_react16.useRef)(/* @__PURE__ */ new Map());
7606
+ const stopRequestBySessionRef = (0, import_react16.useRef)(/* @__PURE__ */ new Map());
7607
+ const lastRequestBySessionRef = (0, import_react16.useRef)(/* @__PURE__ */ new Map());
7608
+ const previousActiveSessionIdRef = (0, import_react16.useRef)(activeSessionId);
7609
+ (0, import_react16.useEffect)(() => {
7367
7610
  setSelectedModel(
7368
7611
  (current) => resolveSelectedChatModel({ currentModel: current, availableModels, isModelsLoading })
7369
7612
  );
7370
7613
  }, [availableModels, isModelsLoading]);
7371
- (0, import_react15.useEffect)(() => {
7614
+ (0, import_react16.useEffect)(() => {
7372
7615
  setSelectedModeLocal(preferredMode ?? DEFAULT_CHAT_AGENT_MODE);
7373
7616
  }, [preferredMode]);
7374
- (0, import_react15.useEffect)(() => {
7617
+ (0, import_react16.useEffect)(() => {
7375
7618
  if (previousActiveSessionIdRef.current !== activeSessionId) {
7376
7619
  setSelectedSkills([]);
7377
7620
  previousActiveSessionIdRef.current = activeSessionId;
7378
7621
  }
7379
7622
  }, [activeSessionId]);
7380
- (0, import_react15.useEffect)(() => {
7623
+ (0, import_react16.useEffect)(() => {
7381
7624
  if (!attachmentNotice)
7382
7625
  return;
7383
7626
  const timeoutId = window.setTimeout(
@@ -7394,11 +7637,11 @@ var useChatComposer = () => {
7394
7637
  window.clearTimeout(stopRequest.timeoutId);
7395
7638
  stopRequest.timeoutId = null;
7396
7639
  };
7397
- const clearStopRequest = (0, import_react15.useCallback)((sessionId) => {
7640
+ const clearStopRequest = (0, import_react16.useCallback)((sessionId) => {
7398
7641
  clearStopTimeout(sessionId);
7399
7642
  stopRequestBySessionRef.current.delete(sessionId);
7400
7643
  }, []);
7401
- const moveSessionRuntimeState = (0, import_react15.useCallback)(
7644
+ const moveSessionRuntimeState = (0, import_react16.useCallback)(
7402
7645
  (previousSessionId, nextSessionId) => {
7403
7646
  if (previousSessionId === nextSessionId) {
7404
7647
  return;
@@ -7416,7 +7659,7 @@ var useChatComposer = () => {
7416
7659
  },
7417
7660
  []
7418
7661
  );
7419
- const finalizeStop = (0, import_react15.useCallback)(
7662
+ const finalizeStop = (0, import_react16.useCallback)(
7420
7663
  (sessionId) => {
7421
7664
  const stopRequest = stopRequestBySessionRef.current.get(sessionId);
7422
7665
  if (stopRequest) {
@@ -7433,7 +7676,7 @@ var useChatComposer = () => {
7433
7676
  },
7434
7677
  [clearStopRequest, finalizeStoppedStreamingMessage]
7435
7678
  );
7436
- const runStream = (0, import_react15.useCallback)(
7679
+ const runStream = (0, import_react16.useCallback)(
7437
7680
  async ({
7438
7681
  localSessionId,
7439
7682
  sessionId,
@@ -7558,7 +7801,7 @@ var useChatComposer = () => {
7558
7801
  store
7559
7802
  ]
7560
7803
  );
7561
- const send = (0, import_react15.useCallback)(
7804
+ const send = (0, import_react16.useCallback)(
7562
7805
  async (contentOverride, options) => {
7563
7806
  const content = (contentOverride ?? value).trim();
7564
7807
  const includeComposerAttachments = options?.includeComposerAttachments ?? true;
@@ -7638,7 +7881,7 @@ var useChatComposer = () => {
7638
7881
  store
7639
7882
  ]
7640
7883
  );
7641
- const openSkillPicker = (0, import_react15.useCallback)(() => {
7884
+ const openSkillPicker = (0, import_react16.useCallback)(() => {
7642
7885
  setValue((current) => {
7643
7886
  const matchedSkillQuery = current.match(/(^|\s)\/([^\s/]*)$/);
7644
7887
  if (matchedSkillQuery && matchedSkillQuery.index !== void 0) {
@@ -7651,7 +7894,7 @@ var useChatComposer = () => {
7651
7894
  return /\s$/.test(current) ? `${current}/` : `${current} /`;
7652
7895
  });
7653
7896
  }, []);
7654
- const stopSession = (0, import_react15.useCallback)(
7897
+ const stopSession = (0, import_react16.useCallback)(
7655
7898
  async (sessionId) => {
7656
7899
  const storeState = store.getState();
7657
7900
  const isSessionStreaming = storeState.isStreamingBySession[sessionId] ?? false;
@@ -7761,14 +8004,14 @@ var useChatComposer = () => {
7761
8004
  };
7762
8005
 
7763
8006
  // src/components/chat-composer/components/chat-composer-attachment-list.tsx
7764
- var import_react16 = require("react");
8007
+ var import_react17 = require("react");
7765
8008
  var import_styled10 = __toESM(require("@emotion/styled"));
7766
8009
  var import_jsx_runtime12 = require("@emotion/react/jsx-runtime");
7767
8010
  var ChatComposerAttachmentList = ({
7768
8011
  attachments,
7769
8012
  onRemoveAttachment
7770
8013
  }) => {
7771
- const [activeImage, setActiveImage] = (0, import_react16.useState)(null);
8014
+ const [activeImage, setActiveImage] = (0, import_react17.useState)(null);
7772
8015
  if (!attachments.length) {
7773
8016
  return null;
7774
8017
  }
@@ -8447,11 +8690,11 @@ var ChatComposerView = ({
8447
8690
  onStop,
8448
8691
  onSend
8449
8692
  }) => {
8450
- const imageInputRef = (0, import_react17.useRef)(null);
8451
- const inputRef = (0, import_react17.useRef)(null);
8452
- const [isComposerExpandable, setIsComposerExpandable] = (0, import_react17.useState)(false);
8453
- const [isComposerExpanded, setIsComposerExpanded] = (0, import_react17.useState)(false);
8454
- const [activeSkillNavigation, setActiveSkillNavigation] = (0, import_react17.useState)({
8693
+ const imageInputRef = (0, import_react18.useRef)(null);
8694
+ const inputRef = (0, import_react18.useRef)(null);
8695
+ const [isComposerExpandable, setIsComposerExpandable] = (0, import_react18.useState)(false);
8696
+ const [isComposerExpanded, setIsComposerExpanded] = (0, import_react18.useState)(false);
8697
+ const [activeSkillNavigation, setActiveSkillNavigation] = (0, import_react18.useState)({
8455
8698
  queryKey: "",
8456
8699
  index: 0
8457
8700
  });
@@ -8494,20 +8737,20 @@ var ChatComposerView = ({
8494
8737
  ],
8495
8738
  whileElementsMounted: autoUpdate
8496
8739
  });
8497
- const setSkillMenuReference = (0, import_react17.useCallback)(
8740
+ const setSkillMenuReference = (0, import_react18.useCallback)(
8498
8741
  (element) => {
8499
8742
  refs.setReference(element);
8500
8743
  },
8501
8744
  [refs]
8502
8745
  );
8503
- const setSkillMenuFloating = (0, import_react17.useCallback)(
8746
+ const setSkillMenuFloating = (0, import_react18.useCallback)(
8504
8747
  (element) => {
8505
8748
  refs.setFloating(element);
8506
8749
  },
8507
8750
  [refs]
8508
8751
  );
8509
8752
  const activeSkillIndex = activeSkillNavigation.queryKey === activeSkillQueryKey ? activeSkillNavigation.index : 0;
8510
- (0, import_react17.useLayoutEffect)(() => {
8753
+ (0, import_react18.useLayoutEffect)(() => {
8511
8754
  const element = inputRef.current;
8512
8755
  if (!element) {
8513
8756
  return;
@@ -8657,7 +8900,7 @@ var ChatComposerView = ({
8657
8900
  }
8658
8901
  )
8659
8902
  ] }),
8660
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Footer, { children: [
8903
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Footer2, { children: [
8661
8904
  /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(LeadingActions, { "data-testid": "chat-composer-leading-actions", children: [
8662
8905
  enableImageAttachments ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8663
8906
  AttachButton,
@@ -8749,7 +8992,7 @@ var ChatComposer = () => {
8749
8992
  const { labels, sendRef, retryRef, stopRef, enableImageAttachments } = useChatContext();
8750
8993
  const { state, actions } = useChatComposer();
8751
8994
  const { send, retry } = actions;
8752
- (0, import_react17.useEffect)(() => {
8995
+ (0, import_react18.useEffect)(() => {
8753
8996
  sendRef.current = send;
8754
8997
  retryRef.current = async (sessionId) => {
8755
8998
  retry(sessionId);
@@ -8997,7 +9240,7 @@ var ComposerExpandButton = import_styled14.default.button`
8997
9240
  color: rgba(255, 255, 255, 0.92);
8998
9241
  }
8999
9242
  `;
9000
- var Footer = import_styled14.default.div`
9243
+ var Footer2 = import_styled14.default.div`
9001
9244
  grid-area: footer;
9002
9245
  display: flex;
9003
9246
  align-items: center;
@@ -9078,14 +9321,14 @@ var SkillButton = import_styled14.default.button`
9078
9321
  `;
9079
9322
 
9080
9323
  // src/components/chat-conversation-list/index.tsx
9081
- var import_react20 = require("react");
9324
+ var import_react21 = require("react");
9082
9325
  var import_styled16 = __toESM(require("@emotion/styled"));
9083
9326
 
9084
9327
  // src/components/chat-conversation-list/components/chat-session-item.tsx
9085
- var import_react19 = require("react");
9328
+ var import_react20 = require("react");
9086
9329
  var import_styled15 = __toESM(require("@emotion/styled"));
9087
9330
  var import_jsx_runtime17 = require("@emotion/react/jsx-runtime");
9088
- var ChatSessionItem = (0, import_react19.memo)(({ session, isActive, onClick }) => {
9331
+ var ChatSessionItem = (0, import_react20.memo)(({ session, isActive, onClick }) => {
9089
9332
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
9090
9333
  SessionButton,
9091
9334
  {
@@ -9179,14 +9422,14 @@ var ChatConversationList = () => {
9179
9422
  const setHistorySessionMessageLoadStatus = useChatStore(
9180
9423
  (s) => s.setHistorySessionMessageLoadStatus
9181
9424
  );
9182
- const isLoadingMoreRef = (0, import_react20.useRef)(false);
9183
- const hasSeenLoadingMoreRef = (0, import_react20.useRef)(false);
9184
- (0, import_react20.useEffect)(() => {
9425
+ const isLoadingMoreRef = (0, import_react21.useRef)(false);
9426
+ const hasSeenLoadingMoreRef = (0, import_react21.useRef)(false);
9427
+ (0, import_react21.useEffect)(() => {
9185
9428
  if (!historySessionList)
9186
9429
  return;
9187
9430
  hydrateHistorySessions(historySessionList.sessions);
9188
9431
  }, [historySessionList, hydrateHistorySessions]);
9189
- (0, import_react20.useEffect)(() => {
9432
+ (0, import_react21.useEffect)(() => {
9190
9433
  if (historySessionList?.isLoading) {
9191
9434
  hasSeenLoadingMoreRef.current = true;
9192
9435
  return;
@@ -9196,7 +9439,7 @@ var ChatConversationList = () => {
9196
9439
  isLoadingMoreRef.current = false;
9197
9440
  }
9198
9441
  }, [historySessionList?.isLoading]);
9199
- (0, import_react20.useEffect)(() => {
9442
+ (0, import_react21.useEffect)(() => {
9200
9443
  isLoadingMoreRef.current = false;
9201
9444
  hasSeenLoadingMoreRef.current = false;
9202
9445
  }, [historySessionList?.sessions.length, historySessionList?.hasMore]);
@@ -9395,7 +9638,7 @@ var AiChatWorkspaceContent = ({
9395
9638
  })
9396
9639
  );
9397
9640
  const shouldShowComposerOnly = showComposerOnlyBeforeFirstMessage && !showConversationList && !isConversationStarted;
9398
- (0, import_react21.useEffect)(() => {
9641
+ (0, import_react22.useEffect)(() => {
9399
9642
  onConversationStartedChange?.(isConversationStarted);
9400
9643
  }, [isConversationStarted, onConversationStartedChange]);
9401
9644
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Root, { "data-testid": "ai-chat", children: [