@assistant-ui/react 0.5.82 → 0.5.84

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.mjs CHANGED
@@ -86,6 +86,10 @@ var { useToolUIs, useToolUIsStore } = createContextStoreHook(
86
86
  useAssistantContext,
87
87
  "useToolUIs"
88
88
  );
89
+ var { useThreadManager } = createContextStoreHook(
90
+ useAssistantContext,
91
+ "useThreadManager"
92
+ );
89
93
 
90
94
  // src/context/stores/AssistantToolUIs.ts
91
95
  import { create } from "zustand";
@@ -260,16 +264,29 @@ var useAssistantRuntimeStore2 = (runtime) => {
260
264
  var useAssistantToolUIsStore = () => {
261
265
  return useMemo2(() => makeAssistantToolUIsStore(), []);
262
266
  };
267
+ var useThreadManagerStore = (runtime) => {
268
+ const [store] = useState3(
269
+ () => create4(() => runtime.threadManager.getState())
270
+ );
271
+ useEffect3(() => {
272
+ const updateState = () => writableStore(store).setState(runtime.threadManager.getState(), true);
273
+ updateState();
274
+ return runtime.threadManager.subscribe(updateState);
275
+ }, [runtime, store]);
276
+ return store;
277
+ };
263
278
  var AssistantRuntimeProviderImpl = ({ children, runtime }) => {
264
279
  const useAssistantRuntime2 = useAssistantRuntimeStore2(runtime);
265
280
  const useToolUIs2 = useAssistantToolUIsStore();
281
+ const useThreadManager2 = useThreadManagerStore(runtime);
266
282
  const context = useMemo2(() => {
267
283
  return {
268
284
  useToolUIs: useToolUIs2,
269
285
  useAssistantRuntime: useAssistantRuntime2,
270
- useAssistantActions: useAssistantRuntime2
286
+ useAssistantActions: useAssistantRuntime2,
287
+ useThreadManager: useThreadManager2
271
288
  };
272
- }, [useAssistantRuntime2, useToolUIs2]);
289
+ }, [useAssistantRuntime2, useToolUIs2, useThreadManager2]);
273
290
  return /* @__PURE__ */ jsx2(AssistantContext.Provider, { value: context, children: /* @__PURE__ */ jsx2(ThreadRuntimeProvider, { runtime: runtime.thread, children }) });
274
291
  };
275
292
  var AssistantRuntimeProvider = memo(AssistantRuntimeProviderImpl);
@@ -448,22 +465,20 @@ import { useEffect as useEffect5 } from "react";
448
465
  var useAssistantTool = (tool) => {
449
466
  const assistantRuntime = useAssistantRuntime();
450
467
  const toolUIsStore = useToolUIsStore();
468
+ useEffect5(() => {
469
+ return tool.render ? toolUIsStore.getState().setToolUI(tool.toolName, tool.render) : void 0;
470
+ }, [toolUIsStore, tool.toolName, tool.render]);
451
471
  useEffect5(() => {
452
472
  const { toolName, render, ...rest } = tool;
453
473
  const config = {
454
474
  tools: {
455
- [tool.toolName]: rest
475
+ [toolName]: rest
456
476
  }
457
477
  };
458
- const unsub1 = assistantRuntime.registerModelConfigProvider({
478
+ return assistantRuntime.registerModelConfigProvider({
459
479
  getModelConfig: () => config
460
480
  });
461
- const unsub2 = render ? toolUIsStore.getState().setToolUI(toolName, render) : void 0;
462
- return () => {
463
- unsub1();
464
- unsub2?.();
465
- };
466
- }, [assistantRuntime, toolUIsStore, tool]);
481
+ }, [assistantRuntime, tool]);
467
482
  };
468
483
 
469
484
  // src/model-config/makeAssistantTool.tsx
@@ -482,9 +497,8 @@ var useAssistantToolUI = (tool) => {
482
497
  const toolUIsStore = useToolUIsStore();
483
498
  useEffect6(() => {
484
499
  if (!tool) return;
485
- const { toolName, render } = tool;
486
- return toolUIsStore.getState().setToolUI(toolName, render);
487
- }, [toolUIsStore, tool]);
500
+ return toolUIsStore.getState().setToolUI(tool.toolName, tool.render);
501
+ }, [toolUIsStore, tool?.toolName, tool?.render]);
488
502
  };
489
503
 
490
504
  // src/model-config/makeAssistantToolUI.tsx
@@ -511,8 +525,22 @@ var useAssistantInstructions = (instruction) => {
511
525
  }, [assistantRuntime, instruction]);
512
526
  };
513
527
 
528
+ // src/model-config/useInlineRender.tsx
529
+ import { useCallback as useCallback3, useEffect as useEffect8, useState as useState5 } from "react";
530
+ import { create as create6 } from "zustand";
531
+ var useInlineRender = (toolUI) => {
532
+ const [useToolUI] = useState5(() => create6(() => toolUI));
533
+ useEffect8(() => {
534
+ useToolUI.setState(toolUI);
535
+ });
536
+ return useCallback3((args) => {
537
+ const toolUI2 = useToolUI();
538
+ return toolUI2(args);
539
+ }, []);
540
+ };
541
+
514
542
  // src/primitive-hooks/actionBar/useActionBarCopy.tsx
