@xinghunm/ai-chat 0.2.1 → 0.2.2

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 (3) hide show
  1. package/dist/index.js +378 -294
  2. package/dist/index.mjs +331 -247
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -45,7 +45,7 @@ __export(src_exports, {
45
45
  module.exports = __toCommonJS(src_exports);
46
46
 
47
47
  // src/components/ai-chat/index.tsx
48
- var import_styled18 = __toESM(require("@emotion/styled"));
48
+ var import_styled17 = __toESM(require("@emotion/styled"));
49
49
  var import_compass_ui4 = require("@xinghunm/compass-ui");
50
50
 
51
51
  // src/components/ai-chat-provider/index.tsx
@@ -636,8 +636,8 @@ var AiChatProvider = (props) => {
636
636
  };
637
637
 
638
638
  // src/components/chat-thread/index.tsx
639
- var import_react11 = require("react");
640
- var import_styled10 = __toESM(require("@emotion/styled"));
639
+ var import_react10 = require("react");
640
+ var import_styled9 = __toESM(require("@emotion/styled"));
641
641
 
642
642
  // src/context/use-chat-context.ts
643
643
  var import_react3 = require("react");
@@ -655,22 +655,6 @@ var useChatStore = (selector) => {
655
655
 
656
656
  // src/components/chat-thread/lib/chat-thread.ts
657
657
  var CHAT_THREAD_SCROLL_TOP_GAP = 16;
658
- var findLatestUserMessageId = (historyMessages) => {
659
- for (let index = historyMessages.length - 1; index >= 0; index -= 1) {
660
- if (historyMessages[index]?.role === "user") {
661
- return historyMessages[index]?.id;
662
- }
663
- }
664
- return void 0;
665
- };
666
- var calculateChatThreadScrollSpacerHeight = ({
667
- containerClientHeight,
668
- containerScrollHeight,
669
- targetOffsetTop
670
- }) => Math.max(
671
- 0,
672
- targetOffsetTop - CHAT_THREAD_SCROLL_TOP_GAP - (containerScrollHeight - containerClientHeight)
673
- );
674
658
 
675
659
  // src/components/chat-thread/components/chat-message-item.tsx
676
660
  var import_react8 = require("react");
@@ -902,11 +886,21 @@ var useChatMessageReveal = (message) => {
902
886
  }, [batchedTargetUnitCount, displayedUnitCount, isAssistantStreaming, message.role]);
903
887
  const settledContent = isFreshBlockActive ? contentBlocks.slice(0, -1).join("\n\n") : displayedContent;
904
888
  const freshContent = isFreshBlockActive ? contentBlocks[contentBlocks.length - 1] ?? "" : "";
889
+ const displayedBlocks = isAssistantStreaming && contentBlocks.length > 1 ? contentBlocks.map((content, index) => ({
890
+ content,
891
+ tone: isFreshBlockActive && index === contentBlocks.length - 1 ? "fresh" : "settled"
892
+ })) : [
893
+ {
894
+ content: displayedContent,
895
+ tone: "settled"
896
+ }
897
+ ];
905
898
  return {
906
899
  isAssistantStreaming,
907
900
  displayedContent,
908
901
  settledContent,
909
- freshContent
902
+ freshContent,
903
+ displayedBlocks
910
904
  };
911
905
  };
912
906
 
@@ -1854,7 +1848,7 @@ var ChatMessageItemView = ({
1854
1848
  }) => {
1855
1849
  const { labels } = useChatContext();
1856
1850
  const [activeImage, setActiveImage] = (0, import_react8.useState)(void 0);
1857
- const { displayedContent, freshContent, isAssistantStreaming, settledContent } = useChatMessageReveal(message);
1851
+ const { displayedBlocks, displayedContent, freshContent, isAssistantStreaming, settledContent } = useChatMessageReveal(message);
1858
1852
  const isStoppedAssistant = message.role === "assistant" && message.status === "stopped";
1859
1853
  const attachments = message.attachments ?? [];
1860
1854
  const blocks = message.blocks ?? [];
@@ -1923,9 +1917,17 @@ var ChatMessageItemView = ({
1923
1917
  }
1924
1918
  };
1925
1919
  const renderTextContent = () => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1926
- settledContent ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ContentBlock, { "data-testid": "chat-message-settled-block", "data-block-tone": "settled", children: renderMarkdownContent(settledContent) }) : null,
1927
- freshContent ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ContentBlock, { "data-testid": "chat-message-fresh-block", "data-block-tone": "fresh", children: renderMarkdownContent(freshContent) }) : null,
1928
- !settledContent && !freshContent && hasTextContent ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ContentBlock, { "data-testid": "chat-message-settled-block", "data-block-tone": "settled", children: renderMarkdownContent(displayedContent) }) : null
1920
+ displayedBlocks.filter((block) => block.content).map((block, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1921
+ ContentBlock,
1922
+ {
1923
+ "data-testid": block.tone === "fresh" ? "chat-message-fresh-block" : "chat-message-settled-block",
1924
+ "data-block-tone": block.tone,
1925
+ "data-block-index": index,
1926
+ children: renderMarkdownContent(block.content)
1927
+ },
1928
+ `${block.tone}-${index}`
1929
+ )),
1930
+ !displayedBlocks.some((block) => block.content) && !settledContent && !freshContent && hasTextContent ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ContentBlock, { "data-testid": "chat-message-settled-block", "data-block-tone": "settled", children: renderMarkdownContent(displayedContent) }) : null
1929
1931
  ] });
