@assistant-ui/react 0.5.82 → 0.5.84

Sign up to get free protection for your applications and to get access to all the features.
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,