515
- import { useCallback as useCallback3 } from "react";
543
+ import { useCallback as useCallback4 } from "react";
516
544
  var useActionBarCopy = ({
517
545
  copiedDuration = 3e3
518
546
  } = {}) => {
@@ -522,7 +550,7 @@ var useActionBarCopy = ({
522
550
  const hasCopyableContent = useMessage((message) => {
523
551
  return (message.role !== "assistant" || message.status.type !== "running") && message.content.some((c) => c.type === "text" && c.text.length > 0);
524
552
  });
525
- const callback = useCallback3(() => {
553
+ const callback = useCallback4(() => {
526
554
  const { isEditing, text: composerValue } = composerRuntime.getState();
527
555
  const valueToCopy = isEditing ? composerValue : messageRuntime.unstable_getCopyText();
528
556
  navigator.clipboard.writeText(valueToCopy).then(() => {
@@ -535,11 +563,11 @@ var useActionBarCopy = ({
535
563
  };
536
564
 
537
565
  // src/primitive-hooks/actionBar/useActionBarEdit.tsx
538
- import { useCallback as useCallback4 } from "react";
566
+ import { useCallback as useCallback5 } from "react";
539
567
  var useActionBarEdit = () => {
540
568
  const messageRuntime = useMessageRuntime();
541
569
  const disabled = useEditComposer((c) => c.isEditing);
542
- const callback = useCallback4(() => {
570
+ const callback = useCallback5(() => {
543
571
  messageRuntime.composer.beginEdit();
544
572
  }, [messageRuntime]);
545
573
  if (disabled) return null;
@@ -547,7 +575,7 @@ var useActionBarEdit = () => {
547
575
  };
548
576
 
549
577
  // src/primitive-hooks/actionBar/useActionBarReload.tsx
550
- import { useCallback as useCallback5 } from "react";
578
+ import { useCallback as useCallback6 } from "react";
551
579
 
552
580
  // src/utils/combined/useCombinedStore.ts
553
581
  import { useMemo as useMemo4 } from "react";
@@ -583,7 +611,7 @@ var useActionBarReload = () => {
583
611
  [threadRuntime, messageRuntime],
584
612
  (t, m) => t.isRunning || t.isDisabled || m.role !== "assistant"
585
613
  );
586
- const callback = useCallback5(() => {
614
+ const callback = useCallback6(() => {
587
615
  messageRuntime.reload();
588
616
  }, [messageRuntime]);
589
617
  if (disabled) return null;
@@ -591,10 +619,10 @@ var useActionBarReload = () => {
591
619
  };
592
620
 
593
621
  // src/primitive-hooks/actionBar/useActionBarSpeak.tsx
594
- import { useCallback as useCallback6 } from "react";
622
+ import { useCallback as useCallback7 } from "react";
595
623
  var useActionBarSpeak = () => {
596
624
  const messageRunime = useMessageRuntime();
597
- const callback = useCallback6(async () => {
625
+ const callback = useCallback7(async () => {
598
626
  messageRunime.speak();
599
627
  }, [messageRunime]);
600
628
  const hasSpeakableContent = useMessage((m) => {
@@ -605,11 +633,11 @@ var useActionBarSpeak = () => {
605
633
  };
606
634
 
607
635
  // src/primitive-hooks/actionBar/useActionBarStopSpeaking.tsx
608
- import { useCallback as useCallback7 } from "react";
636
+ import { useCallback as useCallback8 } from "react";
609
637
  var useActionBarStopSpeaking = () => {
610
638
  const messageRuntime = useMessageRuntime();
611
639
  const isSpeaking = useMessage((u) => u.speech != null);
612
- const callback = useCallback7(async () => {
640
+ const callback = useCallback8(async () => {
613
641
  messageRuntime.stopSpeaking();
614
642
  }, [messageRuntime]);
615
643
  if (!isSpeaking) return null;
@@ -617,20 +645,20 @@ var useActionBarStopSpeaking = () => {
617
645
  };
618
646
 
619
647
  // src/primitive-hooks/actionBar/useActionBarFeedbackPositive.tsx
620
- import { useCallback as useCallback8 } from "react";
648
+ import { useCallback as useCallback9 } from "react";
621
649
  var useActionBarFeedbackPositive = () => {
622
650
  const messageRuntime = useMessageRuntime();
623
- const callback = useCallback8(() => {
651
+ const callback = useCallback9(() => {
624
652
  messageRuntime.submitFeedback({ type: "positive" });
625
653
  }, [messageRuntime]);
626
654
  return callback;
627
655
  };
628
656
 
629
657
  // src/primitive-hooks/actionBar/useActionBarFeedbackNegative.tsx
630
- import { useCallback as useCallback9 } from "react";
658
+ import { useCallback as useCallback10 } from "react";
631
659
  var useActionBarFeedbackNegative = () => {
632
660
  const messageRuntime = useMessageRuntime();
633
- const callback = useCallback9(() => {
661
+ const callback = useCallback10(() => {
634
662
  messageRuntime.submitFeedback({ type: "negative" });
635
663
  }, [messageRuntime]);
636
664
  return callback;
@@ -643,11 +671,11 @@ var useBranchPickerCount = () => {
643
671
  };
644
672
 
645
673
  // src/primitive-hooks/branchPicker/useBranchPickerNext.tsx
646
- import { useCallback as useCallback10 } from "react";
674
+ import { useCallback as useCallback11 } from "react";
647
675
  var useBranchPickerNext = () => {
648
676
  const messageRuntime = useMessageRuntime();
649
677
  const disabled = useMessage((m) => m.branchNumber >= m.branchCount);
650
- const callback = useCallback10(() => {
678
+ const callback = useCallback11(() => {
651
679
  messageRuntime.switchToBranch({ position: "next" });
652
680
  }, [messageRuntime]);
653
681
  if (disabled) return null;
@@ -661,11 +689,11 @@ var useBranchPickerNumber = () => {
661
689
  };
662
690
 
663
691
  // src/primitive-hooks/branchPicker/useBranchPickerPrevious.tsx
664
- import { useCallback as useCallback11 } from "react";
692
+ import { useCallback as useCallback12 } from "react";
665
693
  var useBranchPickerPrevious = () => {
666
694
  const messageRuntime = useMessageRuntime();
667
695
  const disabled = useMessage((m) => m.branchNumber <= 1);
668
- const callback = useCallback11(() => {
696
+ const callback = useCallback12(() => {
669
697
  messageRuntime.switchToBranch({ position: "previous" });
670
698
  }, [messageRuntime]);
671
699
  if (disabled) return null;
@@ -673,11 +701,11 @@ var useBranchPickerPrevious = () => {
673
701
  };
674
702
 
675
703
  // src/primitive-hooks/composer/useComposerCancel.tsx
676
- import { useCallback as useCallback12 } from "react";
704
+ import { useCallback as useCallback13 } from "react";
677
705
  var useComposerCancel = () => {
678
706
  const composerRuntime = useComposerRuntime();
679
707
  const disabled = useComposer((c) => !c.canCancel);
680
- const callback = useCallback12(() => {
708
+ const callback = useCallback13(() => {
681
709
  composerRuntime.cancel();
682
710
  }, [composerRuntime]);
683
711
  if (disabled) return null;
@@ -694,7 +722,7 @@ var useComposerIf = (props) => {
694
722
  };
695
723
 
696
724
  // src/primitive-hooks/composer/useComposerSend.tsx
697
- import { useCallback as useCallback13 } from "react";
725
+ import { useCallback as useCallback14 } from "react";
698
726
  var useComposerSend = () => {
699
727
  const composerRuntime = useComposerRuntime();
700
728
  const threadRuntime = useThreadRuntime();
@@ -702,7 +730,7 @@ var useComposerSend = () => {
702
730
  [threadRuntime, composerRuntime],
703
731
  (t, c) => t.isRunning || !c.isEditing || c.isEmpty
704
732
  );
705
- const callback = useCallback13(() => {
733
+ const callback = useCallback14(() => {
706
734
  if (!composerRuntime.getState().isEditing) return;
707
735
  composerRuntime.send();
708
736
  }, [threadRuntime]);
@@ -711,11 +739,11 @@ var useComposerSend = () => {
711
739
  };
712
740
 
713
741
  // src/primitive-hooks/composer/useComposerAddAttachment.tsx
714
- import { useCallback as useCallback14 } from "react";
742
+ import { useCallback as useCallback15 } from "react";
715
743
  var useComposerAddAttachment = () => {
716
744
  const disabled = useComposer((c) => !c.isEditing);
717
745
  const composerRuntime = useComposerRuntime();
718
- const callback = useCallback14(() => {
746
+ const callback = useCallback15(() => {
719
747
  const input = document.createElement("input");
720
748
  input.type = "file";
721
749
  const attachmentAccept = composerRuntime.getAttachmentAccept();
@@ -825,11 +853,11 @@ var useThreadEmpty = () => {
825
853
  };
826
854
 
827
855
  // src/primitive-hooks/thread/useThreadScrollToBottom.tsx
828
- import { useCallback as useCallback15 } from "react";
856
+ import { useCallback as useCallback16 } from "react";
829
857
  var useThreadScrollToBottom = () => {
830
858
  const isAtBottom = useThreadViewport((s) => s.isAtBottom);
831
859
  const threadViewportStore = useThreadViewportStore();
832
- const handleScrollToBottom = useCallback15(() => {
860
+ const handleScrollToBottom = useCallback16(() => {
833
861
  threadViewportStore.getState().scrollToBottom();
834
862
  }, [threadViewportStore]);
835
863
  if (isAtBottom) return null;
@@ -837,14 +865,14 @@ var useThreadScrollToBottom = () => {
837
865
  };
838
866
 
839
867
  // src/primitive-hooks/thread/useThreadSuggestion.tsx
840
- import { useCallback as useCallback16 } from "react";
868
+ import { useCallback as useCallback17 } from "react";
841
869
  var useThreadSuggestion = ({
842
870
  prompt,
843
871
  autoSend
844
872
  }) => {
845
873
  const threadRuntime = useThreadRuntime();
846
874
  const disabled = useThread((t) => t.isDisabled);
847
- const callback = useCallback16(() => {
875
+ const callback = useCallback17(() => {
848
876
  if (autoSend && !threadRuntime.getState().isRunning) {
849
877
  threadRuntime.append(prompt);
850
878
  threadRuntime.composer.setText("");
@@ -1083,7 +1111,7 @@ __export(assistantModal_exports, {
1083
1111
  });
1084
1112
 
1085
1113
  // src/primitives/assistantModal/AssistantModalRoot.tsx
1086
- import { useEffect as useEffect8, useState as useState5 } from "react";
1114
+ import { useEffect as useEffect9, useState as useState6 } from "react";
1087
1115
  import * as PopoverPrimitive2 from "@radix-ui/react-popover";
1088
1116
  import { composeEventHandlers as composeEventHandlers6 } from "@radix-ui/primitive";
1089
1117
 
@@ -1097,10 +1125,10 @@ var useAssistantModalOpenState = ({
1097
1125
  defaultOpen = false,
1098
1126
  unstable_openOnRunStart = true
1099
1127
  }) => {
1100
- const state = useState5(defaultOpen);
1128
+ const state = useState6(defaultOpen);
1101
1129
  const [, setOpen] = state;
1102
1130
  const threadRuntime = useThreadRuntime();
1103
- useEffect8(() => {
1131
+ useEffect9(() => {
1104
1132
  if (!unstable_openOnRunStart) return void 0;
1105
1133
  return threadRuntime.unstable_on("run-start", () => {
1106
1134
  setOpen(true);
@@ -1294,10 +1322,10 @@ var AttachmentPrimitiveName = () => {
1294
1322
  AttachmentPrimitiveName.displayName = "AttachmentPrimitive.Name";
1295
1323
 
1296
1324
  // src/primitive-hooks/attachment/useAttachmentRemove.ts
1297
- import { useCallback as useCallback17 } from "react";
1325
+ import { useCallback as useCallback18 } from "react";
1298
1326
  var useAttachmentRemove = () => {
1299
1327
  const attachmentRuntime = useAttachmentRuntime();
1300
- const handleRemoveAttachment = useCallback17(() => {
1328
+ const handleRemoveAttachment = useCallback18(() => {
1301
1329
  attachmentRuntime.remove();
1302
1330
  }, [attachmentRuntime]);
1303
1331
  return handleRemoveAttachment;
@@ -1365,14 +1393,14 @@ __export(message_exports, {
1365
1393
  import { Primitive as Primitive9 } from "@radix-ui/react-primitive";
1366
1394
  import {
1367
1395
  forwardRef as forwardRef12,
1368
- useCallback as useCallback19
1396
+ useCallback as useCallback20
1369
1397
  } from "react";
1370
1398
 
1371
1399
  // src/utils/hooks/useManagedRef.ts
1372
- import { useCallback as useCallback18, useRef } from "react";
1400
+ import { useCallback as useCallback19, useRef } from "react";
1373
1401
  var useManagedRef = (callback) => {
1374
1402
  const cleanupRef = useRef();
1375
- const ref = useCallback18(
1403
+ const ref = useCallback19(
1376
1404
  (el) => {
1377
1405
  if (cleanupRef.current) {
1378
1406
  cleanupRef.current();
@@ -1391,7 +1419,7 @@ import { useComposedRefs } from "@radix-ui/react-compose-refs";
1391
1419
  import { jsx as jsx18 } from "react/jsx-runtime";
1392
1420
  var useIsHoveringRef = () => {
1393
1421
  const messageUtilsStore = useMessageUtilsStore();
1394
- const callbackRef = useCallback19(
1422
+ const callbackRef = useCallback20(
1395
1423
  (el) => {
1396
1424
  const setIsHovering = messageUtilsStore.getState().setIsHovering;
1397
1425
  const handleMouseEnter = () => {
@@ -1433,19 +1461,19 @@ MessagePrimitiveIf.displayName = "MessagePrimitive.If";
1433
1461
  import { memo as memo2, useMemo as useMemo6 } from "react";
1434
1462
 
1435
1463
  // src/context/providers/ContentPartRuntimeProvider.tsx
1436
- import { useEffect as useEffect9, useState as useState6 } from "react";
1437
- import { create as create6 } from "zustand";
1464
+ import { useEffect as useEffect10, useState as useState7 } from "react";
1465
+ import { create as create7 } from "zustand";
1438
1466
  import { jsx as jsx19 } from "react/jsx-runtime";
1439
1467
  var useContentPartRuntimeStore = (runtime) => {
1440
- const [store] = useState6(() => create6(() => runtime));
1441
- useEffect9(() => {
1468
+ const [store] = useState7(() => create7(() => runtime));
1469
+ useEffect10(() => {
1442
1470
  writableStore(store).setState(runtime, true);
1443
1471
  }, [runtime, store]);
1444
1472
  return store;
1445
1473
  };
1446
1474
  var useContentPartStore2 = (runtime) => {
1447
- const [store] = useState6(() => create6(() => runtime.getState()));
1448
- useEffect9(() => {
1475
+ const [store] = useState7(() => create7(() => runtime.getState()));
1476
+ useEffect10(() => {
1449
1477
  const updateState = () => writableStore(store).setState(runtime.getState(), true);
1450
1478
  updateState();
1451
1479
  return runtime.subscribe(updateState);
@@ -1458,7 +1486,7 @@ var ContentPartRuntimeProvider = ({
1458
1486
  }) => {
1459
1487
  const useContentPartRuntime2 = useContentPartRuntimeStore(runtime);
1460
1488
  const useContentPart2 = useContentPartStore2(runtime);
1461
- const [context] = useState6(() => {
1489
+ const [context] = useState7(() => {
1462
1490
  return { useContentPartRuntime: useContentPartRuntime2, useContentPart: useContentPart2 };
1463
1491
  });
1464
1492
  return /* @__PURE__ */ jsx19(ContentPartContext.Provider, { value: context, children });
@@ -1470,7 +1498,7 @@ import {
1470
1498
  } from "react";
1471
1499
 
1472
1500
  // src/utils/smooth/useSmooth.tsx
1473
- import { useEffect as useEffect10, useMemo as useMemo5, useRef as useRef2, useState as useState8 } from "react";
1501
+ import { useEffect as useEffect11, useMemo as useMemo5, useRef as useRef2, useState as useState9 } from "react";
1474
1502
  import { useCallbackRef } from "@radix-ui/react-use-callback-ref";
1475
1503
 
1476
1504
  // src/utils/smooth/SmoothContext.tsx
@@ -1478,19 +1506,19 @@ import {
1478
1506
  createContext as createContext6,
1479
1507
  forwardRef as forwardRef13,
1480
1508
  useContext as useContext3,
1481
- useState as useState7
1509
+ useState as useState8
1482
1510
  } from "react";
1483
- import { create as create7 } from "zustand";
1511
+ import { create as create8 } from "zustand";
1484
1512
  import { jsx as jsx20 } from "react/jsx-runtime";
1485
1513
  var SmoothContext = createContext6(null);
1486
1514
  var makeSmoothContext = (initialState) => {
1487
- const useSmoothStatus2 = create7(() => initialState);
1515
+ const useSmoothStatus2 = create8(() => initialState);
1488
1516
  return { useSmoothStatus: useSmoothStatus2 };
1489
1517
  };
1490
1518
  var SmoothContextProvider = ({ children }) => {
1491
1519
  const outer = useSmoothContext({ optional: true });
1492
1520
  const contentPartStore = useContentPartStore();
1493
- const [context] = useState7(
1521
+ const [context] = useState8(
1494
1522
  () => makeSmoothContext(contentPartStore.getState().status)
1495
1523
  );
1496
1524
  if (outer) return children;
@@ -1571,7 +1599,7 @@ var useSmooth = (state, smooth = false) => {
1571
1599
  selector: (m) => m.id
1572
1600
  });
1573
1601
  const idRef = useRef2(id);
1574
- const [displayedText, setDisplayedText] = useState8(text);
1602
+ const [displayedText, setDisplayedText] = useState9(text);
1575
1603
  const smoothStatusStore = useSmoothStatusStore({ optional: true });
1576
1604
  const setText = useCallbackRef((text2) => {
1577
1605
  setDisplayedText(text2);
@@ -1581,17 +1609,17 @@ var useSmooth = (state, smooth = false) => {
1581
1609
  );
1582
1610
  }
1583
1611
  });
1584
- useEffect10(() => {
1612
+ useEffect11(() => {
1585
1613
  if (smoothStatusStore) {
1586
1614
  writableStore(smoothStatusStore).setState(
1587
1615
  text !== state.text ? SMOOTH_STATUS : state.status
1588
1616
  );
1589
1617
  }
1590
1618
  }, [smoothStatusStore, text, displayedText, state.status, state.text]);
1591
- const [animatorRef] = useState8(
1619
+ const [animatorRef] = useState9(
1592
1620
  new TextStreamAnimator(text, setText)
1593
1621
  );
1594
- useEffect10(() => {
1622
+ useEffect11(() => {
1595
1623
  if (!smooth) {
1596
1624
  animatorRef.stop();
1597
1625
  return;
@@ -1607,7 +1635,7 @@ var useSmooth = (state, smooth = false) => {
1607
1635
  animatorRef.targetText = text;
1608
1636
  animatorRef.start();
1609
1637
  }, [setText, animatorRef, id, smooth, text]);
1610
- useEffect10(() => {
1638
+ useEffect11(() => {
1611
1639
  return () => {
1612
1640
  animatorRef.stop();
1613
1641
  };
@@ -2374,22 +2402,22 @@ import { memo as memo3, useMemo as useMemo8 } from "react";
2374
2402
 
2375
2403
  // src/context/providers/AttachmentRuntimeProvider.tsx
2376
2404
  import {
2377
- useEffect as useEffect11,
2405
+ useEffect as useEffect12,
2378
2406
  useMemo as useMemo7,
2379
- useState as useState9
2407
+ useState as useState10
2380
2408
  } from "react";
2381
- import { create as create8 } from "zustand";
2409
+ import { create as create9 } from "zustand";
2382
2410
  import { jsx as jsx24 } from "react/jsx-runtime";
2383
2411
  var useAttachmentRuntimeStore = (runtime) => {
2384
- const [store] = useState9(() => create8(() => runtime));
2385
- useEffect11(() => {
2412
+ const [store] = useState10(() => create9(() => runtime));
2413
+ useEffect12(() => {
2386
2414
  writableStore(store).setState(runtime, true);
2387
2415
  }, [runtime, store]);
2388
2416
  return store;
2389
2417
  };
2390
2418
  var useAttachmentStore = (runtime) => {
2391
- const [store] = useState9(() => create8(() => runtime.getState()));
2392
- useEffect11(() => {
2419
+ const [store] = useState10(() => create9(() => runtime.getState()));
2420
+ useEffect12(() => {
2393
2421
  const updateState = () => writableStore(store).setState(runtime.getState(), true);
2394
2422
  updateState();
2395
2423
  return runtime.subscribe(updateState);
@@ -2514,8 +2542,8 @@ import { useComposedRefs as useComposedRefs2 } from "@radix-ui/react-compose-ref
2514
2542
  import { Slot } from "@radix-ui/react-slot";
2515
2543
  import {
2516
2544
  forwardRef as forwardRef18,
2517
- useCallback as useCallback20,
2518
- useEffect as useEffect13,
2545
+ useCallback as useCallback21,
2546
+ useEffect as useEffect14,
2519
2547
  useRef as useRef3
2520
2548
  } from "react";
2521
2549
  import TextareaAutosize from "react-textarea-autosize";
@@ -2523,11 +2551,11 @@ import { useEscapeKeydown as useEscapeKeydown2 } from "@radix-ui/react-use-escap
2523
2551
 
2524
2552
  // src/utils/hooks/useOnScrollToBottom.tsx
2525
2553
  import { useCallbackRef as useCallbackRef2 } from "@radix-ui/react-use-callback-ref";
2526
- import { useEffect as useEffect12 } from "react";
2554
+ import { useEffect as useEffect13 } from "react";
2527
2555
  var useOnScrollToBottom = (callback) => {
2528
2556
  const callbackRef = useCallbackRef2(callback);
2529
2557
  const onScrollToBottom = useThreadViewport((vp) => vp.onScrollToBottom);
2530
- useEffect12(() => {
2558
+ useEffect13(() => {
2531
2559
  return onScrollToBottom(callbackRef);
2532
2560
  }, [onScrollToBottom, callbackRef]);
2533
2561
  };
@@ -2577,7 +2605,7 @@ var ComposerPrimitiveInput = forwardRef18(
2577
2605
  }
2578
2606
  };
2579
2607
  const autoFocusEnabled = autoFocus && !isDisabled;
2580
- const focus2 = useCallback20(() => {
2608
+ const focus2 = useCallback21(() => {
2581
2609
  const textarea = textareaRef.current;
2582
2610
  if (!textarea || !autoFocusEnabled) return;
2583
2611
  textarea.focus({ preventScroll: true });
@@ -2586,18 +2614,18 @@ var ComposerPrimitiveInput = forwardRef18(
2586
2614
  textareaRef.current.value.length
2587
2615
  );
2588
2616
  }, [autoFocusEnabled]);
2589
- useEffect13(() => focus2(), [focus2]);
2617
+ useEffect14(() => focus2(), [focus2]);
2590
2618
  useOnScrollToBottom(() => {
2591
2619
  if (composerRuntime.type === "thread" && unstable_focusOnScrollToBottom) {
2592
2620
  focus2();
2593
2621
  }
2594
2622
  });
2595
- useEffect13(() => {
2623
+ useEffect14(() => {
2596
2624
  if (composerRuntime.type !== "thread" || !unstable_focusOnRunStart)
2597
2625
  return void 0;
2598
2626
  return threadRuntime.unstable_on("run-start", focus2);
2599
2627
  }, [unstable_focusOnRunStart]);
2600
- useEffect13(() => {
2628
+ useEffect14(() => {
2601
2629
  if (composerRuntime.type !== "thread" || !unstable_focusOnThreadSwitched)
2602
2630
  return void 0;
2603
2631
  return threadRuntime.unstable_on("switched-to", focus2);
@@ -2754,14 +2782,14 @@ import { forwardRef as forwardRef20 } from "react";
2754
2782
 
2755
2783
  // src/primitive-hooks/thread/useThreadViewportAutoScroll.tsx
2756
2784
  import { useComposedRefs as useComposedRefs3 } from "@radix-ui/react-compose-refs";
2757
- import { useEffect as useEffect14, useRef as useRef4 } from "react";
2785
+ import { useEffect as useEffect15, useRef as useRef4 } from "react";
2758
2786
 
2759
2787
  // src/utils/hooks/useOnResizeContent.tsx
2760
2788
  import { useCallbackRef as useCallbackRef3 } from "@radix-ui/react-use-callback-ref";
2761
- import { useCallback as useCallback21 } from "react";
2789
+ import { useCallback as useCallback22 } from "react";
2762
2790
  var useOnResizeContent = (callback) => {
2763
2791
  const callbackRef = useCallbackRef3(callback);
2764
- const refCallback = useCallback21(
2792
+ const refCallback = useCallback22(
2765
2793
  (el) => {
2766
2794
  const resizeObserver = new ResizeObserver(() => {
2767
2795
  callbackRef();
@@ -2846,7 +2874,7 @@ var useThreadViewportAutoScroll = ({
2846
2874
  scrollToBottom("auto");
2847
2875
  });
2848
2876
  const threadRuntime = useThreadRuntime();
2849
- useEffect14(() => {
2877
+ useEffect15(() => {
2850
2878
  if (!unstable_scrollToBottomOnRunStart) return void 0;
2851
2879
  return threadRuntime.unstable_on("run-start", focus);
2852
2880
  }, [unstable_scrollToBottomOnRunStart]);
@@ -2868,12 +2896,12 @@ ThreadPrimitiveViewport.displayName = "ThreadPrimitive.Viewport";
2868
2896
  import { memo as memo5, useMemo as useMemo10 } from "react";
2869
2897
 
2870
2898
  // src/context/providers/MessageRuntimeProvider.tsx
2871
- import { useEffect as useEffect15, useState as useState10 } from "react";
2872
- import { create as create10 } from "zustand";
2899
+ import { useEffect as useEffect16, useState as useState11 } from "react";
2900
+ import { create as create11 } from "zustand";
2873
2901
 
2874
2902
  // src/context/stores/MessageUtils.ts
2875
- import { create as create9 } from "zustand";
2876
- var makeMessageUtilsStore = () => create9((set) => {
2903
+ import { create as create10 } from "zustand";
2904
+ var makeMessageUtilsStore = () => create10((set) => {
2877
2905
  return {
2878
2906
  isCopied: false,
2879
2907
  setIsCopied: (value) => {
@@ -2889,15 +2917,15 @@ var makeMessageUtilsStore = () => create9((set) => {
2889
2917
  // src/context/providers/MessageRuntimeProvider.tsx
2890
2918
  import { jsx as jsx32 } from "react/jsx-runtime";
2891
2919
  var useMessageRuntimeStore = (runtime) => {
2892
- const [store] = useState10(() => create10(() => runtime));
2893
- useEffect15(() => {
2920
+ const [store] = useState11(() => create11(() => runtime));
2921
+ useEffect16(() => {
2894
2922
  writableStore(store).setState(runtime, true);
2895
2923
  }, [runtime, store]);
2896
2924
  return store;
2897
2925
  };
2898
2926
  var useMessageStore2 = (runtime) => {
2899
- const [store] = useState10(() => create10(() => runtime.getState()));
2900
- useEffect15(() => {
2927
+ const [store] = useState11(() => create11(() => runtime.getState()));
2928
+ useEffect16(() => {
2901
2929
  const updateState = () => writableStore(store).setState(runtime.getState(), true);
2902
2930
  updateState();
2903
2931
  return runtime.subscribe(updateState);
@@ -2905,13 +2933,13 @@ var useMessageStore2 = (runtime) => {
2905
2933
  return store;
2906
2934
  };
2907
2935
  var useMessageUtilsStore2 = () => {
2908
- const [store] = useState10(() => makeMessageUtilsStore());
2936
+ const [store] = useState11(() => makeMessageUtilsStore());
2909
2937
  return store;
2910
2938
  };
2911
2939
  var useEditComposerStore2 = (useMessageRuntime2) => {
2912
2940
  const runtime = useMessageRuntime2.getState().composer;
2913
- const [store] = useState10(() => create10(() => runtime.getState()));
2914
- useEffect15(() => {
2941
+ const [store] = useState11(() => create11(() => runtime.getState()));
2942
+ useEffect16(() => {
2915
2943
  const updateState = () => writableStore(store).setState(runtime.getState());
2916
2944
  updateState();
2917
2945
  return runtime.subscribe(updateState);
@@ -2926,7 +2954,7 @@ var MessageRuntimeProvider = ({
2926
2954
  const useMessage2 = useMessageStore2(runtime);
2927
2955
  const useMessageUtils2 = useMessageUtilsStore2();
2928
2956
  const useEditComposer2 = useEditComposerStore2(useMessageRuntime2);
2929
- const [context] = useState10(() => {
2957
+ const [context] = useState11(() => {
2930
2958
  return { useMessageRuntime: useMessageRuntime2, useMessage: useMessage2, useMessageUtils: useMessageUtils2, useEditComposer: useEditComposer2 };
2931
2959
  });
2932
2960
  return /* @__PURE__ */ jsx32(MessageContext.Provider, { value: context, children });
@@ -3018,13 +3046,13 @@ var subscribeToMainThread = (runtime, callback) => {
3018
3046
  let cleanup;
3019
3047
  const inner = () => {
3020
3048
  cleanup?.();
3021
- cleanup = runtime.thread.subscribe(callback);
3049
+ cleanup = runtime.threadManager.mainThread.subscribe(callback);
3022
3050
  if (!first) {
3023
3051
  callback();
3024
3052
  }
3025
3053
  first = false;
3026
3054
  };
3027
- const unsubscribe = runtime.subscribe(inner);
3055
+ const unsubscribe = runtime.threadManager.mainThread.subscribe(inner);
3028
3056
  inner();
3029
3057
  return () => {
3030
3058
  unsubscribe();
@@ -3033,29 +3061,44 @@ var subscribeToMainThread = (runtime, callback) => {
3033
3061
  };
3034
3062
 
3035
3063
  // src/runtimes/local/useLocalRuntime.tsx
3036
- import { useInsertionEffect, useMemo as useMemo11, useState as useState12 } from "react";
3064
+ import { useEffect as useEffect17, useMemo as useMemo11, useState as useState13 } from "react";
3037
3065
 
3038
- // src/runtimes/core/BaseAssistantRuntimeCore.tsx
3039
- var BaseAssistantRuntimeCore = class {
3040
- constructor(_thread) {
3041
- this._thread = _thread;
3042
- this._thread = _thread;
3066
+ // src/utils/ProxyConfigProvider.ts
3067
+ var ProxyConfigProvider = class {
3068
+ _providers = /* @__PURE__ */ new Set();
3069
+ getModelConfig() {
3070
+ return mergeModelConfigs(this._providers);
3043
3071
  }
3044
- get thread() {
3045
- return this._thread;
3072
+ registerModelConfigProvider(provider) {
3073
+ this._providers.add(provider);
3074
+ const unsubscribe = provider.subscribe?.(() => {
3075
+ this.notifySubscribers();
3076
+ });
3077
+ this.notifySubscribers();
3078
+ return () => {
3079
+ this._providers.delete(provider);
3080
+ unsubscribe?.();
3081
+ this.notifySubscribers();
3082
+ };
3046
3083
  }
3047
- set thread(thread) {
3048
- this._thread = thread;
3049
- this.subscriptionHandler();
3084
+ _subscribers = /* @__PURE__ */ new Set();
3085
+ notifySubscribers() {
3086
+ for (const callback of this._subscribers) callback();
3050
3087
  }
3051
- _subscriptions = /* @__PURE__ */ new Set();
3052
3088
  subscribe(callback) {
3053
- this._subscriptions.add(callback);
3054
- return () => this._subscriptions.delete(callback);
3089
+ this._subscribers.add(callback);
3090
+ return () => this._subscribers.delete(callback);
3091
+ }
3092
+ };
3093
+
3094
+ // src/runtimes/core/BaseAssistantRuntimeCore.tsx
3095
+ var BaseAssistantRuntimeCore = class {
3096
+ _proxyConfigProvider = new ProxyConfigProvider();
3097
+ constructor() {
3098
+ }
3099
+ registerModelConfigProvider(provider) {
3100
+ return this._proxyConfigProvider.registerModelConfigProvider(provider);
3055
3101
  }
3056
- subscriptionHandler = () => {
3057
- for (const callback of this._subscriptions) callback();
3058
- };
3059
3102
  };
3060
3103
 
3061
3104
  // src/internal.ts
@@ -3191,34 +3234,6 @@ var DefaultThreadComposerRuntimeCore = class extends BaseComposerRuntimeCore {
3191
3234
  }
3192
3235
  };
3193
3236
 
3194
- // src/utils/ProxyConfigProvider.ts
3195
- var ProxyConfigProvider = class {
3196
- _providers = /* @__PURE__ */ new Set();
3197
- getModelConfig() {
3198
- return mergeModelConfigs(this._providers);
3199
- }
3200
- registerModelConfigProvider(provider) {
3201
- this._providers.add(provider);
3202
- const unsubscribe = provider.subscribe?.(() => {
3203
- this.notifySubscribers();
3204
- });
3205
- this.notifySubscribers();
3206
- return () => {
3207
- this._providers.delete(provider);
3208
- unsubscribe?.();
3209
- this.notifySubscribers();
3210
- };
3211
- }
3212
- _subscribers = /* @__PURE__ */ new Set();
3213
- notifySubscribers() {
3214
- for (const callback of this._subscribers) callback();
3215
- }
3216
- subscribe(callback) {
3217
- this._subscribers.add(callback);
3218
- return () => this._subscribers.delete(callback);
3219
- }
3220
- };
3221
-
3222
3237
  // src/utils/idUtils.tsx
3223
3238
  import { customAlphabet } from "nanoid/non-secure";
3224
3239
  var generateId = customAlphabet(
@@ -3828,20 +3843,67 @@ var ThreadRuntimeImpl = class {
3828
3843
  }
3829
3844
  };
3830
3845
 
3846
+ // src/api/ThreadManagerRuntime.ts
3847
+ var getThreadManagerState = (threadManager) => {
3848
+ return {
3849
+ threads: threadManager.threads,
3850
+ archivedThreads: threadManager.archivedThreads
3851
+ };
3852
+ };
3853
+ var THREAD_MANAGER_PATH = {
3854
+ ref: "threadManager"
3855
+ };
3856
+ var ThreadManagerRuntimeImpl = class {
3857
+ constructor(_core) {
3858
+ this._core = _core;
3859
+ const stateBinding = new LazyMemoizeSubject({
3860
+ path: THREAD_MANAGER_PATH,
3861
+ getState: () => getThreadManagerState(_core),
3862
+ subscribe: (callback) => _core.subscribe(callback)
3863
+ });
3864
+ this._getState = stateBinding.getState.bind(stateBinding);
3865
+ }
3866
+ get path() {
3867
+ return THREAD_MANAGER_PATH;
3868
+ }
3869
+ _getState;
3870
+ getState() {
3871
+ return this._getState();
3872
+ }
3873
+ rename(threadId, newTitle) {
3874
+ return this._core.rename(threadId, newTitle);
3875
+ }
3876
+ archive(threadId) {
3877
+ return this._core.archive(threadId);
3878
+ }
3879
+ unarchive(threadId) {
3880
+ return this._core.unarchive(threadId);
3881
+ }
3882
+ delete(threadId) {
3883
+ return this._core.delete(threadId);
3884
+ }
3885
+ subscribe(callback) {
3886
+ return this._core.subscribe(callback);
3887
+ }
3888
+ };
3889
+
3831
3890
  // src/api/AssistantRuntime.ts
3832
3891
  var AssistantRuntimeImpl = class _AssistantRuntimeImpl {
3833
3892
  constructor(_core, _thread) {
3834
3893
  this._core = _core;
3835
3894
  this._thread = _thread;
3895
+ this.threadManager = new ThreadManagerRuntimeImpl(_core.threadManager);
3836
3896
  }
3897
+ threadManager;
3837
3898
  get thread() {
3838
3899
  return this._thread;
3839
3900
  }
3840
3901
  switchToNewThread() {
3841
- return this._core.switchToNewThread();
3902
+ return this._core.threadManager.switchToNewThread();
3842
3903
  }
3843
3904
  switchToThread(threadId) {
3844
- return this._core.switchToThread(threadId);
3905
+ if (threadId === null) return this.switchToNewThread();
3906
+ return this._core.threadManager.switchToThread(threadId);
3845
3907
  }
3846
3908
  registerModelConfigProvider(provider) {
3847
3909
  return this._core.registerModelConfigProvider(provider);
@@ -3849,8 +3911,9 @@ var AssistantRuntimeImpl = class _AssistantRuntimeImpl {
3849
3911
  /**
3850
3912
  * @deprecated Thread is now static and never gets updated. This will be removed in 0.6.0.
3851
3913
  */
3852
- subscribe(callback) {
3853
- return this._core.subscribe(callback);
3914
+ subscribe() {
3915
+ return () => {
3916
+ };
3854
3917
  }
3855
3918
  static createMainThreadRuntime(_core, CustomThreadRuntime = ThreadRuntimeImpl) {
3856
3919
  return new CustomThreadRuntime(
@@ -3859,8 +3922,8 @@ var AssistantRuntimeImpl = class _AssistantRuntimeImpl {
3859
3922
  ref: "threads.main",
3860
3923
  threadSelector: { type: "main" }
3861
3924
  },
3862
- getState: () => _core.thread,
3863
- subscribe: (callback) => _core.subscribe(callback)
3925
+ getState: () => _core.threadManager.mainThread,
3926
+ subscribe: (callback) => _core.threadManager.subscribe(callback)
3864
3927
  })
3865
3928
  );
3866
3929
  }
@@ -4039,7 +4102,7 @@ var streamUtils = {
4039
4102
  };
4040
4103
 
4041
4104
  // src/runtimes/edge/useEdgeRuntime.ts
4042
- import { useState as useState11 } from "react";
4105
+ import { useState as useState12 } from "react";
4043
4106
 
4044
4107
  // src/runtimes/edge/streams/assistantDecoderStream.ts
4045
4108
  function assistantDecoderStream() {
@@ -4220,7 +4283,7 @@ var splitLocalRuntimeOptions = (options) => {
4220
4283
  // src/runtimes/edge/useEdgeRuntime.ts
4221
4284
  var useEdgeRuntime = (options) => {
4222
4285
  const { localRuntimeOptions, otherOptions } = splitLocalRuntimeOptions(options);
4223
- const [adapter] = useState11(() => new EdgeChatAdapter(otherOptions));
4286
+ const [adapter] = useState12(() => new EdgeChatAdapter(otherOptions));
4224
4287
  return useLocalRuntime(adapter, localRuntimeOptions);
4225
4288
  };
4226
4289
 
@@ -4272,9 +4335,6 @@ var DefaultEditComposerRuntimeCore = class extends BaseComposerRuntimeCore {
4272
4335
  var BaseThreadRuntimeCore = class {
4273
4336
  constructor(configProvider) {
4274
4337
  this.configProvider = configProvider;
4275
- this.configProvider.subscribe?.(() => {
4276
- this._notifyEventSubscribers("model-config-update");
4277
- });
4278
4338
  }
4279
4339
  _subscriptions = /* @__PURE__ */ new Set();
4280
4340
  repository = new MessageRepository();
@@ -4376,6 +4436,10 @@ var BaseThreadRuntimeCore = class {
4376
4436
  }
4377
4437
  _eventSubscribers = /* @__PURE__ */ new Map();
4378
4438
  unstable_on(event, callback) {
4439
+ if (event === "model-config-update") {
4440
+ return this.configProvider.subscribe?.(callback) ?? (() => {
4441
+ });
4442
+ }
4379
4443
  const subscribers = this._eventSubscribers.get(event);
4380
4444
  if (!subscribers) {
4381
4445
  this._eventSubscribers.set(event, /* @__PURE__ */ new Set([callback]));
@@ -4391,19 +4455,10 @@ var BaseThreadRuntimeCore = class {
4391
4455
 
4392
4456
  // src/runtimes/local/LocalThreadRuntimeCore.tsx
4393
4457
  var LocalThreadRuntimeCore = class extends BaseThreadRuntimeCore {
4394
- constructor(configProvider, adapter, { initialMessages, ...options }) {
4458
+ constructor(configProvider, threadId, options) {
4395
4459
  super(configProvider);
4396
- this.adapter = adapter;
4397
- this.threadId = generateId();
4398
- this.options = options;
4399
- if (initialMessages) {
4400
- let parentId = null;
4401
- const messages2 = fromCoreMessages(initialMessages);
4402
- for (const message of messages2) {
4403
- this.repository.addOrUpdateMessage(parentId, message);
4404
- parentId = message.id;
4405
- }
4406
- }
4460
+ this.threadId = threadId;
4461
+ this._options = options;
4407
4462
  }
4408
4463
  capabilities = {
4409
4464
  switchToBranch: true,
@@ -4416,20 +4471,17 @@ var LocalThreadRuntimeCore = class extends BaseThreadRuntimeCore {
4416
4471
  feedback: false
4417
4472
  };
4418
4473
  abortController = null;
4419
- threadId;
4420
4474
  isDisabled = false;
4421
4475
  suggestions = [];
4422
4476
  get adapters() {
4423
- return this.options.adapters;
4477
+ return this._options.adapters;
4424
4478
  }
4425
4479
  _options;
4426
- get options() {
4427
- return this._options;
4428
- }
4429
4480
  get extras() {
4430
4481
  return void 0;
4431
4482
  }
4432
- set options({ initialMessages, ...options }) {
4483
+ setOptions(options) {
4484
+ if (this._options === options) return;
4433
4485
  this._options = options;
4434
4486
  let hasUpdates = false;
4435
4487
  const canSpeak = options.adapters?.speech !== void 0;
@@ -4505,7 +4557,7 @@ var LocalThreadRuntimeCore = class extends BaseThreadRuntimeCore {
4505
4557
  this.repository.addOrUpdateMessage(parentId, message);
4506
4558
  this._notifySubscribers();
4507
4559
  };
4508
- const maxSteps = this.options.maxSteps ? this.options.maxSteps : (this.options.maxToolRoundtrips ?? 1) + 1;
4560
+ const maxSteps = this._options.maxSteps ? this._options.maxSteps : (this._options.maxToolRoundtrips ?? 1) + 1;
4509
4561
  const steps = message.metadata?.steps?.length ?? 0;
4510
4562
  if (steps >= maxSteps) {
4511
4563
  updateMessage({
@@ -4523,7 +4575,7 @@ var LocalThreadRuntimeCore = class extends BaseThreadRuntimeCore {
4523
4575
  });
4524
4576
  }
4525
4577
  try {
4526
- const promiseOrGenerator = this.adapter.run({
4578
+ const promiseOrGenerator = this.adapters.chatModel.run({
4527
4579
  messages: messages2,
4528
4580
  abortSignal: this.abortController.signal,
4529
4581
  config: this.getModelConfig(),
@@ -4596,44 +4648,154 @@ var LocalThreadRuntimeCore = class extends BaseThreadRuntimeCore {
4596
4648
  }
4597
4649
  };
4598
4650
 
4599
- // src/runtimes/local/LocalRuntimeCore.tsx
4600
- var LocalRuntimeCore = class extends BaseAssistantRuntimeCore {
4601
- _proxyConfigProvider;
4602
- constructor(adapter, options) {
4603
- const proxyConfigProvider = new ProxyConfigProvider();
4604
- super(new LocalThreadRuntimeCore(proxyConfigProvider, adapter, options));
4605
- this._proxyConfigProvider = proxyConfigProvider;
4651
+ // src/runtimes/local/LocalThreadManagerRuntimeCore.tsx
4652
+ var LocalThreadManagerRuntimeCore = class {
4653
+ constructor(_threadFactory) {
4654
+ this._threadFactory = _threadFactory;
4655
+ this._mainThread = this._threadFactory(generateId(), { messages: [] });
4606
4656
  }
4607
- registerModelConfigProvider(provider) {
4608
- return this._proxyConfigProvider.registerModelConfigProvider(provider);
4657
+ _threadData = /* @__PURE__ */ new Map();
4658
+ _threads = [];
4659
+ _archivedThreads = [];
4660
+ get threads() {
4661
+ return this._threads;
4609
4662
  }
4610
- switchToNewThread() {
4611
- const { initialMessages, ...options } = this.thread.options;
4612
- this.thread = new LocalThreadRuntimeCore(
4613
- this._proxyConfigProvider,
4614
- this.thread.adapter,
4615
- options
4616
- );
4617
- this.thread._notifyEventSubscribers("switched-to");
4663
+ get archivedThreads() {
4664
+ return this._archivedThreads;
4665
+ }
4666
+ _mainThread;
4667
+ get mainThread() {
4668
+ return this._mainThread;
4618
4669
  }
4619
4670
  switchToThread(threadId) {
4620
- if (threadId !== null) {
4621
- throw new Error("LocalRuntime does not yet support switching threads");
4671
+ if (this._mainThread.threadId === threadId) return;
4672
+ const data = this._threadData.get(threadId);
4673
+ if (!data) throw new Error("Thread not found");
4674
+ const thread = this._threadFactory(threadId, data.data);
4675
+ this._performThreadSwitch(thread);
4676
+ }
4677
+ switchToNewThread() {
4678
+ if (!this._mainThread) return;
4679
+ const thread = this._threadFactory(generateId(), { messages: [] });
4680
+ this._performThreadSwitch(thread);
4681
+ }
4682
+ _performThreadSwitch(newThreadCore) {
4683
+ if (this._mainThread) {
4684
+ const data = this._threadData.get(this._mainThread.threadId);
4685
+ if (!data) throw new Error("Thread not found");
4686
+ const exprt = this._mainThread.export();
4687
+ data.data = exprt;
4622
4688
  }
4623
- this.switchToNewThread();
4689
+ this._mainThread._notifyEventSubscribers("switched-away");
4690
+ this._mainThread = newThreadCore;
4691
+ newThreadCore._notifyEventSubscribers("switched-to");
4692
+ this._notifySubscribers();
4693
+ }
4694
+ _performMoveOp(threadId, operation) {
4695
+ const data = this._threadData.get(threadId);
4696
+ if (!data) throw new Error("Thread not found");
4697
+ if (operation === "archive" && data.isArchived) return;
4698
+ if (operation === "unarchive" && !data.isArchived) return;
4699
+ if (operation === "archive") {
4700
+ data.isArchived = true;
4701
+ this._archivedThreads = [...this._archivedThreads, data.metadata];
4702
+ }
4703
+ if (operation === "unarchive") {
4704
+ data.isArchived = false;
4705
+ this._threads = [...this._threads, data.metadata];
4706
+ }
4707
+ if (operation === "delete") {
4708
+ this._threadData.delete(threadId);
4709
+ }
4710
+ if (operation === "archive" || operation === "delete" && data.isArchived) {
4711
+ this._archivedThreads = this._archivedThreads.filter(
4712
+ (t) => t.threadId !== threadId
4713
+ );
4714
+ }
4715
+ if (operation === "unarchive" || operation === "delete" && !data.isArchived) {
4716
+ this._threads = this._threads.filter((t) => t.threadId !== threadId);
4717
+ }
4718
+ this._notifySubscribers();
4719
+ }
4720
+ async rename(threadId, newTitle) {
4721
+ const data = this._threadData.get(threadId);
4722
+ if (!data) throw new Error("Thread not found");
4723
+ data.metadata = {
4724
+ ...data.metadata,
4725
+ title: newTitle
4726
+ };
4727
+ const threadList = data.isArchived ? this.archivedThreads : this.threads;
4728
+ const idx = threadList.findIndex((t) => t.threadId === threadId);
4729
+ const updatedThreadList = threadList.toSpliced(idx, 1, data.metadata);
4730
+ if (data.isArchived) {
4731
+ this._archivedThreads = updatedThreadList;
4732
+ } else {
4733
+ this._threads = updatedThreadList;
4734
+ }
4735
+ this._notifySubscribers();
4736
+ }
4737
+ async archive(threadId) {
4738
+ this._performMoveOp(threadId, "archive");
4739
+ }
4740
+ async unarchive(threadId) {
4741
+ this._performMoveOp(threadId, "unarchive");
4742
+ }
4743
+ async delete(threadId) {
4744
+ this._performMoveOp(threadId, "delete");
4745
+ }
4746
+ _subscriptions = /* @__PURE__ */ new Set();
4747
+ subscribe(callback) {
4748
+ this._subscriptions.add(callback);
4749
+ return () => this._subscriptions.delete(callback);
4750
+ }
4751
+ _notifySubscribers() {
4752
+ for (const callback of this._subscriptions) callback();
4753
+ }
4754
+ };
4755
+
4756
+ // src/runtimes/local/LocalRuntimeCore.tsx
4757
+ var getExportFromInitialMessages = (initialMessages) => {
4758
+ const messages2 = fromCoreMessages(initialMessages);
4759
+ return {
4760
+ messages: messages2.map((m, idx) => ({
4761
+ parentId: messages2[idx - 1]?.id ?? null,
4762
+ message: m
4763
+ }))
4764
+ };
4765
+ };
4766
+ var LocalRuntimeCore = class extends BaseAssistantRuntimeCore {
4767
+ threadManager;
4768
+ _options;
4769
+ constructor(options, initialMessages) {
4770
+ super();
4771
+ this._options = options;
4772
+ this.threadManager = new LocalThreadManagerRuntimeCore((threadId, data) => {
4773
+ const thread = new LocalThreadRuntimeCore(
4774
+ this._proxyConfigProvider,
4775
+ threadId,
4776
+ this._options
4777
+ );
4778
+ thread.import(data);
4779
+ return thread;
4780
+ });
4781
+ if (initialMessages) {
4782
+ this.threadManager.mainThread.import(
4783
+ getExportFromInitialMessages(initialMessages)
4784
+ );
4785
+ }
4786
+ }
4787
+ setOptions(options) {
4788
+ this._options = options;
4789
+ this.threadManager.mainThread.setOptions(options);
4624
4790
  }
4625
4791
  reset({
4626
4792
  initialMessages
4627
4793
  } = {}) {
4628
- this.switchToThread(null);
4794
+ this.threadManager.switchToNewThread();
4629
4795
  if (!initialMessages) return;
4630
- const messages2 = fromCoreMessages(initialMessages);
4631
- this.thread.import({
4632
- messages: messages2.map((m, idx) => ({
4633
- parentId: messages2[idx - 1]?.id ?? null,
4634
- message: m
4635
- }))
4636
- });
4796
+ this.threadManager.mainThread.import(
4797
+ getExportFromInitialMessages(initialMessages)
4798
+ );
4637
4799
  }
4638
4800
  };
4639
4801
 
@@ -4654,16 +4816,108 @@ var LocalRuntimeImpl = class _LocalRuntimeImpl extends AssistantRuntimeImpl {
4654
4816
  }
4655
4817
  };
4656
4818
  var useLocalRuntime = (adapter, options = {}) => {
4657
- const [runtime] = useState12(() => new LocalRuntimeCore(adapter, options));
4658
- useInsertionEffect(() => {
4659
- runtime.thread.adapter = adapter;
4660
- runtime.thread.options = options;
4819
+ const opt = {
4820
+ ...options,
4821
+ adapters: {
4822
+ ...options.adapters,
4823
+ chatModel: adapter
4824
+ }
4825
+ };
4826
+ const [runtime] = useState13(() => new LocalRuntimeCore(opt));
4827
+ useEffect17(() => {
4828
+ runtime.setOptions(opt);
4661
4829
  });
4662
4830
  return useMemo11(() => LocalRuntimeImpl.create(runtime), [runtime]);
4663
4831
  };
4664
4832
 
4665
4833
  // src/runtimes/external-store/useExternalStoreRuntime.tsx
4666
- import { useEffect as useEffect16, useMemo as useMemo12, useState as useState13 } from "react";
4834
+ import { useEffect as useEffect18, useMemo as useMemo12, useState as useState14 } from "react";
4835
+
4836
+ // src/runtimes/external-store/ExternalStoreThreadManagementAdapter.tsx
4837
+ var EMPTY_ARRAY2 = Object.freeze([]);
4838
+ var DEFAULT_THREAD_ID = "DEFAULT_THREAD_ID";
4839
+ var ExternalStoreThreadManagerRuntimeCore = class {
4840
+ constructor(adapter = {}, threadFactory) {
4841
+ this.adapter = adapter;
4842
+ this.threadFactory = threadFactory;
4843
+ this._mainThread = this.threadFactory(DEFAULT_THREAD_ID);
4844
+ }
4845
+ get threads() {
4846
+ return this.adapter.threads ?? EMPTY_ARRAY2;
4847
+ }
4848
+ get archivedThreads() {
4849
+ return this.adapter.archivedThreads ?? EMPTY_ARRAY2;
4850
+ }
4851
+ _mainThread;
4852
+ get mainThread() {
4853
+ return this._mainThread;
4854
+ }
4855
+ setAdapter(adapter) {
4856
+ const previousAdapter = this.adapter;
4857
+ this.adapter = adapter;
4858
+ const newThreadId = adapter.threadId ?? DEFAULT_THREAD_ID;
4859
+ const newThreads = adapter.threads ?? EMPTY_ARRAY2;
4860
+ const newArchivedThreads = adapter.archivedThreads ?? EMPTY_ARRAY2;
4861
+ if (previousAdapter.threadId === newThreadId && previousAdapter.threads === newThreads && previousAdapter.archivedThreads === newArchivedThreads) {
4862
+ return;
4863
+ }
4864
+ if (previousAdapter.threadId !== newThreadId) {
4865
+ this._mainThread._notifyEventSubscribers("switched-away");
4866
+ this._mainThread = this.threadFactory(newThreadId);
4867
+ this._mainThread._notifyEventSubscribers("switched-to");
4868
+ }
4869
+ this._notifySubscribers();
4870
+ }
4871
+ switchToThread(threadId) {
4872
+ if (this._mainThread?.threadId === threadId) return;
4873
+ const onSwitchToThread = this.adapter.onSwitchToThread;
4874
+ if (!onSwitchToThread)
4875
+ throw new Error(
4876
+ "External store adapter does not support switching to thread"
4877
+ );
4878
+ onSwitchToThread(threadId);
4879
+ }
4880
+ switchToNewThread() {
4881
+ const onSwitchToNewThread = this.adapter.onSwitchToNewThread;
4882
+ if (!onSwitchToNewThread)
4883
+ throw new Error(
4884
+ "External store adapter does not support switching to new thread"
4885
+ );
4886
+ onSwitchToNewThread();
4887
+ }
4888
+ async rename(threadId, newTitle) {
4889
+ const onRename = this.adapter.onRename;
4890
+ if (!onRename)
4891
+ throw new Error("External store adapter does not support renaming");
4892
+ onRename(threadId, newTitle);
4893
+ }
4894
+ async archive(threadId) {
4895
+ const onArchive = this.adapter.onArchive;
4896
+ if (!onArchive)
4897
+ throw new Error("External store adapter does not support archiving");
4898
+ onArchive(threadId);
4899
+ }
4900
+ async unarchive(threadId) {
4901
+ const onUnarchive = this.adapter.onUnarchive;
4902
+ if (!onUnarchive)
4903
+ throw new Error("External store adapter does not support unarchiving");
4904
+ onUnarchive(threadId);
4905
+ }
4906
+ async delete(threadId) {
4907
+ const onDelete = this.adapter.onDelete;
4908
+ if (!onDelete)
4909
+ throw new Error("External store adapter does not support deleting");
4910
+ onDelete(threadId);
4911
+ }
4912
+ _subscriptions = /* @__PURE__ */ new Set();
4913
+ subscribe(callback) {
4914
+ this._subscriptions.add(callback);
4915
+ return () => this._subscriptions.delete(callback);
4916
+ }
4917
+ _notifySubscribers() {
4918
+ for (const callback of this._subscriptions) callback();
4919
+ }
4920
+ };
4667
4921
 
4668
4922
  // src/runtimes/external-store/getExternalStoreMessage.tsx
4669
4923
  var symbolInnerMessage = Symbol("innerMessage");
@@ -4768,7 +5022,7 @@ var fromThreadMessageLike = (like, fallbackId, fallbackStatus) => {
4768
5022
  };
4769
5023
 
4770
5024
  // src/runtimes/external-store/ExternalStoreThreadRuntimeCore.tsx
4771
- var EMPTY_ARRAY2 = Object.freeze([]);
5025
+ var EMPTY_ARRAY3 = Object.freeze([]);
4772
5026
  var hasUpcomingMessage = (isRunning, messages2) => {
4773
5027
  return isRunning && messages2[messages2.length - 1]?.role !== "assistant";
4774
5028
  };
@@ -4801,26 +5055,23 @@ var ExternalStoreThreadRuntimeCore = class extends BaseThreadRuntimeCore {
4801
5055
  _converter = new ThreadMessageConverter();
4802
5056
  _store;
4803
5057
  beginEdit(messageId) {
4804
- if (!this.store.onEdit)
5058
+ if (!this._store.onEdit)
4805
5059
  throw new Error("Runtime does not support editing.");
4806
5060
  super.beginEdit(messageId);
4807
5061
  }
4808
- constructor(configProvider, store) {
5062
+ constructor(configProvider, threadId, store) {
4809
5063
  super(configProvider);
4810
- this.store = store;
4811
- }
4812
- get store() {
4813
- return this._store;
5064
+ this.threadId = threadId;
5065
+ this.setStore(store);
4814
5066
  }
4815
- set store(store) {
5067
+ setStore(store) {
4816
5068
  if (this._store === store) return;
4817
- this.threadId = store.threadId ?? this.threadId ?? generateId();
4818
5069
  const isRunning = store.isRunning ?? false;
4819
5070
  this.isDisabled = store.isDisabled ?? false;
4820
5071
  const oldStore = this._store;
4821
5072
  this._store = store;
4822
5073
  this.extras = store.extras;
4823
- this.suggestions = store.suggestions ?? EMPTY_ARRAY2;
5074
+ this.suggestions = store.suggestions ?? EMPTY_ARRAY3;
4824
5075
  this._capabilities = {
4825
5076
  switchToBranch: this._store.setMessages !== void 0,
4826
5077
  edit: this._store.onEdit !== void 0,
@@ -4829,8 +5080,8 @@ var ExternalStoreThreadRuntimeCore = class extends BaseThreadRuntimeCore {
4829
5080
  speech: this._store.adapters?.speech !== void 0,
4830
5081
  unstable_copy: this._store.unstable_capabilities?.copy !== false,
4831
5082
  // default true
4832
- attachments: !!this.store.adapters?.attachments,
4833
- feedback: !!this.store.adapters?.feedback
5083
+ attachments: !!this._store.adapters?.attachments,
5084
+ feedback: !!this._store.adapters?.feedback
4834
5085
  };
4835
5086
  if (oldStore) {
4836
5087
  if (oldStore.convertMessage !== store.convertMessage) {
@@ -4934,57 +5185,41 @@ var ExternalStoreThreadRuntimeCore = class extends BaseThreadRuntimeCore {
4934
5185
  };
4935
5186
 
4936
5187
  // src/runtimes/external-store/ExternalStoreRuntimeCore.tsx
5188
+ var getThreadManagerAdapter = (store) => {
5189
+ return {
5190
+ threadId: store.threadId,
5191
+ onSwitchToNewThread: store.onSwitchToNewThread,
5192
+ onSwitchToThread: store.onSwitchToThread,
5193
+ ...store.adapters?.threadManager
5194
+ };
5195
+ };
4937
5196
  var ExternalStoreRuntimeCore = class extends BaseAssistantRuntimeCore {
4938
- _proxyConfigProvider;
5197
+ threadManager;
5198
+ _store;
4939
5199
  constructor(store) {
4940
- const provider = new ProxyConfigProvider();
4941
- super(new ExternalStoreThreadRuntimeCore(provider, store));
4942
- this._proxyConfigProvider = provider;
4943
- }
4944
- getModelConfig() {
4945
- return this._proxyConfigProvider.getModelConfig();
4946
- }
4947
- registerModelConfigProvider(provider) {
4948
- return this._proxyConfigProvider.registerModelConfigProvider(provider);
4949
- }
4950
- async switchToNewThread() {
4951
- if (!this.thread.store.onSwitchToNewThread)
4952
- throw new Error("Runtime does not support switching to new threads.");
4953
- this.thread = new ExternalStoreThreadRuntimeCore(
4954
- this._proxyConfigProvider,
4955
- {
4956
- ...this.thread.store,
4957
- messages: []
4958
- }
4959
- );
4960
- await this.thread.store.onSwitchToNewThread();
4961
- this.thread._notifyEventSubscribers("switched-to");
4962
- }
4963
- async switchToThread(threadId) {
4964
- if (threadId !== null) {
4965
- if (!this.thread.store.onSwitchToThread)
4966
- throw new Error("Runtime does not support switching threads.");
4967
- this.thread = new ExternalStoreThreadRuntimeCore(
5200
+ super();
5201
+ this._store = store;
5202
+ this.threadManager = new ExternalStoreThreadManagerRuntimeCore(
5203
+ getThreadManagerAdapter(store),
5204
+ (threadId) => new ExternalStoreThreadRuntimeCore(
4968
5205
  this._proxyConfigProvider,
4969
- {
4970
- ...this.thread.store,
4971
- messages: []
4972
- // ignore messages until rerender
4973
- }
4974
- );
4975
- await this.thread.store.onSwitchToThread(threadId);
4976
- this.thread._notifyEventSubscribers("switched-to");
4977
- } else {
4978
- this.switchToNewThread();
4979
- }
5206
+ threadId,
5207
+ this._store
5208
+ )
5209
+ );
5210
+ }
5211
+ setStore(store) {
5212
+ this._store = store;
5213
+ this.threadManager.setAdapter(getThreadManagerAdapter(store));
5214
+ this.threadManager.mainThread.setStore(store);
4980
5215
  }
4981
5216
  };
4982
5217
 
4983
5218
  // src/runtimes/external-store/useExternalStoreRuntime.tsx
4984
5219
  var useExternalStoreRuntime = (store) => {
4985
- const [runtime] = useState13(() => new ExternalStoreRuntimeCore(store));
4986
- useEffect16(() => {
4987
- runtime.thread.store = store;
5220
+ const [runtime] = useState14(() => new ExternalStoreRuntimeCore(store));
5221
+ useEffect18(() => {
5222
+ runtime.setStore(store);
4988
5223
  });
4989
5224
  return useMemo12(
4990
5225
  () => AssistantRuntimeImpl.create(runtime, ThreadRuntimeImpl),
@@ -5139,7 +5374,7 @@ var shallowArrayEqual = (a, b) => {
5139
5374
  };
5140
5375
 
5141
5376
  // src/runtimes/dangerous-in-browser/useDangerousInBrowserRuntime.ts
5142
- import { useState as useState14 } from "react";
5377
+ import { useState as useState15 } from "react";
5143
5378
 
5144
5379
  // src/runtimes/dangerous-in-browser/DangerousInBrowserAdapter.ts
5145
5380
  var DangerousInBrowserAdapter = class {
@@ -5168,7 +5403,7 @@ var DangerousInBrowserAdapter = class {
5168
5403
  // src/runtimes/dangerous-in-browser/useDangerousInBrowserRuntime.ts
5169
5404
  var useDangerousInBrowserRuntime = (options) => {
5170
5405
  const { localRuntimeOptions, otherOptions } = splitLocalRuntimeOptions(options);
5171
- const [adapter] = useState14(() => new DangerousInBrowserAdapter(otherOptions));
5406
+ const [adapter] = useState15(() => new DangerousInBrowserAdapter(otherOptions));
5172
5407
  return useLocalRuntime(adapter, localRuntimeOptions);
5173
5408
  };
5174
5409
 
@@ -5754,8 +5989,8 @@ CircleStopIcon.displayName = "CircleStopIcon";
5754
5989
  // src/ui/attachment.tsx
5755
5990
  import {
5756
5991
  forwardRef as forwardRef28,
5757
- useEffect as useEffect17,
5758
- useState as useState15
5992
+ useEffect as useEffect19,
5993
+ useState as useState16
5759
5994
  } from "react";
5760
5995
  import { CircleXIcon, FileIcon } from "lucide-react";
5761
5996
 
@@ -5798,8 +6033,8 @@ var AttachmentRoot = withDefaults(attachment_exports.Root, {
5798
6033
  });
5799
6034
  AttachmentRoot.displayName = "AttachmentRoot";
5800
6035
  var useFileSrc = (file) => {
5801
- const [src, setSrc] = useState15(void 0);
5802
- useEffect17(() => {
6036
+ const [src, setSrc] = useState16(void 0);
6037
+ useEffect19(() => {
5803
6038
  if (!file) {
5804
6039
  setSrc(void 0);
5805
6040
  return;
@@ -5823,7 +6058,7 @@ var useAttachmentSrc = () => {
5823
6058
  return useFileSrc(file) ?? src;
5824
6059
  };
5825
6060
  var AttachmentPreview = ({ src }) => {
5826
- const [isLoaded, setIsLoaded] = useState15(false);
6061
+ const [isLoaded, setIsLoaded] = useState16(false);
5827
6062
  return (
5828
6063
  // eslint-disable-next-line @next/next/no-img-element
5829
6064
  /* @__PURE__ */ jsx46(
@@ -6069,8 +6304,13 @@ var ThreadWelcomeMessageStyled = withDefaults("p", {
6069
6304
  className: "aui-thread-welcome-message"
6070
6305
  });
6071
6306
  var ThreadWelcomeMessage = forwardRef30(({ message: messageProp, ...rest }, ref) => {
6072
- const { welcome: { message = "How can I help you today?" } = {} } = useThreadConfig();
6073
- return /* @__PURE__ */ jsx48(ThreadWelcomeMessageStyled, { ...rest, ref, children: messageProp ?? message });
6307
+ const {
6308
+ welcome: { message } = {},
6309
+ strings: {
6310
+ welcome: { message: defaultMessage = "How can I help you today?" } = {}
6311
+ } = {}
6312
+ } = useThreadConfig();
6313
+ return /* @__PURE__ */ jsx48(ThreadWelcomeMessageStyled, { ...rest, ref, children: messageProp ?? message ?? defaultMessage });
6074
6314
  });
6075
6315
  ThreadWelcomeMessage.displayName = "ThreadWelcomeMessage";
6076
6316
  var ThreadWelcomeSuggestionContainer = withDefaults("div", {
@@ -6504,6 +6744,7 @@ export {
6504
6744
  useEditComposerStore,
6505
6745
  useExternalMessageConverter,
6506
6746
  useExternalStoreRuntime,
6747
+ useInlineRender,
6507
6748
  useLocalRuntime,
6508
6749
  useMessage,
6509
6750
  useMessageContext,
@@ -6522,6 +6763,7 @@ export {
6522
6763
  useThreadContext,
6523
6764
  useThreadEmpty,
6524
6765
  useThreadIf,
6766
+ useThreadManager,
6525
6767
  useThreadMessages,
6526
6768
  useThreadMessagesStore,
6527
6769
  useThreadModelConfig,