1930
1932
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1931
1933
  /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Bubble, { "data-role": message.role, "data-status": message.status ?? "done", children: [
@@ -2189,65 +2191,21 @@ var StreamingCaret = import_styled7.default.span`
2189
2191
  animation: ${caretBlink} 0.9s steps(1) infinite;
2190
2192
  `;
2191
2193
 
2192
- // src/components/chat-thread/components/chat-thread-history-list.tsx
2193
- var import_react10 = require("react");
2194
+ // src/components/chat-thread/components/chat-thread-empty-state.tsx
2194
2195
  var import_styled8 = __toESM(require("@emotion/styled"));
2195
2196
  var import_jsx_runtime9 = require("@emotion/react/jsx-runtime");
2196
- var ChatThreadHistoryList = (0, import_react10.memo)(
2197
- ({
2198
- mode,
2199
- historyMessages,
2200
- latestUserMessageId,
2201
- latestUserMessageRef,
2202
- onConfirmationSubmit,
2203
- onQuestionnaireSubmit,
2204
- renderMessageBlock
2205
- }) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(HistoryGroup, { "data-testid": "chat-thread-history", children: historyMessages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2206
- MessageSlot,
2207
- {
2208
- ref: message.id === latestUserMessageId ? latestUserMessageRef : null,
2209
- "data-testid": message.id === latestUserMessageId ? "chat-latest-user-anchor" : void 0,
2210
- style: message.id === latestUserMessageId ? {
2211
- scrollMarginTop: `${CHAT_THREAD_SCROLL_TOP_GAP}px`
2212
- } : void 0,
2213
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2214
- ChatMessageItem,
2215
- {
2216
- mode,
2217
- message,
2218
- onConfirmationSubmit,
2219
- onQuestionnaireSubmit,
2220
- renderMessageBlock
2221
- }
2222
- )
2223
- },
2224
- message.id
2225
- )) })
2226
- );
2227
- ChatThreadHistoryList.displayName = "ChatThreadHistoryList";
2228
- var HistoryGroup = import_styled8.default.div`
2229
- display: contents;
2230
- `;
2231
- var MessageSlot = import_styled8.default.div`
2232
- display: flex;
2233
- align-items: flex-start;
2234
- `;
2235
-
2236
- // src/components/chat-thread/components/chat-thread-empty-state.tsx
2237
- var import_styled9 = __toESM(require("@emotion/styled"));
2238
- var import_jsx_runtime10 = require("@emotion/react/jsx-runtime");
2239
2197
  var ChatThreadEmptyState = () => {
2240
2198
  const { labels } = useChatContext();
2241
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(EmptyShell, { "data-testid": "chat-empty-hero", children: [
2242
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(HeroMark, { children: [
2243
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(HeroOrbit, {}),
2244
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(HeroCore, { children: "AI" })
2199
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(EmptyShell, { "data-testid": "chat-empty-hero", children: [
2200
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(HeroMark, { children: [
2201
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(HeroOrbit, {}),
2202
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(HeroCore, { children: "AI" })
2245
2203
  ] }),
2246
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(HeroTitle, { children: labels.emptyStateTitle }),
2247
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(HeroSubtitle, { children: labels.emptyStateSubtitle })
2204
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(HeroTitle, { children: labels.emptyStateTitle }),
2205
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(HeroSubtitle, { children: labels.emptyStateSubtitle })
2248
2206
  ] });
2249
2207
  };
2250
- var EmptyShell = import_styled9.default.div`
2208
+ var EmptyShell = import_styled8.default.div`
2251
2209
  flex: 1;
2252
2210
  min-height: 0;
2253
2211
  display: flex;
@@ -2257,7 +2215,7 @@ var EmptyShell = import_styled9.default.div`
2257
2215
  gap: 16px;
2258
2216
  padding: 48px 24px 24px;
2259
2217
  `;
2260
- var HeroMark = import_styled9.default.div`
2218
+ var HeroMark = import_styled8.default.div`
2261
2219
  position: relative;
2262
2220
  width: 108px;
2263
2221
  height: 108px;
@@ -2265,7 +2223,7 @@ var HeroMark = import_styled9.default.div`
2265
2223
  display: grid;
2266
2224
  place-items: center;
2267
2225
  `;
2268
- var HeroOrbit = import_styled9.default.div`
2226
+ var HeroOrbit = import_styled8.default.div`
2269
2227
  position: absolute;
2270
2228
  inset: 20px;
2271
2229
  border-radius: 50%;
@@ -2288,7 +2246,7 @@ var HeroOrbit = import_styled9.default.div`
2288
2246
  transform: rotate(-22deg);
2289
2247
  }
2290
2248
  `;
2291
- var HeroCore = import_styled9.default.div`
2249
+ var HeroCore = import_styled8.default.div`
2292
2250
  position: relative;
2293
2251
  z-index: 1;
2294
2252
  font-size: 28px;
@@ -2298,13 +2256,13 @@ var HeroCore = import_styled9.default.div`
2298
2256
  color: rgba(242, 244, 255, 0.96);
2299
2257
  text-shadow: 0 0 16px rgba(98, 116, 255, 0.65);
2300
2258
  `;
2301
- var HeroTitle = import_styled9.default.p`
2259
+ var HeroTitle = import_styled8.default.p`
2302
2260
  margin: 0;
2303
2261
  color: rgba(255, 255, 255, 0.88);
2304
2262
  font-size: 16px;
2305
2263
  line-height: 24px;
2306
2264
  `;
2307
- var HeroSubtitle = import_styled9.default.p`
2265
+ var HeroSubtitle = import_styled8.default.p`
2308
2266
  margin: 0;
2309
2267
  color: rgba(255, 255, 255, 0.72);
2310
2268
  font-size: 14px;
@@ -2312,7 +2270,74 @@ var HeroSubtitle = import_styled9.default.p`
2312
2270
  `;
2313
2271
 
2314
2272
  // src/components/chat-thread/index.tsx
2315
- var import_jsx_runtime11 = require("@emotion/react/jsx-runtime");
2273
+ var import_jsx_runtime10 = require("@emotion/react/jsx-runtime");
2274
+ var renderChatMessage = ({
2275
+ message,
2276
+ mode,
2277
+ onConfirmationSubmit,
2278
+ onQuestionnaireSubmit,
2279
+ renderMessageBlock
2280
+ }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2281
+ ChatMessageItem,
2282
+ {
2283
+ mode,
2284
+ message,
2285
+ onConfirmationSubmit,
2286
+ onQuestionnaireSubmit,
2287
+ renderMessageBlock
2288
+ }
2289
+ );
2290
+ var renderErrorState = ({
2291
+ error,
2292
+ onRetry,
2293
+ retryButtonLabel
2294
+ }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(ErrorState, { "data-testid": "chat-thread-error-state", children: [
2295
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ErrorText, { children: error }),
2296
+ onRetry ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ErrorActions, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(RetryButton, { type: "button", "data-testid": "chat-thread-retry", onClick: onRetry, children: retryButtonLabel }) }) : null
2297
+ ] });
2298
+ var groupConversationTurns = (historyMessages, streamingMessage) => {
2299
+ const turns = [];
2300
+ let currentTurn = null;
2301
+ historyMessages.forEach((message) => {
2302
+ if (message.role === "user") {
2303
+ currentTurn = {
2304
+ id: message.id,
2305
+ userMessage: message,
2306
+ responseMessages: []
2307
+ };
2308
+ turns.push(currentTurn);
2309
+ return;
2310
+ }
2311
+ if (!currentTurn) {
2312
+ currentTurn = {
2313
+ id: `assistant-turn-${message.id}`,
2314
+ responseMessages: [message]
2315
+ };
2316
+ turns.push(currentTurn);
2317
+ return;
2318
+ }
2319
+ currentTurn.responseMessages.push(message);
2320
+ });
2321
+ if (!streamingMessage) {
2322
+ return turns;
2323
+ }
2324
+ const lastTurn = turns[turns.length - 1];
2325
+ if (lastTurn) {
2326
+ return [
2327
+ ...turns.slice(0, -1),
2328
+ {
2329
+ ...lastTurn,
2330
+ responseMessages: [...lastTurn.responseMessages, streamingMessage]
2331
+ }
2332
+ ];
2333
+ }
2334
+ return [
2335
+ {
2336
+ id: `assistant-turn-${streamingMessage.id}`,
2337
+ responseMessages: [streamingMessage]
2338
+ }
2339
+ ];
2340
+ };
2316
2341
  var ChatThreadView = ({
2317
2342
  activeSessionMode = DEFAULT_CHAT_AGENT_MODE,
2318
2343
  historyMessages,
@@ -2324,45 +2349,56 @@ var ChatThreadView = ({
2324
2349
  onQuestionnaireSubmit,
2325
2350
  renderMessageBlock
2326
2351
  }) => {
2327
- const containerRef = (0, import_react11.useRef)(null);
2328
- const latestUserMessageId = (0, import_react11.useMemo)(
2329
- () => findLatestUserMessageId(historyMessages),
2330
- [historyMessages]
2352
+ const containerRef = (0, import_react10.useRef)(null);
2353
+ const conversationTurns = (0, import_react10.useMemo)(
2354
+ () => groupConversationTurns(historyMessages, streamingMessage),
2355
+ [historyMessages, streamingMessage]
2331
2356
  );
2332
- const latestUserMessageRef = (0, import_react11.useRef)(null);
2333
- const pendingScrollUserMessageIdRef = (0, import_react11.useRef)(void 0);
2334
- const reservedSpaceFrameRef = (0, import_react11.useRef)(null);
2335
- const [latestUserMessageReservedSpace, setLatestUserMessageReservedSpace] = (0, import_react11.useState)({ messageId: void 0, value: 0 });
2336
- const reservedPaddingBottom = 24 + (latestUserMessageReservedSpace.messageId === latestUserMessageId ? latestUserMessageReservedSpace.value : 0);
2337
- const measureLatestUserMessageReservedSpace = (0, import_react11.useCallback)((messageId) => {
2357
+ const latestTurn = conversationTurns[conversationTurns.length - 1];
2358
+ const previousTurns = conversationTurns.slice(0, -1);
2359
+ const latestUserMessageId = latestTurn?.userMessage?.id;
2360
+ const latestUserMessageRef = (0, import_react10.useRef)(null);
2361
+ const reservedSpaceFrameRef = (0, import_react10.useRef)(null);
2362
+ const [latestTurnMinHeight, setLatestTurnMinHeight] = (0, import_react10.useState)(0);
2363
+ const measureLatestTurnMinHeight = (0, import_react10.useCallback)(() => {
2364
+ const container = containerRef.current;
2365
+ if (!container)
2366
+ return;
2367
+ const computedStyle = window.getComputedStyle(container);
2368
+ const paddingTop = Number.parseFloat(computedStyle.paddingTop || "0") || 0;
2369
+ const paddingBottom = Number.parseFloat(computedStyle.paddingBottom || "0") || 0;
2370
+ const nextMinHeight = Math.max(0, container.clientHeight - paddingTop - paddingBottom);
2371
+ setLatestTurnMinHeight((current) => current === nextMinHeight ? current : nextMinHeight);
2372
+ }, []);
2373
+ const scrollLatestUserMessageToTop = (0, import_react10.useCallback)(() => {
2338
2374
  const container = containerRef.current;
2339
2375
  const target = latestUserMessageRef.current;
2340
2376
  if (!container || !target)
2341
2377
  return;
2342
- const reservedHeight = calculateChatThreadScrollSpacerHeight({
2343
- containerClientHeight: container.clientHeight,
2344
- containerScrollHeight: container.scrollHeight,
2345
- targetOffsetTop: target.offsetTop
2346
- });
2347
- setLatestUserMessageReservedSpace((current) => {
2348
- const next = reservedHeight > 0 ? reservedHeight : 0;
2349
- if (current.messageId === messageId && current.value === next)
2350
- return current;
2351
- return { messageId, value: next };
2352
- });
2378
+ const containerRect = container.getBoundingClientRect();
2379
+ const targetRect = target.getBoundingClientRect();
2380
+ const nextScrollTop = Math.max(
2381
+ 0,
2382
+ container.scrollTop + (targetRect.top - containerRect.top) - CHAT_THREAD_SCROLL_TOP_GAP
2383
+ );
2384
+ if (typeof container.scrollTo === "function") {
2385
+ container.scrollTo({
2386
+ top: nextScrollTop,
2387
+ behavior: "auto"
2388
+ });
2389
+ return;
2390
+ }
2391
+ container.scrollTop = nextScrollTop;
2353
2392
  }, []);
2354
- (0, import_react11.useLayoutEffect)(() => {
2393
+ (0, import_react10.useLayoutEffect)(() => {
2355
2394
  if (reservedSpaceFrameRef.current !== null) {
2356
2395
  window.cancelAnimationFrame(reservedSpaceFrameRef.current);
2357
2396
  reservedSpaceFrameRef.current = null;
2358
2397
  }
2359
2398
  if (!latestUserMessageId) {
2360
- pendingScrollUserMessageIdRef.current = void 0;
2361
2399
  reservedSpaceFrameRef.current = window.requestAnimationFrame(() => {
2362
2400
  reservedSpaceFrameRef.current = null;
2363
- setLatestUserMessageReservedSpace(
2364
- (current) => current.messageId === void 0 && current.value === 0 ? current : { messageId: void 0, value: 0 }
2365
- );
2401
+ setLatestTurnMinHeight((current) => current === 0 ? current : 0);
2366
2402
  });
2367
2403
  return () => {
2368
2404
  if (reservedSpaceFrameRef.current !== null) {
@@ -2371,10 +2407,10 @@ var ChatThreadView = ({
2371
2407
  }
2372
2408
  };
2373
2409
  }
2374
- pendingScrollUserMessageIdRef.current = latestUserMessageId;
2375
2410
  reservedSpaceFrameRef.current = window.requestAnimationFrame(() => {
2376
2411
  reservedSpaceFrameRef.current = null;
2377
- measureLatestUserMessageReservedSpace(latestUserMessageId);
2412
+ measureLatestTurnMinHeight();
2413
+ scrollLatestUserMessageToTop();
2378
2414
  });
2379
2415
  return () => {
2380
2416
  if (reservedSpaceFrameRef.current !== null) {
@@ -2382,51 +2418,79 @@ var ChatThreadView = ({
2382
2418
  reservedSpaceFrameRef.current = null;
2383
2419
  }
2384
2420
  };
2385
- }, [latestUserMessageId, measureLatestUserMessageReservedSpace]);
2386
- (0, import_react11.useLayoutEffect)(() => {
2387
- if (!latestUserMessageId || pendingScrollUserMessageIdRef.current !== latestUserMessageId)
2421
+ }, [latestUserMessageId, measureLatestTurnMinHeight, scrollLatestUserMessageToTop]);
2422
+ (0, import_react10.useLayoutEffect)(() => {
2423
+ if (!latestUserMessageId)
2388
2424
  return;
2389
- if (latestUserMessageReservedSpace.messageId !== latestUserMessageId)
2390
- return;
2391
- latestUserMessageRef.current?.scrollIntoView({ block: "start", behavior: "smooth" });
2392
- pendingScrollUserMessageIdRef.current = void 0;
2393
- }, [latestUserMessageId, latestUserMessageReservedSpace]);
2394
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2395
- Container,
2396
- {
2397
- ref: containerRef,
2398
- "data-testid": "chat-thread",
2399
- style: { paddingBottom: `${reservedPaddingBottom}px` },
2400
- children: [
2401
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2402
- ChatThreadHistoryList,
2403
- {
2404
- mode: activeSessionMode,
2405
- historyMessages,
2406
- latestUserMessageId,
2407
- latestUserMessageRef,
2408
- onConfirmationSubmit,
2409
- onQuestionnaireSubmit,
2410
- renderMessageBlock
2411
- }
2412
- ),
2413
- streamingMessage ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(StreamingGroup, { "data-testid": "chat-thread-streaming", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(MessageSlot2, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2414
- ChatMessageItem,
2415
- {
2425
+ const handleResize = () => {
2426
+ measureLatestTurnMinHeight();
2427
+ scrollLatestUserMessageToTop();
2428
+ };
2429
+ const container = containerRef.current;
2430
+ let resizeObserver = null;
2431
+ if (container && typeof ResizeObserver !== "undefined") {
2432
+ resizeObserver = new ResizeObserver(() => {
2433
+ handleResize();
2434
+ });
2435
+ resizeObserver.observe(container);
2436
+ }
2437
+ window.addEventListener("resize", handleResize);
2438
+ return () => {
2439
+ resizeObserver?.disconnect();
2440
+ window.removeEventListener("resize", handleResize);
2441
+ };
2442
+ }, [latestUserMessageId, measureLatestTurnMinHeight, scrollLatestUserMessageToTop]);
2443
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Container, { ref: containerRef, "data-testid": "chat-thread", children: [
2444
+ previousTurns.map((turn) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(ConversationTurn, { "data-testid": "chat-thread-turn", children: [
2445
+ turn.userMessage ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MessageSlot, { children: renderChatMessage({
2446
+ message: turn.userMessage,
2447
+ mode: activeSessionMode,
2448
+ onConfirmationSubmit,
2449
+ onQuestionnaireSubmit,
2450
+ renderMessageBlock
2451
+ }) }) : null,
2452
+ turn.responseMessages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MessageSlot, { children: renderChatMessage({
2453
+ message,
2454
+ mode: activeSessionMode,
2455
+ onConfirmationSubmit,
2456
+ onQuestionnaireSubmit,
2457
+ renderMessageBlock
2458
+ }) }, message.id))
2459
+ ] }, turn.id)),
2460
+ latestTurn ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
2461
+ ConversationTurn,
2462
+ {
2463
+ "data-testid": "chat-thread-latest-turn",
2464
+ style: latestTurnMinHeight > 0 ? { minHeight: `${latestTurnMinHeight}px` } : void 0,
2465
+ children: [
2466
+ latestTurn.userMessage ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2467
+ MessageSlot,
2468
+ {
2469
+ ref: latestUserMessageRef,
2470
+ "data-testid": "chat-latest-user-anchor",
2471
+ style: { scrollMarginTop: `${CHAT_THREAD_SCROLL_TOP_GAP}px` },
2472
+ children: renderChatMessage({
2473
+ message: latestTurn.userMessage,
2474
+ mode: activeSessionMode,
2475
+ onConfirmationSubmit,
2476
+ onQuestionnaireSubmit,
2477
+ renderMessageBlock
2478
+ })
2479
+ }
2480
+ ) : null,
2481
+ latestTurn.responseMessages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MessageSlot, { children: renderChatMessage({
2482
+ message,
2416
2483
  mode: activeSessionMode,
2417
- message: streamingMessage,
2418
2484
  onConfirmationSubmit,
2419
2485
  onQuestionnaireSubmit,
2420
2486
  renderMessageBlock
2421
- }
2422
- ) }) }) : null,
2423
- error ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(ErrorState, { "data-testid": "chat-thread-error-state", children: [
2424
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ErrorText, { children: error }),
2425
- onRetry ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ErrorActions, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(RetryButton, { type: "button", "data-testid": "chat-thread-retry", onClick: onRetry, children: retryButtonLabel }) }) : null
2426
- ] }) : null
2427
- ]
2428
- }
2429
- );
2487
+ }) }, message.id)),
2488
+ error ? renderErrorState({ error, onRetry, retryButtonLabel }) : null
2489
+ ]
2490
+ }
2491
+ ) : null,
2492
+ !latestTurn && error ? renderErrorState({ error, onRetry, retryButtonLabel }) : null
2493
+ ] });
2430
2494
  };
2431
2495
  var EMPTY_MESSAGES = [];
2432
2496
  var ChatThread = () => {
@@ -2443,13 +2507,13 @@ var ChatThread = () => {
2443
2507
  const updateQA = useChatStore((s) => s.updateQuestionnaireAnswers);
2444
2508
  const clearSessionError = useChatStore((s) => s.clearSessionError);
2445
2509
  const { sendRef, retryRef, renderMessageBlock, labels } = useChatContext();
2446
- const handleRetry = (0, import_react11.useCallback)(() => {
2510
+ const handleRetry = (0, import_react10.useCallback)(() => {
2447
2511
  if (!activeSessionId)
2448
2512
  return;
2449
2513
  clearSessionError(activeSessionId);
2450
2514
  void retryRef.current();
2451
2515
  }, [activeSessionId, clearSessionError, retryRef]);
2452
- const handleQuestionnaireSubmit = (0, import_react11.useCallback)(
2516
+ const handleQuestionnaireSubmit = (0, import_react10.useCallback)(
2453
2517
  (submission) => {
2454
2518
  if (activeSessionId && submission.sourceMessageId) {
2455
2519
  updateQA(
@@ -2463,16 +2527,16 @@ var ChatThread = () => {
2463
2527
  },
2464
2528
  [activeSessionId, updateQA, sendRef]
2465
2529
  );
2466
- const handleConfirmationSubmit = (0, import_react11.useCallback)(
2530
+ const handleConfirmationSubmit = (0, import_react10.useCallback)(
2467
2531
  (submission) => {
2468
2532
  void sendRef.current(submission.content);
2469
2533
  },
2470
2534
  [sendRef]
2471
2535
  );
2472
2536
  if (!hasSessions || messages.length === 0 && !streamingMessage) {
2473
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ChatThreadEmptyState, {});
2537
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ChatThreadEmptyState, {});
2474
2538
  }
2475
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2539
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2476
2540
  ChatThreadView,
2477
2541
  {
2478
2542
  activeSessionMode,
@@ -2487,7 +2551,7 @@ var ChatThread = () => {
2487
2551
  }
2488
2552
  );
2489
2553
  };
2490
- var Container = import_styled10.default.div`
2554
+ var Container = import_styled9.default.div`
2491
2555
  display: flex;
2492
2556
  flex: 1;
2493
2557
  flex-direction: column;
@@ -2510,27 +2574,29 @@ var Container = import_styled10.default.div`
2510
2574
  background: transparent;
2511
2575
  }
2512
2576
  `;
2513
- var MessageSlot2 = import_styled10.default.div`
2577
+ var MessageSlot = import_styled9.default.div`
2514
2578
  display: flex;
2515
2579
  `;
2516
- var StreamingGroup = import_styled10.default.div`
2517
- display: contents;
2580
+ var ConversationTurn = import_styled9.default.div`
2581
+ display: flex;
2582
+ flex-direction: column;
2583
+ gap: 18px;
2518
2584
  `;
2519
- var ErrorText = import_styled10.default.div`
2585
+ var ErrorText = import_styled9.default.div`
2520
2586
  color: #ff7b72;
2521
2587
  font-size: 14px;
2522
2588
  `;
2523
- var ErrorState = import_styled10.default.div`
2589
+ var ErrorState = import_styled9.default.div`
2524
2590
  display: flex;
2525
2591
  flex-direction: column;
2526
2592
  align-items: flex-start;
2527
2593
  gap: 10px;
2528
2594
  `;
2529
- var ErrorActions = import_styled10.default.div`
2595
+ var ErrorActions = import_styled9.default.div`
2530
2596
  display: flex;
2531
2597
  align-items: center;
2532
2598
  `;
2533
- var RetryButton = import_styled10.default.button`
2599
+ var RetryButton = import_styled9.default.button`
2534
2600
  border: 1px solid rgba(255, 255, 255, 0.14);
2535
2601
  border-radius: 999px;
2536
2602
  background: rgba(255, 255, 255, 0.04);
@@ -2546,8 +2612,8 @@ var RetryButton = import_styled10.default.button`
2546
2612
  `;
2547
2613
 
2548
2614
  // src/components/chat-composer/index.tsx
2549
- var import_react15 = require("react");
2550
- var import_styled15 = __toESM(require("@emotion/styled"));
2615
+ var import_react14 = require("react");
2616
+ var import_styled14 = __toESM(require("@emotion/styled"));
2551
2617
 
2552
2618
  // src/components/chat-composer/lib/chat-composer.ts
2553
2619
  var DRAFT_CHAT_SESSION_ID_PREFIX = "draft-session-";
@@ -2658,10 +2724,10 @@ var resolveSendSession = ({
2658
2724
  };
2659
2725
 
2660
2726
  // src/components/chat-composer/hooks/use-chat-composer.ts
2661
- var import_react13 = require("react");
2727
+ var import_react12 = require("react");
2662
2728
 
2663
2729
  // src/components/chat-composer/hooks/use-composer-attachments.ts
2664
- var import_react12 = require("react");
2730
+ var import_react11 = require("react");
2665
2731
  var SUPPORTED_IMAGE_MIME_TYPES = /* @__PURE__ */ new Set(["image/png", "image/jpeg", "image/webp"]);
2666
2732
  var MAX_COMPOSER_ATTACHMENTS = 10;
2667
2733
  var createObjectUrl = (file) => typeof URL !== "undefined" && typeof URL.createObjectURL === "function" ? URL.createObjectURL(file) : "";
@@ -2675,12 +2741,12 @@ var releaseComposerAttachments = (attachments) => {
2675
2741
  attachments.forEach((attachment) => revokeObjectUrl(attachment.previewUrl));
2676
2742
  };
2677
2743
  var useComposerAttachments = () => {
2678
- const [attachments, setAttachments] = (0, import_react12.useState)([]);
2679
- const attachmentsRef = (0, import_react12.useRef)([]);
2680
- (0, import_react12.useEffect)(() => {
2744
+ const [attachments, setAttachments] = (0, import_react11.useState)([]);
2745
+ const attachmentsRef = (0, import_react11.useRef)([]);
2746
+ (0, import_react11.useEffect)(() => {
2681
2747
  attachmentsRef.current = attachments;
2682
2748
  }, [attachments]);
2683
- (0, import_react12.useEffect)(
2749
+ (0, import_react11.useEffect)(
2684
2750
  () => () => {
2685
2751
  releaseComposerAttachments(attachmentsRef.current);
2686
2752
  },
@@ -2793,10 +2859,10 @@ var useChatComposer = () => {
2793
2859
  const clearSessionError = useChatStore((s) => s.clearSessionError);
2794
2860
  const setPreferredMode = useChatStore((s) => s.setPreferredMode);
2795
2861
  const setSessionMode = useChatStore((s) => s.setSessionMode);
2796
- const [availableModels, setAvailableModels] = (0, import_react13.useState)([]);
2797
- const [isModelsLoading, setIsModelsLoading] = (0, import_react13.useState)(true);
2798
- const [isModelsError, setIsModelsError] = (0, import_react13.useState)(false);
2799
- const fetchModels = (0, import_react13.useCallback)(async () => {
2862
+ const [availableModels, setAvailableModels] = (0, import_react12.useState)([]);
2863
+ const [isModelsLoading, setIsModelsLoading] = (0, import_react12.useState)(true);
2864
+ const [isModelsError, setIsModelsError] = (0, import_react12.useState)(false);
2865
+ const fetchModels = (0, import_react12.useCallback)(async () => {
2800
2866
  setIsModelsLoading(true);
2801
2867
  setIsModelsError(false);
2802
2868
  try {
@@ -2808,31 +2874,31 @@ var useChatComposer = () => {
2808
2874
  setIsModelsLoading(false);
2809
2875
  }
2810
2876
  }, [transport]);
2811
- (0, import_react13.useEffect)(() => {
2877
+ (0, import_react12.useEffect)(() => {
2812
2878
  void fetchModels();
2813
2879
  }, [fetchModels]);
2814
2880
  const hasModels = availableModels.length > 0;
2815
- const [value, setValue] = (0, import_react13.useState)("");
2816
- const [selectedModel, setSelectedModel] = (0, import_react13.useState)("");
2817
- const [selectedMode, setSelectedModeLocal] = (0, import_react13.useState)(DEFAULT_CHAT_AGENT_MODE);
2818
- const [attachmentNotice, setAttachmentNotice] = (0, import_react13.useState)(null);
2881
+ const [value, setValue] = (0, import_react12.useState)("");
2882
+ const [selectedModel, setSelectedModel] = (0, import_react12.useState)("");
2883
+ const [selectedMode, setSelectedModeLocal] = (0, import_react12.useState)(DEFAULT_CHAT_AGENT_MODE);
2884
+ const [attachmentNotice, setAttachmentNotice] = (0, import_react12.useState)(null);
2819
2885
  const { attachments, appendFiles, removeAttachment, takeMessageAttachments } = useComposerAttachments();
2820
- const abortControllerRef = (0, import_react13.useRef)(null);
2821
- const stopRequestRef = (0, import_react13.useRef)(null);
2822
- const lastRequestRef = (0, import_react13.useRef)(null);
2823
- (0, import_react13.useEffect)(() => {
2886
+ const abortControllerRef = (0, import_react12.useRef)(null);
2887
+ const stopRequestRef = (0, import_react12.useRef)(null);
2888
+ const lastRequestRef = (0, import_react12.useRef)(null);
2889
+ (0, import_react12.useEffect)(() => {
2824
2890
  setSelectedModel(
2825
2891
  (current) => resolveSelectedChatModel({ currentModel: current, availableModels, isModelsLoading })
2826
2892
  );
2827
2893
  }, [availableModels, isModelsLoading]);
2828
- (0, import_react13.useEffect)(() => {
2894
+ (0, import_react12.useEffect)(() => {
2829
2895
  if (activeSession) {
2830
2896
  setSelectedModeLocal(activeSession.mode ?? DEFAULT_CHAT_AGENT_MODE);
2831
2897
  return;
2832
2898
  }
2833
2899
  setSelectedModeLocal(preferredMode ?? DEFAULT_CHAT_AGENT_MODE);
2834
2900
  }, [activeSession, preferredMode]);
2835
- (0, import_react13.useEffect)(() => {
2901
+ (0, import_react12.useEffect)(() => {
2836
2902
  if (!attachmentNotice)
2837
2903
  return;
2838
2904
  const timeoutId = window.setTimeout(
@@ -2851,7 +2917,7 @@ var useChatComposer = () => {
2851
2917
  stopRequestRef.current.timeoutId = null;
2852
2918
  }
2853
2919
  };
2854
- const clearStopRequest = (0, import_react13.useCallback)((sessionId) => {
2920
+ const clearStopRequest = (0, import_react12.useCallback)((sessionId) => {
2855
2921
  if (!stopRequestRef.current)
2856
2922
  return;
2857
2923
  if (sessionId && stopRequestRef.current.sessionId !== sessionId)
@@ -2859,7 +2925,7 @@ var useChatComposer = () => {
2859
2925
  clearStopTimeout(sessionId);
2860
2926
  stopRequestRef.current = null;
2861
2927
  }, []);
2862
- const finalizeStop = (0, import_react13.useCallback)(
2928
+ const finalizeStop = (0, import_react12.useCallback)(
2863
2929
  (sessionId) => {
2864
2930
  if (stopRequestRef.current?.sessionId === sessionId) {
2865
2931
  if (stopRequestRef.current.finalized)
@@ -2874,7 +2940,7 @@ var useChatComposer = () => {
2874
2940
  },
2875
2941
  [clearStopRequest, finalizeStoppedStreamingMessage]
2876
2942
  );
2877
- const runStream = (0, import_react13.useCallback)(
2943
+ const runStream = (0, import_react12.useCallback)(
2878
2944
  async ({
2879
2945
  localSessionId,
2880
2946
  sessionId,
@@ -2963,7 +3029,7 @@ var useChatComposer = () => {
2963
3029
  setSessionError
2964
3030
  ]
2965
3031
  );
2966
- const send = (0, import_react13.useCallback)(
3032
+ const send = (0, import_react12.useCallback)(
2967
3033
  async (contentOverride) => {
2968
3034
  const content = (contentOverride ?? value).trim();
2969
3035
  const hasText = Boolean(content);
@@ -3111,29 +3177,29 @@ var useChatComposer = () => {
3111
3177
  };
3112
3178
 
3113
3179
  // src/components/chat-composer/components/chat-composer-attachment-list.tsx
3114
- var import_react14 = require("react");
3115
- var import_styled11 = __toESM(require("@emotion/styled"));
3116
- var import_jsx_runtime12 = require("@emotion/react/jsx-runtime");
3180
+ var import_react13 = require("react");
3181
+ var import_styled10 = __toESM(require("@emotion/styled"));
3182
+ var import_jsx_runtime11 = require("@emotion/react/jsx-runtime");
3117
3183
  var ChatComposerAttachmentList = ({
3118
3184
  attachments,
3119
3185
  onRemoveAttachment
3120
3186
  }) => {
3121
- const [activeImage, setActiveImage] = (0, import_react14.useState)(null);
3187
+ const [activeImage, setActiveImage] = (0, import_react13.useState)(null);
3122
3188
  if (!attachments.length) {
3123
3189
  return null;
3124
3190
  }
3125
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
3126
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(AttachmentList, { "data-testid": "chat-composer-attachment-list", children: attachments.map((attachment) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(AttachmentCard, { children: [
3127
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3191
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
3192
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(AttachmentList, { "data-testid": "chat-composer-attachment-list", children: attachments.map((attachment) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(AttachmentCard, { children: [
3193
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3128
3194
  AttachmentPreviewButton,
3129
3195
  {
3130
3196
  type: "button",
3131
3197
  "aria-label": `${attachment.name} preview`,
3132
3198
  onClick: () => setActiveImage(attachment),
3133
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(AttachmentThumb, { src: attachment.previewUrl, alt: attachment.name })
3199
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(AttachmentThumb, { src: attachment.previewUrl, alt: attachment.name })
3134
3200
  }
3135
3201
  ),
3136
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3202
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3137
3203
  AttachmentRemoveButton,
3138
3204
  {
3139
3205
  type: "button",
@@ -3142,11 +3208,11 @@ var ChatComposerAttachmentList = ({
3142
3208
  event.stopPropagation();
3143
3209
  onRemoveAttachment(attachment.id);
3144
3210
  },
3145
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CloseGlyph, { "aria-hidden": "true" })
3211
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CloseGlyph, { "aria-hidden": "true" })
3146
3212
  }
3147
3213
  )
3148
3214
  ] }, attachment.id)) }),
3149
- activeImage ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3215
+ activeImage ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3150
3216
  ImageViewer,
3151
3217
  {
3152
3218
  src: activeImage.previewUrl,
@@ -3156,7 +3222,7 @@ var ChatComposerAttachmentList = ({
3156
3222
  ) : null
3157
3223
  ] });
3158
3224
  };
3159
- var AttachmentList = import_styled11.default.div`
3225
+ var AttachmentList = import_styled10.default.div`
3160
3226
  display: flex;
3161
3227
  flex-wrap: wrap;
3162
3228
  gap: 10px;
@@ -3178,7 +3244,7 @@ var AttachmentList = import_styled11.default.div`
3178
3244
  background: transparent;
3179
3245
  }
3180
3246
  `;
3181
- var AttachmentCard = import_styled11.default.div`
3247
+ var AttachmentCard = import_styled10.default.div`
3182
3248
  position: relative;
3183
3249
  width: 108px;
3184
3250
  height: 72px;
@@ -3187,7 +3253,7 @@ var AttachmentCard = import_styled11.default.div`
3187
3253
  border: 1px solid rgba(255, 255, 255, 0.12);
3188
3254
  background: rgba(255, 255, 255, 0.04);
3189
3255
  `;
3190
- var AttachmentPreviewButton = import_styled11.default.button`
3256
+ var AttachmentPreviewButton = import_styled10.default.button`
3191
3257
  width: 100%;
3192
3258
  height: 100%;
3193
3259
  padding: 0;
@@ -3195,13 +3261,13 @@ var AttachmentPreviewButton = import_styled11.default.button`
3195
3261
  background: transparent;
3196
3262
  cursor: zoom-in;
3197
3263
  `;
3198
- var AttachmentThumb = import_styled11.default.img`
3264
+ var AttachmentThumb = import_styled10.default.img`
3199
3265
  width: 100%;
3200
3266
  height: 100%;
3201
3267
  object-fit: cover;
3202
3268
  display: block;
3203
3269
  `;
3204
- var AttachmentRemoveButton = import_styled11.default.button`
3270
+ var AttachmentRemoveButton = import_styled10.default.button`
3205
3271
  position: absolute;
3206
3272
  top: 6px;
3207
3273
  right: 6px;
@@ -3239,7 +3305,7 @@ var AttachmentRemoveButton = import_styled11.default.button`
3239
3305
  background: rgba(30, 30, 35, 0.98);
3240
3306
  }
3241
3307
  `;
3242
- var CloseGlyph = import_styled11.default.span`
3308
+ var CloseGlyph = import_styled10.default.span`
3243
3309
  position: relative;
3244
3310
  width: 11px;
3245
3311
  height: 11px;
@@ -3268,9 +3334,9 @@ var CloseGlyph = import_styled11.default.span`
3268
3334
  `;
3269
3335
 
3270
3336
  // src/components/chat-composer/components/chat-model-control.tsx
3271
- var import_styled12 = __toESM(require("@emotion/styled"));
3337
+ var import_styled11 = __toESM(require("@emotion/styled"));
3272
3338
  var import_compass_ui = require("@xinghunm/compass-ui");
3273
- var import_jsx_runtime13 = require("@emotion/react/jsx-runtime");
3339
+ var import_jsx_runtime12 = require("@emotion/react/jsx-runtime");
3274
3340
  var ChatModelControl = ({
3275
3341
  selectedModel,
3276
3342
  availableModels,
@@ -3281,7 +3347,7 @@ var ChatModelControl = ({
3281
3347
  onReloadModels
3282
3348
  }) => {
3283
3349
  if (isModelsError) {
3284
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
3350
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
3285
3351
  ModelReloadButton,
3286
3352
  {
3287
3353
  type: "button",
@@ -3289,8 +3355,8 @@ var ChatModelControl = ({
3289
3355
  "aria-label": "Reload",
3290
3356
  onClick: onReloadModels,
3291
3357
  children: [
3292
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Failed to load models" }),
3293
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
3358
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: "Failed to load models" }),
3359
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
3294
3360
  ReloadIcon,
3295
3361
  {
3296
3362
  "data-testid": "chat-model-reload-icon",
@@ -3301,8 +3367,8 @@ var ChatModelControl = ({
3301
3367
  fill: "currentColor",
3302
3368
  xmlns: "http://www.w3.org/2000/svg",
3303
3369
  children: [
3304
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M895.469672 511.745197c0-146.498562-82.099856-273.805016-202.788589-338.470805l22.072715-46.630017c-4.50664-12.609179-18.382673-19.176758-30.991852-14.670118l-92.436272 33.040511c-12.609179 4.50664-19.176758 18.382673-14.670118 30.991852l33.040511 92.436272c4.50664 12.609179 18.382673 19.176758 30.991852 14.670118l24.581861-51.92972c99.069343 54.335513 166.240185 159.596881 166.240185 280.561907 0 165.56685-125.817544 301.747415-287.057855 318.14692l0 0.022513c-17.730826 0-32.105209 14.374382-32.105209 32.105209 0 17.730826 14.374382 32.105209 32.105209 32.105209 2.098801 0 4.149507-0.207731 6.135744-0.592494C744.270041 874.039593 895.469672 710.564381 895.469672 511.745197z" }),
3305
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M480.616222 129.23948c-0.041956 0-0.082888 0.00307-0.124843 0.00307l0-0.00307c-0.01535 0.001023-0.031722 0.00307-0.047072 0.004093-1.892093 0.010233-3.744277 0.189312-5.545296 0.5137-194.674794 18.529005-346.957083 182.459588-346.957083 381.987924 0 147.431817 83.146699 275.42798 205.097168 339.700819l-24.814152 52.419883c4.50664 12.609179 18.382673 19.176758 30.991852 14.670118l92.436272-33.040511c12.609179-4.50664 19.176758-18.382673 14.670118-30.991852l-33.040511-92.436272c-4.50664-12.609179-18.382673-19.176758-30.991852-14.670118l-21.853727 46.167482c-100.326986-53.964052-168.535461-159.920246-168.535461-281.81955 0-166.089759 126.616746-302.591643 288.588721-318.284043l0-0.014326c0.041956 0 0.082888 0.00307 0.124843 0.00307 17.730826 0 32.105209-14.374382 32.105209-32.105209C512.721431 143.613862 498.347049 129.23948 480.616222 129.23948z" })
3370
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M895.469672 511.745197c0-146.498562-82.099856-273.805016-202.788589-338.470805l22.072715-46.630017c-4.50664-12.609179-18.382673-19.176758-30.991852-14.670118l-92.436272 33.040511c-12.609179 4.50664-19.176758 18.382673-14.670118 30.991852l33.040511 92.436272c4.50664 12.609179 18.382673 19.176758 30.991852 14.670118l24.581861-51.92972c99.069343 54.335513 166.240185 159.596881 166.240185 280.561907 0 165.56685-125.817544 301.747415-287.057855 318.14692l0 0.022513c-17.730826 0-32.105209 14.374382-32.105209 32.105209 0 17.730826 14.374382 32.105209 32.105209 32.105209 2.098801 0 4.149507-0.207731 6.135744-0.592494C744.270041 874.039593 895.469672 710.564381 895.469672 511.745197z" }),
3371
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M480.616222 129.23948c-0.041956 0-0.082888 0.00307-0.124843 0.00307l0-0.00307c-0.01535 0.001023-0.031722 0.00307-0.047072 0.004093-1.892093 0.010233-3.744277 0.189312-5.545296 0.5137-194.674794 18.529005-346.957083 182.459588-346.957083 381.987924 0 147.431817 83.146699 275.42798 205.097168 339.700819l-24.814152 52.419883c4.50664 12.609179 18.382673 19.176758 30.991852 14.670118l92.436272-33.040511c12.609179-4.50664 19.176758-18.382673 14.670118-30.991852l-33.040511-92.436272c-4.50664-12.609179-18.382673-19.176758-30.991852-14.670118l-21.853727 46.167482c-100.326986-53.964052-168.535461-159.920246-168.535461-281.81955 0-166.089759 126.616746-302.591643 288.588721-318.284043l0-0.014326c0.041956 0 0.082888 0.00307 0.124843 0.00307 17.730826 0 32.105209-14.374382 32.105209-32.105209C512.721431 143.613862 498.347049 129.23948 480.616222 129.23948z" })
3306
3372
  ]
3307
3373
  }
3308
3374
  )
@@ -3311,11 +3377,11 @@ var ChatModelControl = ({
3311
3377
  );
3312
3378
  }
3313
3379
  if (isModelsLoading) {
3314
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ModelBadge, { children: "Loading models..." });
3380
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ModelBadge, { children: "Loading models..." });
3315
3381
  }
3316
3382
  if (hasModels && selectedModel) {
3317
3383
  if (availableModels.length > 1) {
3318
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3384
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3319
3385
  ModelSelect,
3320
3386
  {
3321
3387
  "data-testid": "chat-model-select",
@@ -3329,11 +3395,11 @@ var ChatModelControl = ({
3329
3395
  }
3330
3396
  );
3331
3397
  }
3332
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ModelBadge, { children: selectedModel });
3398
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ModelBadge, { children: selectedModel });
3333
3399
  }
3334
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ModelBadge, { children: "No model available" });
3400
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ModelBadge, { children: "No model available" });
3335
3401
  };
3336
- var ModelBadge = import_styled12.default.span`
3402
+ var ModelBadge = import_styled11.default.span`
3337
3403
  border-radius: 999px;
3338
3404
  border: 1px solid var(--border-hover);
3339
3405
  padding: 5px 12px;
@@ -3342,7 +3408,7 @@ var ModelBadge = import_styled12.default.span`
3342
3408
  color: var(--text-secondary);
3343
3409
  line-height: 12px;
3344
3410
  `;
3345
- var ModelReloadButton = import_styled12.default.button`
3411
+ var ModelReloadButton = import_styled11.default.button`
3346
3412
  display: inline-flex;
3347
3413
  align-items: center;
3348
3414
  gap: 8px;
@@ -3367,10 +3433,10 @@ var ModelReloadButton = import_styled12.default.button`
3367
3433
  color: rgba(255, 255, 255, 0.88);
3368
3434
  }
3369
3435
  `;
3370
- var ReloadIcon = import_styled12.default.svg`
3436
+ var ReloadIcon = import_styled11.default.svg`
3371
3437
  flex-shrink: 0;
3372
3438
  `;
3373
- var ModelSelect = (0, import_styled12.default)(import_compass_ui.Select)`
3439
+ var ModelSelect = (0, import_styled11.default)(import_compass_ui.Select)`
3374
3440
  && {
3375
3441
  width: auto;
3376
3442
  min-width: 0;
@@ -3390,16 +3456,16 @@ var ModelSelect = (0, import_styled12.default)(import_compass_ui.Select)`
3390
3456
  `;
3391
3457
 
3392
3458
  // src/components/chat-composer/components/chat-mode-control.tsx
3393
- var import_styled13 = __toESM(require("@emotion/styled"));
3459
+ var import_styled12 = __toESM(require("@emotion/styled"));
3394
3460
  var import_compass_ui2 = require("@xinghunm/compass-ui");
3395
- var import_jsx_runtime14 = require("@emotion/react/jsx-runtime");
3461
+ var import_jsx_runtime13 = require("@emotion/react/jsx-runtime");
3396
3462
  var ChatModeControl = ({
3397
3463
  value,
3398
3464
  disabled = false,
3399
3465
  labels,
3400
3466
  onChange
3401
3467
  }) => {
3402
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3468
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3403
3469
  ModeSelect,
3404
3470
  {
3405
3471
  "data-testid": "chat-mode-select",
@@ -3414,7 +3480,7 @@ var ChatModeControl = ({
3414
3480
  }
3415
3481
  );
3416
3482
  };
3417
- var ModeSelect = (0, import_styled13.default)(import_compass_ui2.Select)`
3483
+ var ModeSelect = (0, import_styled12.default)(import_compass_ui2.Select)`
3418
3484
  && {
3419
3485
  flex: 0 1 auto;
3420
3486
  width: auto;
@@ -3435,10 +3501,10 @@ var ModeSelect = (0, import_styled13.default)(import_compass_ui2.Select)`
3435
3501
  `;
3436
3502
 
3437
3503
  // src/components/chat-composer/components/chat-send-actions.tsx
3438
- var import_styled14 = __toESM(require("@emotion/styled"));
3504
+ var import_styled13 = __toESM(require("@emotion/styled"));
3439
3505
  var import_compass_ui3 = require("@xinghunm/compass-ui");
3440
- var import_jsx_runtime15 = require("@emotion/react/jsx-runtime");
3441
- var ArrowUpIcon = () => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3506
+ var import_jsx_runtime14 = require("@emotion/react/jsx-runtime");
3507
+ var ArrowUpIcon = () => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3442
3508
  "svg",
3443
3509
  {
3444
3510
  "aria-hidden": "true",
@@ -3447,7 +3513,7 @@ var ArrowUpIcon = () => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3447
3513
  viewBox: "0 0 12 12",
3448
3514
  fill: "none",
3449
3515
  xmlns: "http://www.w3.org/2000/svg",
3450
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3516
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3451
3517
  "path",
3452
3518
  {
3453
3519
  d: "M6 10V2M6 2L2 6M6 2L10 6",
@@ -3465,7 +3531,7 @@ var ChatSendActions = ({
3465
3531
  isStopping,
3466
3532
  onStop,
3467
3533
  onSend
3468
- }) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, { children: isStreaming ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3534
+ }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_jsx_runtime14.Fragment, { children: isStreaming ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3469
3535
  StopButton,
3470
3536
  {
3471
3537
  type: "button",
@@ -3475,14 +3541,14 @@ var ChatSendActions = ({
3475
3541
  disabled: isStopping,
3476
3542
  shape: "circle",
3477
3543
  onClick: () => void onStop(),
3478
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(StopGlyph, { "aria-hidden": "true" })
3544
+ children: isStopping ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(StopSpinner, { "aria-hidden": "true", "data-testid": "chat-composer-stop-spinner" }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(StopGlyph, { "aria-hidden": "true", "data-testid": "chat-composer-stop-glyph" })
3479
3545
  }
3480
- ) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3546
+ ) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3481
3547
  PrimaryButton,
3482
3548
  {
3483
3549
  $canSend: canSend,
3484
3550
  type: "button",
3485
- icon: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ArrowUpIcon, {}),
3551
+ icon: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ArrowUpIcon, {}),
3486
3552
  "aria-label": "Send",
3487
3553
  "data-testid": "chat-composer-send",
3488
3554
  disabled: !canSend,
@@ -3490,7 +3556,7 @@ var ChatSendActions = ({
3490
3556
  onClick: () => void onSend()
3491
3557
  }
3492
3558
  ) });
3493
- var PrimaryButton = (0, import_styled14.default)(import_compass_ui3.Button)`
3559
+ var PrimaryButton = (0, import_styled13.default)(import_compass_ui3.Button)`
3494
3560
  && {
3495
3561
  min-width: 24px;
3496
3562
  width: 24px;
@@ -3516,7 +3582,7 @@ var PrimaryButton = (0, import_styled14.default)(import_compass_ui3.Button)`
3516
3582
  }
3517
3583
  }
3518
3584
  `;
3519
- var StopButton = (0, import_styled14.default)(import_compass_ui3.Button)`
3585
+ var StopButton = (0, import_styled13.default)(import_compass_ui3.Button)`
3520
3586
  && {
3521
3587
  min-width: 24px;
3522
3588
  width: 24px;
@@ -3544,17 +3610,35 @@ var StopButton = (0, import_styled14.default)(import_compass_ui3.Button)`
3544
3610
  }
3545
3611
  }
3546
3612
  `;
3547
- var StopGlyph = import_styled14.default.span`
3613
+ var StopGlyph = import_styled13.default.span`
3548
3614
  width: 8px;
3549
3615
  height: 8px;
3550
3616
  border-radius: 2px;
3551
3617
  background: #1b1b1b;
3552
3618
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
3553
3619
  `;
3620
+ var StopSpinner = import_styled13.default.span`
3621
+ width: 10px;
3622
+ height: 10px;
3623
+ border-radius: 999px;
3624
+ border: 1.5px solid rgba(27, 27, 27, 0.2);
3625
+ border-top-color: #1b1b1b;
3626
+ animation: chat-composer-stop-spin 0.7s linear infinite;
3627
+
3628
+ @keyframes chat-composer-stop-spin {
3629
+ from {
3630
+ transform: rotate(0deg);
3631
+ }
3632
+
3633
+ to {
3634
+ transform: rotate(360deg);
3635
+ }
3636
+ }
3637
+ `;
3554
3638
 
3555
3639
  // src/components/chat-composer/index.tsx
3556
- var import_jsx_runtime16 = require("@emotion/react/jsx-runtime");
3557
- var PlusIcon = () => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3640
+ var import_jsx_runtime15 = require("@emotion/react/jsx-runtime");
3641
+ var PlusIcon = () => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3558
3642
  "svg",
3559
3643
  {
3560
3644
  "aria-hidden": "true",
@@ -3563,7 +3647,7 @@ var PlusIcon = () => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3563
3647
  viewBox: "0 0 16 16",
3564
3648
  fill: "none",
3565
3649
  xmlns: "http://www.w3.org/2000/svg",
3566
- children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M8 3v10M3 8h10", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round" })
3650
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M8 3v10M3 8h10", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round" })
3567
3651
  }
3568
3652
  );
3569
3653
  var ChatComposerView = ({
@@ -3592,7 +3676,7 @@ var ChatComposerView = ({
3592
3676
  onStop,
3593
3677
  onSend
3594
3678
  }) => {
3595
- const imageInputRef = (0, import_react15.useRef)(null);
3679
+ const imageInputRef = (0, import_react14.useRef)(null);
3596
3680
  const canSend = canSendChatMessage({
3597
3681
  value,
3598
3682
  attachmentCount: attachments.length,
@@ -3623,8 +3707,8 @@ var ChatComposerView = ({
3623
3707
  event.preventDefault();
3624
3708
  onPasteImages(imageFiles);
3625
3709
  };
3626
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Container2, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Surface, { "data-testid": "chat-composer-surface", children: [
3627
- enableImageAttachments ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3710
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Container2, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Surface, { "data-testid": "chat-composer-surface", children: [
3711
+ enableImageAttachments ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3628
3712
  "input",
3629
3713
  {
3630
3714
  ref: imageInputRef,
@@ -3636,15 +3720,15 @@ var ChatComposerView = ({
3636
3720
  onChange: handlePickImages
3637
3721
  }
3638
3722
  ) : null,
3639
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3723
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3640
3724
  ChatComposerAttachmentList,
3641
3725
  {
3642
3726
  attachments,
3643
3727
  onRemoveAttachment
3644
3728
  }
3645
3729
  ),
3646
- attachmentNotice === "limit_reached" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AttachmentNotice, { "data-testid": "chat-composer-attachment-notice", children: attachmentLimitNotice }) : null,
3647
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3730
+ attachmentNotice === "limit_reached" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AttachmentNotice, { "data-testid": "chat-composer-attachment-notice", children: attachmentLimitNotice }) : null,
3731
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3648
3732
  Input,
3649
3733
  {
3650
3734
  "data-testid": "chat-composer-input",
@@ -3655,18 +3739,18 @@ var ChatComposerView = ({
3655
3739
  placeholder
3656
3740
  }
3657
3741
  ),
3658
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Footer, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Actions2, { "data-testid": "chat-composer-actions", children: [
3659
- enableImageAttachments ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3742
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Footer, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Actions2, { "data-testid": "chat-composer-actions", children: [
3743
+ enableImageAttachments ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3660
3744
  AttachButton,
3661
3745
  {
3662
3746
  type: "button",
3663
3747
  "data-testid": "chat-composer-attach-image",
3664
3748
  "aria-label": "Attach image",
3665
3749
  onClick: () => imageInputRef.current?.click(),
3666
- children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(PlusIcon, {})
3750
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(PlusIcon, {})
3667
3751
  }
3668
3752
  ) : null,
3669
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3753
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3670
3754
  ChatModeControl,
3671
3755
  {
3672
3756
  value: selectedMode,
@@ -3675,7 +3759,7 @@ var ChatComposerView = ({
3675
3759
  onChange: onSelectedModeChange
3676
3760
  }
3677
3761
  ),
3678
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3762
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3679
3763
  ChatModelControl,
3680
3764
  {
3681
3765
  selectedModel,
@@ -3687,7 +3771,7 @@ var ChatComposerView = ({
3687
3771
  onReloadModels
3688
3772
  }
3689
3773
  ),
3690
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3774
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3691
3775
  ChatSendActions,
3692
3776
  {
3693
3777
  canSend,
@@ -3704,7 +3788,7 @@ var ChatComposer = () => {
3704
3788
  const { labels, sendRef, retryRef, enableImageAttachments } = useChatContext();
3705
3789
  const { state, actions } = useChatComposer();
3706
3790
  const { send, retry } = actions;
3707
- (0, import_react15.useEffect)(() => {
3791
+ (0, import_react14.useEffect)(() => {
3708
3792
  sendRef.current = send;
3709
3793
  retryRef.current = async () => {
3710
3794
  retry();
@@ -3715,7 +3799,7 @@ var ChatComposer = () => {
3715
3799
  plan: labels.modeLabelPlan,
3716
3800
  agent: labels.modeLabelAgent
3717
3801
  };
3718
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3802
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3719
3803
  ChatComposerView,
3720
3804
  {
3721
3805
  value: state.value,
@@ -3745,10 +3829,10 @@ var ChatComposer = () => {
3745
3829
  }
3746
3830
  );
3747
3831
  };
3748
- var Container2 = import_styled15.default.div`
3832
+ var Container2 = import_styled14.default.div`
3749
3833
  padding: 0 16px 16px;
3750
3834
  `;
3751
- var Surface = import_styled15.default.div`
3835
+ var Surface = import_styled14.default.div`
3752
3836
  background: var(--border-color);
3753
3837
  border-radius: 20px;
3754
3838
  border: 1px solid var(--border-hover);
@@ -3757,7 +3841,7 @@ var Surface = import_styled15.default.div`
3757
3841
  0 12px 36px rgba(0, 0, 0, 0.3);
3758
3842
  backdrop-filter: blur(10px);
3759
3843
  `;
3760
- var AttachmentNotice = import_styled15.default.div`
3844
+ var AttachmentNotice = import_styled14.default.div`
3761
3845
  margin: 10px 12px 0;
3762
3846
  padding: 8px 10px;
3763
3847
  border-radius: 10px;
@@ -3767,7 +3851,7 @@ var AttachmentNotice = import_styled15.default.div`
3767
3851
  font-size: 12px;
3768
3852
  line-height: 1.4;
3769
3853
  `;
3770
- var Input = import_styled15.default.textarea`
3854
+ var Input = import_styled14.default.textarea`
3771
3855
  width: 100%;
3772
3856
  min-height: 96px;
3773
3857
  resize: none;
@@ -3789,14 +3873,14 @@ var Input = import_styled15.default.textarea`
3789
3873
  display: none;
3790
3874
  }
3791
3875
  `;
3792
- var Footer = import_styled15.default.div`
3876
+ var Footer = import_styled14.default.div`
3793
3877
  display: flex;
3794
3878
  align-items: flex-end;
3795
3879
  justify-content: stretch;
3796
3880
  gap: 16px;
3797
3881
  padding: 0 14px 14px;
3798
3882
  `;
3799
- var Actions2 = import_styled15.default.div`
3883
+ var Actions2 = import_styled14.default.div`
3800
3884
  display: flex;
3801
3885
  align-items: center;
3802
3886
  flex-wrap: wrap;
@@ -3805,7 +3889,7 @@ var Actions2 = import_styled15.default.div`
3805
3889
  justify-content: flex-end;
3806
3890
  gap: 8px;
3807
3891
  `;
3808
- var AttachButton = import_styled15.default.button`
3892
+ var AttachButton = import_styled14.default.button`
3809
3893
  width: 28px;
3810
3894
  height: 28px;
3811
3895
  display: grid;
@@ -3822,42 +3906,42 @@ var AttachButton = import_styled15.default.button`
3822
3906
  `;
3823
3907
 
3824
3908
  // src/components/chat-conversation-list/index.tsx
3825
- var import_styled17 = __toESM(require("@emotion/styled"));
3909
+ var import_styled16 = __toESM(require("@emotion/styled"));
3826
3910
 
3827
3911
  // src/components/chat-conversation-list/components/chat-session-item.tsx
3828
- var import_react16 = require("react");
3829
- var import_styled16 = __toESM(require("@emotion/styled"));
3830
- var import_jsx_runtime17 = require("@emotion/react/jsx-runtime");
3831
- var ChatSessionItem = (0, import_react16.memo)(
3912
+ var import_react15 = require("react");
3913
+ var import_styled15 = __toESM(require("@emotion/styled"));
3914
+ var import_jsx_runtime16 = require("@emotion/react/jsx-runtime");
3915
+ var ChatSessionItem = (0, import_react15.memo)(
3832
3916
  ({ session, isActive, modeLabel, onClick }) => {
3833
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3917
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3834
3918
  SessionButton,
3835
3919
  {
3836
3920
  type: "button",
3837
3921
  "data-active": isActive,
3838
3922
  onClick: () => onClick(session.sessionId),
3839
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(SessionMeta, { children: [
3840
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SessionTitle, { children: session.title }),
3841
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ModeBadge, { children: modeLabel })
3923
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(SessionMeta, { children: [
3924
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SessionTitle, { children: session.title }),
3925
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ModeBadge, { children: modeLabel })
3842
3926
  ] })
3843
3927
  }
3844
3928
  );
3845
3929
  }
3846
3930
  );
3847
3931
  ChatSessionItem.displayName = "ChatSessionItem";
3848
- var SessionMeta = import_styled16.default.div`
3932
+ var SessionMeta = import_styled15.default.div`
3849
3933
  display: flex;
3850
3934
  align-items: center;
3851
3935
  justify-content: space-between;
3852
3936
  gap: 8px;
3853
3937
  `;
3854
- var SessionTitle = import_styled16.default.span`
3938
+ var SessionTitle = import_styled15.default.span`
3855
3939
  min-width: 0;
3856
3940
  overflow: hidden;
3857
3941
  text-overflow: ellipsis;
3858
3942
  white-space: nowrap;
3859
3943
  `;
3860
- var SessionButton = import_styled16.default.button`
3944
+ var SessionButton = import_styled15.default.button`
3861
3945
  border: 1px solid transparent;
3862
3946
  border-radius: 12px;
3863
3947
  padding: 12px;
@@ -3871,7 +3955,7 @@ var SessionButton = import_styled16.default.button`
3871
3955
  background: rgba(255, 255, 255, 0.08);
3872
3956
  }
3873
3957
  `;
3874
- var ModeBadge = import_styled16.default.span`
3958
+ var ModeBadge = import_styled15.default.span`
3875
3959
  flex-shrink: 0;
3876
3960
  border-radius: 999px;
3877
3961
  border: 1px solid rgba(255, 255, 255, 0.1);
@@ -3883,7 +3967,7 @@ var ModeBadge = import_styled16.default.span`
3883
3967
  `;
3884
3968
 
3885
3969
  // src/components/chat-conversation-list/index.tsx
3886
- var import_jsx_runtime18 = require("@emotion/react/jsx-runtime");
3970
+ var import_jsx_runtime17 = require("@emotion/react/jsx-runtime");
3887
3971
  var ChatConversationList = () => {
3888
3972
  const { labels } = useChatContext();
3889
3973
  const sessions = useChatStore((s) => s.sessions);
@@ -3906,12 +3990,12 @@ var ChatConversationList = () => {
3906
3990
  });
3907
3991
  createSession(session);
3908
3992
  };
3909
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Container3, { children: [
3910
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Toolbar, { children: [
3911
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Title4, { children: "Sessions" }),
3912
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(CreateButton, { type: "button", "data-testid": "chat-create-session", onClick: handleCreateSession, children: labels.newChat })
3993
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Container3, { children: [
3994
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Toolbar, { children: [
3995
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Title4, { children: "Sessions" }),
3996
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(CreateButton, { type: "button", "data-testid": "chat-create-session", onClick: handleCreateSession, children: labels.newChat })
3913
3997
  ] }),
3914
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(List2, { "data-testid": "chat-session-list", children: sessions.map((session) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3998
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(List2, { "data-testid": "chat-session-list", children: sessions.map((session) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3915
3999
  ChatSessionItem,
3916
4000
  {
3917
4001
  session,
@@ -3923,7 +4007,7 @@ var ChatConversationList = () => {
3923
4007
  )) })
3924
4008
  ] });
3925
4009
  };
3926
- var Container3 = import_styled17.default.aside`
4010
+ var Container3 = import_styled16.default.aside`
3927
4011
  width: 280px;
3928
4012
  min-width: 280px;
3929
4013
  border-right: 1px solid var(--border-default, rgba(255, 255, 255, 0.08));
@@ -3931,18 +4015,18 @@ var Container3 = import_styled17.default.aside`
3931
4015
  flex-direction: column;
3932
4016
  background: rgba(255, 255, 255, 0.02);
3933
4017
  `;
3934
- var Toolbar = import_styled17.default.div`
4018
+ var Toolbar = import_styled16.default.div`
3935
4019
  padding: 20px 16px 12px;
3936
4020
  display: flex;
3937
4021
  flex-direction: column;
3938
4022
  gap: 12px;
3939
4023
  `;
3940
- var Title4 = import_styled17.default.h2`
4024
+ var Title4 = import_styled16.default.h2`
3941
4025
  margin: 0;
3942
4026
  font-size: 14px;
3943
4027
  color: var(--text-secondary);
3944
4028
  `;
3945
- var CreateButton = import_styled17.default.button`
4029
+ var CreateButton = import_styled16.default.button`
3946
4030
  border: none;
3947
4031
  border-radius: 12px;
3948
4032
  padding: 12px 14px;
@@ -3951,7 +4035,7 @@ var CreateButton = import_styled17.default.button`
3951
4035
  text-align: left;
3952
4036
  cursor: pointer;
3953
4037
  `;
3954
- var List2 = import_styled17.default.div`
4038
+ var List2 = import_styled16.default.div`
3955
4039
  padding: 0 12px 16px;
3956
4040
  display: flex;
3957
4041
  flex-direction: column;
@@ -3960,8 +4044,8 @@ var List2 = import_styled17.default.div`
3960
4044
  `;
3961
4045
 
3962
4046
  // src/components/ai-chat/index.tsx
3963
- var import_jsx_runtime19 = require("@emotion/react/jsx-runtime");
3964
- var AiChat = ({ showConversationList = false, ...providerProps }) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4047
+ var import_jsx_runtime18 = require("@emotion/react/jsx-runtime");
4048
+ var AiChat = ({ showConversationList = false, ...providerProps }) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3965
4049
  import_compass_ui4.ConfigProvider,
3966
4050
  {
3967
4051
  theme: {
@@ -3996,23 +4080,23 @@ var AiChat = ({ showConversationList = false, ...providerProps }) => /* @__PURE_
3996
4080
  }
3997
4081
  }
3998
4082
  },
3999
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(AiChatProvider, { ...providerProps, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Root, { "data-testid": "ai-chat", children: [
4000
- showConversationList ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ChatConversationList, {}) : null,
4001
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Workspace, { children: [
4002
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ChatThread, {}),
4003
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ChatComposer, {})
4083
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AiChatProvider, { ...providerProps, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Root, { "data-testid": "ai-chat", children: [
4084
+ showConversationList ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ChatConversationList, {}) : null,
4085
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Workspace, { children: [
4086
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ChatThread, {}),
4087
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ChatComposer, {})
4004
4088
  ] })
4005
4089
  ] }) })
4006
4090
  }
4007
4091
  );
4008
- var Root = import_styled18.default.div`
4092
+ var Root = import_styled17.default.div`
4009
4093
  display: flex;
4010
4094
  width: 100%;
4011
4095
  height: 100%;
4012
4096
  min-height: 0;
4013
4097
  overflow: hidden;
4014
4098
  `;
4015
- var Workspace = import_styled18.default.section`
4099
+ var Workspace = import_styled17.default.section`
4016
4100
  flex: 1;
4017
4101
  display: flex;
4018
4102
  flex-direction: column;