@yushaw/sanqian-chat 0.2.37 → 0.2.40

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.
@@ -107,6 +107,12 @@ var findLastBlock = (blocks, predicate) => {
107
107
  }
108
108
  return void 0;
109
109
  };
110
+ var CHAT_CAPABILITIES = {
111
+ conversationSwitch: {
112
+ supportsCancelActiveStream: true,
113
+ supportsDetachContext: true
114
+ }
115
+ };
110
116
  function useChat(options) {
111
117
  const { adapter, onError, onConversationChange } = options;
112
118
  const [messages, setMessages] = (0, import_react.useState)([]);
@@ -127,6 +133,7 @@ function useChat(options) {
127
133
  const pendingCancelRef = (0, import_react.useRef)(false);
128
134
  const pendingCancelFnRef = (0, import_react.useRef)(null);
129
135
  const suppressStreamRef = (0, import_react.useRef)(false);
136
+ const activeStreamContextRef = (0, import_react.useRef)(null);
130
137
  const currentBlocksRef = (0, import_react.useRef)([]);
131
138
  const currentTextBlockIndexRef = (0, import_react.useRef)(-1);
132
139
  const needsContentClearRef = (0, import_react.useRef)(false);
@@ -214,8 +221,43 @@ function useChat(options) {
214
221
  pendingCancelRef.current = false;
215
222
  pendingCancelFnRef.current = null;
216
223
  }, []);
217
- const handleStreamEvent = (0, import_react.useCallback)((event, assistantMessageId) => {
224
+ const detachActiveStream = (0, import_react.useCallback)((detachContext) => {
225
+ const context = activeStreamContextRef.current;
226
+ if (!context || context.detached) {
227
+ return;
228
+ }
229
+ context.detached = true;
230
+ context.detachContext = detachContext;
231
+ if (typewriterIntervalRef.current) {
232
+ clearTimeout(typewriterIntervalRef.current);
233
+ typewriterIntervalRef.current = null;
234
+ }
235
+ currentAssistantMessageIdRef.current = null;
236
+ resetStreamBuffers();
237
+ setIsStreaming(false);
238
+ setIsLoading(false);
239
+ setPendingInterrupt(null);
240
+ currentRunIdRef.current = null;
241
+ pendingInterruptStreamIdRef.current = null;
242
+ clearPendingCancel();
243
+ suppressStreamRef.current = false;
244
+ }, [clearPendingCancel, resetStreamBuffers]);
245
+ const handleStreamEvent = (0, import_react.useCallback)((event, streamContext) => {
218
246
  if (!isMountedRef.current) return;
247
+ const isActiveStream = activeStreamContextRef.current?.token === streamContext.token && !streamContext.detached;
248
+ if (!isActiveStream) {
249
+ if (event.type === "done" && event.conversationId && !streamContext.didReportConversationChange) {
250
+ streamContext.didReportConversationChange = true;
251
+ onConversationChange?.(event.conversationId, event.title, {
252
+ source: "background",
253
+ streamToken: streamContext.token,
254
+ detached: true,
255
+ detachContext: streamContext.detachContext
256
+ });
257
+ }
258
+ return;
259
+ }
260
+ const assistantMessageId = streamContext.assistantMessageId;
219
261
  currentAssistantMessageIdRef.current = assistantMessageId;
220
262
  if (suppressStreamRef.current && event.type !== "start" && event.type !== "cancelled" && event.type !== "done" && event.type !== "error") {
221
263
  return;
@@ -561,8 +603,13 @@ function useChat(options) {
561
603
  });
562
604
  resetStreamBuffers();
563
605
  if (event.conversationId) {
606
+ streamContext.didReportConversationChange = true;
564
607
  setConversationId(event.conversationId);
565
- onConversationChange?.(event.conversationId, event.title);
608
+ onConversationChange?.(event.conversationId, event.title, {
609
+ source: "active",
610
+ streamToken: streamContext.token,
611
+ detached: false
612
+ });
566
613
  }
567
614
  if (event.title) setConversationTitle(event.title);
568
615
  setIsStreaming(false);
@@ -571,6 +618,7 @@ function useChat(options) {
571
618
  pendingInterruptStreamIdRef.current = null;
572
619
  suppressStreamRef.current = false;
573
620
  clearPendingCancel();
621
+ activeStreamContextRef.current = null;
574
622
  break;
575
623
  }
576
624
  case "cancelled": {
@@ -608,6 +656,7 @@ function useChat(options) {
608
656
  pendingInterruptStreamIdRef.current = null;
609
657
  suppressStreamRef.current = false;
610
658
  clearPendingCancel();
659
+ activeStreamContextRef.current = null;
611
660
  break;
612
661
  }
613
662
  case "error": {
@@ -636,6 +685,7 @@ function useChat(options) {
636
685
  pendingInterruptStreamIdRef.current = null;
637
686
  suppressStreamRef.current = false;
638
687
  clearPendingCancel();
688
+ activeStreamContextRef.current = null;
639
689
  break;
640
690
  }
641
691
  case "interrupt": {
@@ -686,6 +736,13 @@ function useChat(options) {
686
736
  blocks: [],
687
737
  isComplete: false
688
738
  };
739
+ const streamContext = {
740
+ token: crypto.randomUUID(),
741
+ assistantMessageId: assistantMessage.id,
742
+ detached: false,
743
+ didReportConversationChange: false
744
+ };
745
+ activeStreamContextRef.current = streamContext;
689
746
  const shouldRenderUserMessage = trimmedContent.length > 0 || hasAttachedResources;
690
747
  setMessages(
691
748
  (prev) => shouldRenderUserMessage ? [...prev, userMessage, assistantMessage] : [...prev, assistantMessage]
@@ -708,7 +765,7 @@ function useChat(options) {
708
765
  const { cancel } = await adapter.chatStream(
709
766
  apiMessages,
710
767
  conversationIdRef.current ?? void 0,
711
- (event) => handleStreamEvent(event, assistantMessage.id),
768
+ (event) => handleStreamEvent(event, streamContext),
712
769
  {
713
770
  agentId: currentAgentIdRef.current,
714
771
  attachedResources: attachedResources?.length ? attachedResources : void 0,
@@ -743,6 +800,9 @@ function useChat(options) {
743
800
  pendingInterruptStreamIdRef.current = null;
744
801
  setIsLoading(false);
745
802
  setIsStreaming(false);
803
+ if (activeStreamContextRef.current?.token === streamContext.token) {
804
+ activeStreamContextRef.current = null;
805
+ }
746
806
  return false;
747
807
  }
748
808
  }, [adapter, clearPendingCancel, handleStreamEvent, onError, resetStreamBuffers, sessionResources]);
@@ -784,6 +844,7 @@ function useChat(options) {
784
844
  resetStreamBuffers();
785
845
  currentRunIdRef.current = null;
786
846
  pendingInterruptStreamIdRef.current = null;
847
+ activeStreamContextRef.current = null;
787
848
  setIsStreaming(false);
788
849
  setIsLoading(false);
789
850
  }, [clearPendingCancel, flushTypewriter, resetStreamBuffers]);
@@ -797,10 +858,20 @@ function useChat(options) {
797
858
  resetStreamBuffers();
798
859
  currentRunIdRef.current = null;
799
860
  pendingInterruptStreamIdRef.current = null;
861
+ activeStreamContextRef.current = null;
800
862
  clearPendingCancel();
801
863
  suppressStreamRef.current = false;
802
864
  }, [clearPendingCancel, resetStreamBuffers]);
803
- const loadConversation = (0, import_react.useCallback)(async (id) => {
865
+ const loadConversation = (0, import_react.useCallback)(async (id, optionsArg) => {
866
+ const cancelActiveStream = optionsArg?.cancelActiveStream ?? true;
867
+ const activeStream = activeStreamContextRef.current;
868
+ if (activeStream && !activeStream.detached) {
869
+ if (cancelActiveStream) {
870
+ stopStreaming();
871
+ } else {
872
+ detachActiveStream(optionsArg?.detachContext);
873
+ }
874
+ }
804
875
  try {
805
876
  setIsLoading(true);
806
877
  setError(null);
@@ -821,9 +892,19 @@ function useChat(options) {
821
892
  } finally {
822
893
  if (isMountedRef.current) setIsLoading(false);
823
894
  }
824
- }, [adapter, onError]);
825
- const newConversation = (0, import_react.useCallback)(() => {
826
- cancelRef.current?.();
895
+ }, [adapter, detachActiveStream, onError, stopStreaming]);
896
+ const newConversation = (0, import_react.useCallback)((optionsArg) => {
897
+ const cancelActiveStream = optionsArg?.cancelActiveStream ?? true;
898
+ const activeStream = activeStreamContextRef.current;
899
+ if (activeStream && !activeStream.detached) {
900
+ if (cancelActiveStream) {
901
+ stopStreaming();
902
+ } else {
903
+ detachActiveStream(optionsArg?.detachContext);
904
+ }
905
+ } else if (cancelActiveStream) {
906
+ cancelRef.current?.();
907
+ }
827
908
  if (typewriterIntervalRef.current) clearTimeout(typewriterIntervalRef.current);
828
909
  setMessages([]);
829
910
  setConversationId(null);
@@ -835,8 +916,9 @@ function useChat(options) {
835
916
  resetStreamBuffers();
836
917
  currentRunIdRef.current = null;
837
918
  pendingInterruptStreamIdRef.current = null;
919
+ activeStreamContextRef.current = null;
838
920
  clearPendingCancel();
839
- }, [clearPendingCancel, resetStreamBuffers]);
921
+ }, [clearPendingCancel, detachActiveStream, resetStreamBuffers, stopStreaming]);
840
922
  const sendHitlResponse = (0, import_react.useCallback)((response) => {
841
923
  const runId = currentRunIdRef.current ?? void 0;
842
924
  const streamId = pendingInterruptStreamIdRef.current ?? void 0;
@@ -916,7 +998,8 @@ function useChat(options) {
916
998
  loadConversation,
917
999
  newConversation,
918
1000
  sessionResources,
919
- removeSessionResource
1001
+ removeSessionResource,
1002
+ capabilities: CHAT_CAPABILITIES
920
1003
  };
921
1004
  }
922
1005
 
@@ -1837,33 +1920,56 @@ code {
1837
1920
 
1838
1921
  [data-streamdown="code-block-header"] {
1839
1922
  position: absolute !important;
1840
- top: 14px !important;
1841
- right: 8px !important;
1923
+ top: 10px !important;
1924
+ left: 12px !important;
1925
+ right: auto !important;
1842
1926
  z-index: 10;
1843
1927
  padding: 0 !important;
1844
1928
  background: transparent !important;
1845
1929
  border: none !important;
1846
1930
  opacity: 0;
1847
1931
  transition: opacity 150ms ease;
1932
+ pointer-events: none;
1848
1933
  }
1849
1934
 
1850
- [data-streamdown="code-block"]:hover [data-streamdown="code-block-header"] {
1935
+ [data-streamdown="code-block-actions"] {
1936
+ position: absolute !important;
1937
+ top: 10px !important;
1938
+ right: 8px !important;
1939
+ z-index: 11;
1940
+ display: flex !important;
1941
+ align-items: center;
1942
+ gap: 4px;
1943
+ padding: 0 !important;
1944
+ background: transparent !important;
1945
+ border: none !important;
1946
+ opacity: 0;
1947
+ transition: opacity 150ms ease;
1948
+ pointer-events: auto !important;
1949
+ }
1950
+
1951
+ [data-streamdown="code-block"]:hover [data-streamdown="code-block-header"],
1952
+ [data-streamdown="code-block"]:hover [data-streamdown="code-block-actions"] {
1851
1953
  opacity: 1;
1852
1954
  }
1853
1955
 
1854
1956
  [data-streamdown="code-block-header"] > span:first-child {
1957
+ display: inline-flex;
1855
1958
  font-size: 11px;
1856
1959
  color: var(--color-muted);
1857
1960
  text-transform: lowercase;
1858
- margin-right: 8px;
1859
1961
  }
1860
1962
 
1861
1963
  [data-streamdown="code-block-header"] > div {
1862
1964
  display: flex;
1863
1965
  gap: 4px;
1966
+ margin-left: 8px;
1967
+ pointer-events: auto;
1864
1968
  }
1865
1969
 
1866
- [data-streamdown="code-block-header"] button {
1970
+ /* Normalize action buttons for both streamdown v1 (header>div) and v2 (code-block-actions). */
1971
+ [data-streamdown="code-block-header"] button,
1972
+ [data-streamdown="code-block-actions"] button {
1867
1973
  padding: 4px !important;
1868
1974
  border: none !important;
1869
1975
  border-radius: 4px !important;
@@ -1872,18 +1978,21 @@ code {
1872
1978
  cursor: pointer;
1873
1979
  }
1874
1980
 
1875
- [data-streamdown="code-block-header"] button:hover {
1981
+ [data-streamdown="code-block-header"] button:hover,
1982
+ [data-streamdown="code-block-actions"] button:hover {
1876
1983
  opacity: 1;
1877
1984
  background: var(--color-border) !important;
1878
1985
  }
1879
1986
 
1880
- [data-streamdown="code-block-header"] svg {
1987
+ [data-streamdown="code-block-header"] svg,
1988
+ [data-streamdown="code-block-actions"] svg {
1881
1989
  color: var(--color-muted) !important;
1882
1990
  width: 12px !important;
1883
1991
  height: 12px !important;
1884
1992
  }
1885
1993
 
1886
- [data-streamdown="code-block-header"] button:hover svg {
1994
+ [data-streamdown="code-block-header"] button:hover svg,
1995
+ [data-streamdown="code-block-actions"] button:hover svg {
1887
1996
  color: var(--color-text) !important;
1888
1997
  }
1889
1998
 
@@ -6884,9 +6993,8 @@ var useChatHeader = (config) => {
6884
6993
  }
6885
6994
  if (typeof config?.alwaysOnTop === "boolean") {
6886
6995
  setIsPinned(config.alwaysOnTop);
6887
- resolvedOnPin?.(config.alwaysOnTop);
6888
6996
  }
6889
- }, [config?.alwaysOnTop, resolvedOnPin]);
6997
+ }, [config?.alwaysOnTop]);
6890
6998
  const showPin = !!resolvedOnPin || typeof config?.alwaysOnTop === "boolean";
6891
6999
  const showClose = !!resolvedOnClose;
6892
7000
  const logoNode = (0, import_react17.useMemo)(() => resolveLogoNode(config?.logo, "header"), [config?.logo]);
@@ -10169,7 +10277,9 @@ var HistoryList = (0, import_react36.memo)(function HistoryList2({
10169
10277
  onDelete,
10170
10278
  onLoadMore,
10171
10279
  isDarkMode = false,
10172
- strings = {}
10280
+ strings = {},
10281
+ isConversationHighlighted,
10282
+ highlightedLabel
10173
10283
  }) {
10174
10284
  const [hoveredId, setHoveredId] = (0, import_react36.useState)(null);
10175
10285
  const loadMoreRef = (0, import_react36.useRef)(null);
@@ -10225,6 +10335,8 @@ var HistoryList = (0, import_react36.memo)(function HistoryList2({
10225
10335
  conversations.map((conv) => {
10226
10336
  const isSelected = conv.id === selectedId;
10227
10337
  const isHovered = conv.id === hoveredId;
10338
+ const isHighlighted = isConversationHighlighted?.(conv) === true;
10339
+ const resolvedHighlightLabel = isHighlighted ? (typeof highlightedLabel === "function" ? highlightedLabel(conv) : highlightedLabel) ?? "RELATED" : null;
10228
10340
  return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
10229
10341
  "div",
10230
10342
  {
@@ -10236,21 +10348,39 @@ var HistoryList = (0, import_react36.memo)(function HistoryList2({
10236
10348
  padding: "0.5rem 0.75rem",
10237
10349
  textAlign: "left",
10238
10350
  cursor: "pointer",
10239
- transition: "background-color 0.15s ease",
10240
- background: isSelected || isHovered ? colors.hover : "transparent"
10351
+ transition: "background-color 0.15s ease, border-color 0.15s ease",
10352
+ border: isHighlighted ? "1px solid var(--chat-accent)" : "1px solid transparent",
10353
+ background: isSelected || isHovered ? colors.hover : isHighlighted ? "color-mix(in srgb, var(--chat-accent) 10%, transparent)" : "transparent"
10241
10354
  },
10242
10355
  onClick: () => onSelect(conv.id),
10243
10356
  onMouseEnter: () => setHoveredId(conv.id),
10244
10357
  onMouseLeave: () => setHoveredId(null),
10245
10358
  children: [
10246
10359
  /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { minWidth: 0, flex: 1 }, children: [
10247
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: {
10248
- fontSize: "0.875rem",
10249
- color: colors.text,
10250
- overflow: "hidden",
10251
- textOverflow: "ellipsis",
10252
- whiteSpace: "nowrap"
10253
- }, children: conv.title || "Untitled" }),
10360
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "0.375rem", minWidth: 0 }, children: [
10361
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: {
10362
+ fontSize: "0.875rem",
10363
+ color: colors.text,
10364
+ overflow: "hidden",
10365
+ textOverflow: "ellipsis",
10366
+ whiteSpace: "nowrap"
10367
+ }, children: conv.title || "Untitled" }),
10368
+ resolvedHighlightLabel && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
10369
+ "span",
10370
+ {
10371
+ style: {
10372
+ fontSize: "0.625rem",
10373
+ lineHeight: 1,
10374
+ padding: "0.2rem 0.35rem",
10375
+ borderRadius: 999,
10376
+ background: "var(--chat-accent)",
10377
+ color: "#fff",
10378
+ flexShrink: 0
10379
+ },
10380
+ children: resolvedHighlightLabel
10381
+ }
10382
+ )
10383
+ ] }),
10254
10384
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { fontSize: "0.75rem", color: colors.muted }, children: formatRelativeTime(conv.updatedAt, strings) })
10255
10385
  ] }),
10256
10386
  isHovered && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
@@ -10511,6 +10641,7 @@ var CompactChat = (0, import_react38.memo)(function CompactChat2({
10511
10641
  onError,
10512
10642
  onMessageReceived,
10513
10643
  onLoadingChange,
10644
+ onConversationChange,
10514
10645
  onStateChange,
10515
10646
  headerLeft,
10516
10647
  headerRight,
@@ -10519,8 +10650,13 @@ var CompactChat = (0, import_react38.memo)(function CompactChat2({
10519
10650
  inputPortalContainer,
10520
10651
  sendMessageRef,
10521
10652
  newConversationRef,
10653
+ loadConversationRef,
10654
+ stopStreamingRef,
10522
10655
  focusInputRef: parentFocusInputRef,
10523
10656
  setTextRef: parentSetTextRef,
10657
+ controllerRef,
10658
+ onConversationDeleted,
10659
+ historyConfig,
10524
10660
  renderMessage,
10525
10661
  emptyState,
10526
10662
  className = "",
@@ -10591,7 +10727,8 @@ var CompactChat = (0, import_react38.memo)(function CompactChat2({
10591
10727
  });
10592
10728
  const chat = useChat({
10593
10729
  adapter,
10594
- onError
10730
+ onError,
10731
+ onConversationChange
10595
10732
  });
10596
10733
  useFocusPersistence({
10597
10734
  containerRef: chatContainerRef,
@@ -10635,6 +10772,16 @@ var CompactChat = (0, import_react38.memo)(function CompactChat2({
10635
10772
  newConversationRef.current = chat.newConversation;
10636
10773
  }
10637
10774
  }, [newConversationRef, chat.newConversation]);
10775
+ (0, import_react38.useEffect)(() => {
10776
+ if (loadConversationRef) {
10777
+ loadConversationRef.current = chat.loadConversation;
10778
+ }
10779
+ }, [loadConversationRef, chat.loadConversation]);
10780
+ (0, import_react38.useEffect)(() => {
10781
+ if (stopStreamingRef) {
10782
+ stopStreamingRef.current = chat.stopStreaming;
10783
+ }
10784
+ }, [stopStreamingRef, chat.stopStreaming]);
10638
10785
  (0, import_react38.useEffect)(() => {
10639
10786
  if (parentFocusInputRef) {
10640
10787
  parentFocusInputRef.current = () => chatInputRef.current?.focus();
@@ -10645,6 +10792,63 @@ var CompactChat = (0, import_react38.memo)(function CompactChat2({
10645
10792
  parentSetTextRef.current = (text) => chatInputRef.current?.setValue(text);
10646
10793
  }
10647
10794
  }, [parentSetTextRef]);
10795
+ const getStateSnapshot = (0, import_react38.useCallback)(() => ({
10796
+ messages: chat.messages,
10797
+ isLoading: chat.isLoading,
10798
+ isStreaming: chat.isStreaming,
10799
+ error: chat.error,
10800
+ conversationId: chat.conversationId,
10801
+ conversationTitle: chat.conversationTitle,
10802
+ capabilities: chat.capabilities
10803
+ }), [
10804
+ chat.messages,
10805
+ chat.isLoading,
10806
+ chat.isStreaming,
10807
+ chat.error,
10808
+ chat.conversationId,
10809
+ chat.conversationTitle,
10810
+ chat.capabilities
10811
+ ]);
10812
+ (0, import_react38.useEffect)(() => {
10813
+ if (!controllerRef) return;
10814
+ controllerRef.current = {
10815
+ sendMessage: chat.sendMessage,
10816
+ trySendMessage: chat.trySendMessage,
10817
+ newConversation: chat.newConversation,
10818
+ loadConversation: chat.loadConversation,
10819
+ stopStreaming: chat.stopStreaming,
10820
+ focusInput: () => chatInputRef.current?.focus(),
10821
+ setInputText: (text) => chatInputRef.current?.setValue(text),
10822
+ getState: getStateSnapshot
10823
+ };
10824
+ }, [
10825
+ controllerRef,
10826
+ chat.sendMessage,
10827
+ chat.trySendMessage,
10828
+ chat.newConversation,
10829
+ chat.loadConversation,
10830
+ chat.stopStreaming,
10831
+ getStateSnapshot
10832
+ ]);
10833
+ (0, import_react38.useEffect)(() => {
10834
+ return () => {
10835
+ if (sendMessageRef) sendMessageRef.current = null;
10836
+ if (newConversationRef) newConversationRef.current = null;
10837
+ if (loadConversationRef) loadConversationRef.current = null;
10838
+ if (stopStreamingRef) stopStreamingRef.current = null;
10839
+ if (parentFocusInputRef) parentFocusInputRef.current = null;
10840
+ if (parentSetTextRef) parentSetTextRef.current = null;
10841
+ if (controllerRef) controllerRef.current = null;
10842
+ };
10843
+ }, [
10844
+ sendMessageRef,
10845
+ newConversationRef,
10846
+ loadConversationRef,
10847
+ stopStreamingRef,
10848
+ parentFocusInputRef,
10849
+ parentSetTextRef,
10850
+ controllerRef
10851
+ ]);
10648
10852
  (0, import_react38.useEffect)(() => {
10649
10853
  if (!adapter.onFocusInput) return;
10650
10854
  return adapter.onFocusInput(() => {
@@ -10666,12 +10870,9 @@ var CompactChat = (0, import_react38.memo)(function CompactChat2({
10666
10870
  }, [chat.isLoading, onLoadingChange]);
10667
10871
  (0, import_react38.useEffect)(() => {
10668
10872
  if (onStateChange) {
10669
- onStateChange({
10670
- messages: chat.messages,
10671
- conversationId: chat.conversationId
10672
- });
10873
+ onStateChange(getStateSnapshot());
10673
10874
  }
10674
- }, [chat.messages, chat.conversationId, onStateChange]);
10875
+ }, [getStateSnapshot, onStateChange]);
10675
10876
  (0, import_react38.useEffect)(() => {
10676
10877
  if (connection.isConnected) {
10677
10878
  resourcePicker.refreshProviders();
@@ -10699,11 +10900,12 @@ var CompactChat = (0, import_react38.memo)(function CompactChat2({
10699
10900
  const handleDeleteConversation = (0, import_react38.useCallback)(
10700
10901
  async (id) => {
10701
10902
  await conversations.deleteConversation(id);
10903
+ onConversationDeleted?.(id);
10702
10904
  if (id === chat.conversationId) {
10703
10905
  chat.newConversation();
10704
10906
  }
10705
10907
  },
10706
- [conversations, chat]
10908
+ [conversations, chat, onConversationDeleted]
10707
10909
  );
10708
10910
  const handleNewChat = (0, import_react38.useCallback)(() => {
10709
10911
  chat.newConversation();
@@ -10964,6 +11166,8 @@ var CompactChat = (0, import_react38.memo)(function CompactChat2({
10964
11166
  onDelete: handleDeleteConversation,
10965
11167
  onLoadMore: conversations.loadMore,
10966
11168
  isDarkMode: resolvedIsDarkMode,
11169
+ isConversationHighlighted: historyConfig?.isConversationHighlighted,
11170
+ highlightedLabel: historyConfig?.highlightedLabel,
10967
11171
  strings: {
10968
11172
  noHistory: mergedStrings.noHistory,
10969
11173
  loadMore: mergedStrings.loadMore,