@assistant-ui/react 0.1.8 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -98,7 +98,7 @@ var getMessageText = (message) => {
98
98
 
99
99
  // src/actions/useCopyMessage.tsx
100
100
  var useCopyMessage = ({ copiedDuration = 3e3 }) => {
101
- const { useMessage, useComposer } = useMessageContext();
101
+ const { useMessage, useMessageUtils, useComposer } = useMessageContext();
102
102
  const hasCopyableContent = useCombinedStore(
103
103
  [useMessage, useComposer],
104
104
  (m, c) => {
@@ -106,13 +106,14 @@ var useCopyMessage = ({ copiedDuration = 3e3 }) => {
106
106
  }
107
107
  );
108
108
  const callback = (0, import_react4.useCallback)(() => {
109
+ const { message } = useMessage.getState();
110
+ const { setIsCopied } = useMessageUtils.getState();
109
111
  const { isEditing, value: composerValue } = useComposer.getState();
110
- const { message, setIsCopied } = useMessage.getState();
111
112
  const valueToCopy = isEditing ? composerValue : getMessageText(message);
112
113
  navigator.clipboard.writeText(valueToCopy);
113
114
  setIsCopied(true);
114
115
  setTimeout(() => setIsCopied(false), copiedDuration);
115
- }, [useComposer, useMessage, copiedDuration]);
116
+ }, [useMessage, useMessageUtils, useComposer, copiedDuration]);
116
117
  if (!hasCopyableContent) return null;
117
118
  return callback;
118
119
  };
@@ -134,7 +135,7 @@ var useThreadContext = () => {
134
135
 
135
136
  // src/actions/useReloadMessage.tsx
136
137
  var useReloadMessage = () => {
137
- const { useThread, useViewport } = useThreadContext();
138
+ const { useThread, useThreadActions, useViewport } = useThreadContext();
138
139
  const { useMessage } = useMessageContext();
139
140
  const disabled = useCombinedStore(
140
141
  [useThread, useMessage],
@@ -142,9 +143,9 @@ var useReloadMessage = () => {
142
143
  );
143
144
  const callback = (0, import_react6.useCallback)(() => {
144
145
  const { parentId } = useMessage.getState();
145
- useThread.getState().startRun(parentId);
146
+ useThreadActions.getState().startRun(parentId);
146
147
  useViewport.getState().scrollToBottom();
147
- }, [useMessage, useThread, useViewport]);
148
+ }, [useThreadActions, useMessage, useViewport]);
148
149
  if (disabled) return null;
149
150
  return callback;
150
151
  };
@@ -168,7 +169,7 @@ var useBeginMessageEdit = () => {
168
169
  // src/actions/useGoToNextBranch.tsx
169
170
  var import_react8 = require("react");
170
171
  var useGoToNextBranch = () => {
171
- const { useThread } = useThreadContext();
172
+ const { useThreadActions } = useThreadContext();
172
173
  const { useMessage, useComposer } = useMessageContext();
173
174
  const disabled = useCombinedStore(
174
175
  [useMessage, useComposer],
@@ -176,8 +177,8 @@ var useGoToNextBranch = () => {
176
177
  );
177
178
  const callback = (0, import_react8.useCallback)(() => {
178
179
  const { message, branches } = useMessage.getState();
179
- useThread.getState().switchToBranch(branches[branches.indexOf(message.id) + 1]);
180
- }, [useMessage, useThread]);
180
+ useThreadActions.getState().switchToBranch(branches[branches.indexOf(message.id) + 1]);
181
+ }, [useThreadActions, useMessage]);
181
182
  if (disabled) return null;
182
183
  return callback;
183
184
  };
@@ -185,7 +186,7 @@ var useGoToNextBranch = () => {
185
186
  // src/actions/useGoToPreviousBranch.tsx
186
187
  var import_react9 = require("react");
187
188
  var useGoToPreviousBranch = () => {
188
- const { useThread } = useThreadContext();
189
+ const { useThreadActions } = useThreadContext();
189
190
  const { useMessage, useComposer } = useMessageContext();
190
191
  const disabled = useCombinedStore(
191
192
  [useMessage, useComposer],
@@ -193,8 +194,8 @@ var useGoToPreviousBranch = () => {
193
194
  );
194
195
  const callback = (0, import_react9.useCallback)(() => {
195
196
  const { message, branches } = useMessage.getState();
196
- useThread.getState().switchToBranch(branches[branches.indexOf(message.id) - 1]);
197
- }, [useMessage, useThread]);
197
+ useThreadActions.getState().switchToBranch(branches[branches.indexOf(message.id) - 1]);
198
+ }, [useThreadActions, useMessage]);
198
199
  if (disabled) return null;
199
200
  return callback;
200
201
  };
@@ -337,7 +338,9 @@ var ThreadViewport = (0, import_react13.forwardRef)(({ autoScroll = true, onScro
337
338
  if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {
338
339
  } else if (newIsAtBottom !== isAtBottom) {
339
340
  isScrollingToBottomRef.current = false;
340
- useViewport.setState({ isAtBottom: newIsAtBottom });
341
+ useViewport.setState({
342
+ isAtBottom: newIsAtBottom
343
+ });
341
344
  }
342
345
  lastScrollTop.current = div.scrollTop;
343
346
  };
@@ -361,7 +364,7 @@ var import_react16 = require("react");
361
364
 
362
365
  // src/context/providers/MessageProvider.tsx
363
366
  var import_react14 = require("react");
364
- var import_zustand2 = require("zustand");
367
+ var import_zustand3 = require("zustand");
365
368
 
366
369
  // src/context/stores/MessageComposer.ts
367
370
  var import_zustand = require("zustand");
@@ -397,17 +400,34 @@ var makeEditComposerStore = ({
397
400
  }
398
401
  }));
399
402
 
403
+ // src/context/stores/MessageUtils.ts
404
+ var import_zustand2 = require("zustand");
405
+ var makeMessageUtilsStore = () => (0, import_zustand2.create)((set) => ({
406
+ inProgressIndicator: null,
407
+ setInProgressIndicator: (value) => {
408
+ set({ inProgressIndicator: value });
409
+ },
410
+ isCopied: false,
411
+ setIsCopied: (value) => {
412
+ set({ isCopied: value });
413
+ },
414
+ isHovering: false,
415
+ setIsHovering: (value) => {
416
+ set({ isHovering: value });
417
+ }
418
+ }));
419
+
400
420
  // src/context/providers/MessageProvider.tsx
401
421
  var import_jsx_runtime4 = require("react/jsx-runtime");
402
422
  var getIsLast = (thread, message) => {
403
423
  return thread.messages[thread.messages.length - 1]?.id === message.id;
404
424
  };
405
- var syncMessage = (thread, useMessage, messageIndex) => {
425
+ var syncMessage = (thread, getBranches, useMessage, messageIndex) => {
406
426
  const parentId = thread.messages[messageIndex - 1]?.id ?? null;
407
427
  const message = thread.messages[messageIndex];
408
428
  if (!message) return;
409
429
  const isLast = getIsLast(thread, message);
410
- const branches = thread.getBranches(message.id);
430
+ const branches = getBranches(message.id);
411
431
  const currentState = useMessage.getState();
412
432
  if (currentState.message === message && currentState.parentId === parentId && currentState.branches === branches && currentState.isLast === isLast)
413
433
  return;
@@ -419,26 +439,10 @@ var syncMessage = (thread, useMessage, messageIndex) => {
419
439
  });
420
440
  };
421
441
  var useMessageContext2 = (messageIndex) => {
422
- const { useThread } = useThreadContext();
442
+ const { useThread, useThreadActions } = useThreadContext();
423
443
  const [context] = (0, import_react14.useState)(() => {
424
- const useMessage = (0, import_zustand2.create)((set) => ({
425
- message: null,
426
- parentId: null,
427
- branches: [],
428
- isLast: false,
429
- inProgressIndicator: null,
430
- isCopied: false,
431
- isHovering: false,
432
- setInProgressIndicator: (value) => {
433
- set({ inProgressIndicator: value });
434
- },
435
- setIsCopied: (value) => {
436
- set({ isCopied: value });
437
- },
438
- setIsHovering: (value) => {
439
- set({ isHovering: value });
440
- }
441
- }));
444
+ const useMessage = (0, import_zustand3.create)(() => ({}));
445
+ const useMessageUtils = makeMessageUtilsStore();
442
446
  const useComposer = makeEditComposerStore({
443
447
  onEdit: () => {
444
448
  const message = useMessage.getState().message;
@@ -458,20 +462,30 @@ var useMessageContext2 = (messageIndex) => {
458
462
  const nonTextParts = message.content.filter(
459
463
  (part) => part.type !== "text" && part.type !== "ui"
460
464
  );
461
- useThread.getState().append({
465
+ useThreadActions.getState().append({
462
466
  parentId,
463
467
  content: [{ type: "text", text }, ...nonTextParts]
464
468
  });
465
469
  }
466
470
  });
467
- syncMessage(useThread.getState(), useMessage, messageIndex);
468
- return { useMessage, useComposer };
471
+ syncMessage(
472
+ useThread.getState(),
473
+ useThreadActions.getState().getBranches,
474
+ useMessage,
475
+ messageIndex
476
+ );
477
+ return { useMessage, useMessageUtils, useComposer };
469
478
  });
470
479
  (0, import_react14.useEffect)(() => {
471
480
  return useThread.subscribe((thread) => {
472
- syncMessage(thread, context.useMessage, messageIndex);
481
+ syncMessage(
482
+ thread,
483
+ useThreadActions.getState().getBranches,
484
+ context.useMessage,
485
+ messageIndex
486
+ );
473
487
  });
474
- }, [context, useThread, messageIndex]);
488
+ }, [useThread, useThreadActions, context, messageIndex]);
475
489
  return context;
476
490
  };
477
491
  var MessageProvider = ({
@@ -512,16 +526,19 @@ var ComposerIf = ({ children, ...query }) => {
512
526
 
513
527
  // src/primitives/message/MessageIf.tsx
514
528
  var useMessageIf = (props) => {
515
- const { useMessage } = useMessageContext();
516
- return useMessage(({ message, branches, isLast, isCopied, isHovering }) => {
517
- if (props.hasBranches === true && branches.length < 2) return false;
518
- if (props.user && message.role !== "user") return false;
519
- if (props.assistant && message.role !== "assistant") return false;
520
- if (props.lastOrHover === true && !isHovering && !isLast) return false;
521
- if (props.copied === true && !isCopied) return false;
522
- if (props.copied === false && isCopied) return false;
523
- return true;
524
- });
529
+ const { useMessage, useMessageUtils } = useMessageContext();
530
+ return useCombinedStore(
531
+ [useMessage, useMessageUtils],
532
+ ({ message, branches, isLast }, { isCopied, isHovering }) => {
533
+ if (props.hasBranches === true && branches.length < 2) return false;
534
+ if (props.user && message.role !== "user") return false;
535
+ if (props.assistant && message.role !== "assistant") return false;
536
+ if (props.lastOrHover === true && !isHovering && !isLast) return false;
537
+ if (props.copied === true && !isCopied) return false;
538
+ if (props.copied === false && isCopied) return false;
539
+ return true;
540
+ }
541
+ );
525
542
  };
526
543
  var MessageIf = ({ children, ...query }) => {
527
544
  const result = useMessageIf(query);
@@ -792,8 +809,8 @@ var import_react23 = require("react");
792
809
  var import_jsx_runtime12 = require("react/jsx-runtime");
793
810
  var MessageRoot = (0, import_react23.forwardRef)(
794
811
  ({ onMouseEnter, onMouseLeave, ...rest }, ref) => {
795
- const { useMessage } = useMessageContext();
796
- const setIsHovering = useMessage((s) => s.setIsHovering);
812
+ const { useMessageUtils } = useMessageContext();
813
+ const setIsHovering = useMessageUtils((s) => s.setIsHovering);
797
814
  const handleMouseEnter = () => {
798
815
  setIsHovering(true);
799
816
  };
@@ -846,7 +863,7 @@ var useContentPartContext = () => {
846
863
 
847
864
  // src/context/providers/ContentPartProvider.tsx
848
865
  var import_react26 = require("react");
849
- var import_zustand3 = require("zustand");
866
+ var import_zustand4 = require("zustand");
850
867
  var import_jsx_runtime13 = require("react/jsx-runtime");
851
868
  var syncContentPart = ({ message }, useContentPart, partIndex) => {
852
869
  const part = message.content[partIndex];
@@ -855,19 +872,24 @@ var syncContentPart = ({ message }, useContentPart, partIndex) => {
855
872
  const status = partIndex === message.content.length - 1 ? messageStatus : "done";
856
873
  const currentState = useContentPart.getState();
857
874
  if (currentState.part === part && currentState.status === status) return;
858
- useContentPart.setState({ part, status });
875
+ useContentPart.setState(
876
+ Object.freeze({
877
+ part,
878
+ status
879
+ })
880
+ );
859
881
  };
860
882
  var useContentPartContext2 = (partIndex) => {
861
883
  const { useMessage } = useMessageContext();
862
884
  const [context] = (0, import_react26.useState)(() => {
863
- const useContentPart = (0, import_zustand3.create)(() => ({
864
- part: { type: "text", text: "" },
865
- status: "done"
866
- }));
885
+ const useContentPart = (0, import_zustand4.create)(
886
+ () => ({})
887
+ );
867
888
  syncContentPart(useMessage.getState(), useContentPart, partIndex);
868
889
  return { useContentPart };
869
890
  });
870
891
  (0, import_react26.useEffect)(() => {
892
+ syncContentPart(useMessage.getState(), context.useContentPart, partIndex);
871
893
  return useMessage.subscribe((message) => {
872
894
  syncContentPart(message, context.useContentPart, partIndex);
873
895
  });
@@ -897,10 +919,10 @@ var ContentPartDisplay = () => {
897
919
 
898
920
  // src/primitives/contentPart/ContentPartInProgressIndicator.tsx
899
921
  var ContentPartInProgressIndicator = () => {
900
- const { useMessage } = useMessageContext();
922
+ const { useMessageUtils } = useMessageContext();
901
923
  const { useContentPart } = useContentPartContext();
902
924
  const indicator = useCombinedStore(
903
- [useMessage, useContentPart],
925
+ [useMessageUtils, useContentPart],
904
926
  (m, c) => c.status === "in_progress" ? m.inProgressIndicator : null
905
927
  );
906
928
  return indicator;
@@ -949,8 +971,8 @@ var MessageContentPartComponent = ({
949
971
  tools: { by_name = {}, Fallback = defaultComponents.tools.Fallback } = {}
950
972
  } = {}
951
973
  }) => {
952
- const { useThread } = useThreadContext();
953
- const addToolResult = useThread((t) => t.addToolResult);
974
+ const { useThreadActions } = useThreadContext();
975
+ const addToolResult = useThreadActions((t) => t.addToolResult);
954
976
  const { useContentPart } = useContentPartContext();
955
977
  const { part, status } = useContentPart();
956
978
  const type = part.type;
@@ -1001,10 +1023,10 @@ var import_react_primitive10 = require("@radix-ui/react-primitive");
1001
1023
  var import_react29 = require("react");
1002
1024
  var import_jsx_runtime16 = require("react/jsx-runtime");
1003
1025
  var MessageInProgress = (0, import_react29.forwardRef)((props, ref) => {
1004
- const { useMessage } = useMessageContext();
1026
+ const { useMessageUtils } = useMessageContext();
1005
1027
  (0, import_react29.useMemo)(() => {
1006
- useMessage.getState().setInProgressIndicator(/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_primitive10.Primitive.span, { ...props, ref }));
1007
- }, [useMessage, props, ref]);
1028
+ useMessageUtils.getState().setInProgressIndicator(/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_primitive10.Primitive.span, { ...props, ref }));
1029
+ }, [useMessageUtils, props, ref]);
1008
1030
  return null;
1009
1031
  });
1010
1032
  MessageInProgress.displayName = "MessageInProgress";
@@ -1088,14 +1110,14 @@ var import_react32 = require("react");
1088
1110
  var import_jsx_runtime21 = require("react/jsx-runtime");
1089
1111
  var ActionBarRoot = (0, import_react32.forwardRef)(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
1090
1112
  const { useThread } = useThreadContext();
1091
- const { useMessage } = useMessageContext();
1113
+ const { useMessage, useMessageUtils } = useMessageContext();
1092
1114
  const hideAndfloatStatus = useCombinedStore(
1093
- [useThread, useMessage],
1094
- (t, m) => {
1115
+ [useThread, useMessage, useMessageUtils],
1116
+ (t, m, mu) => {
1095
1117
  if (hideWhenRunning && t.isRunning) return "hidden" /* Hidden */;
1096
1118
  const autohideEnabled = autohide === "always" || autohide === "not-last" && !m.isLast;
1097
1119
  if (!autohideEnabled) return "normal" /* Normal */;
1098
- if (!m.isHovering) return "hidden" /* Hidden */;
1120
+ if (!mu.isHovering) return "hidden" /* Hidden */;
1099
1121
  if (autohideFloat === "always" || autohideFloat === "single-branch" && m.branches.length <= 1)
1100
1122
  return "floating" /* Floating */;
1101
1123
  return "normal" /* Normal */;
@@ -1449,7 +1471,7 @@ var import_react37 = require("react");
1449
1471
  var import_react36 = require("react");
1450
1472
 
1451
1473
  // src/context/stores/AssistantModelConfig.ts
1452
- var import_zustand4 = require("zustand");
1474
+ var import_zustand5 = require("zustand");
1453
1475
 
1454
1476
  // src/utils/ProxyConfigProvider.ts
1455
1477
  var ProxyConfigProvider = class {
@@ -1466,23 +1488,23 @@ var ProxyConfigProvider = class {
1466
1488
  };
1467
1489
 
1468
1490
  // src/context/stores/AssistantModelConfig.ts
1469
- var makeAssistantModelConfigStore = () => (0, import_zustand4.create)(() => {
1491
+ var makeAssistantModelConfigStore = () => (0, import_zustand5.create)(() => {
1470
1492
  const proxy = new ProxyConfigProvider();
1471
- return {
1493
+ return Object.freeze({
1472
1494
  getModelConfig: () => {
1473
1495
  return proxy.getModelConfig();
1474
1496
  },
1475
1497
  registerModelConfigProvider: (provider) => {
1476
1498
  return proxy.registerModelConfigProvider(provider);
1477
1499
  }
1478
- };
1500
+ });
1479
1501
  });
1480
1502
 
1481
1503
  // src/context/stores/AssistantToolUIs.ts
1482
- var import_zustand5 = require("zustand");
1483
- var makeAssistantToolUIsStore = () => (0, import_zustand5.create)((set) => {
1504
+ var import_zustand6 = require("zustand");
1505
+ var makeAssistantToolUIsStore = () => (0, import_zustand6.create)((set) => {
1484
1506
  const renderers = /* @__PURE__ */ new Map();
1485
- return {
1507
+ return Object.freeze({
1486
1508
  getToolUI: (name) => {
1487
1509
  const arr = renderers.get(name);
1488
1510
  const last = arr?.at(-1);
@@ -1502,25 +1524,27 @@ var makeAssistantToolUIsStore = () => (0, import_zustand5.create)((set) => {
1502
1524
  if (index !== -1) {
1503
1525
  arr.splice(index, 1);
1504
1526
  }
1505
- set({});
1527
+ if (index === arr.length) {
1528
+ set({});
1529
+ }
1506
1530
  };
1507
1531
  }
1508
- };
1532
+ });
1509
1533
  });
1510
1534
 
1511
1535
  // src/context/providers/ThreadProvider.tsx
1512
1536
  var import_react35 = require("react");
1513
1537
 
1514
1538
  // src/context/stores/Composer.ts
1515
- var import_zustand6 = require("zustand");
1516
- var makeComposerStore = (useThread) => (0, import_zustand6.create)()((set, get, store) => {
1539
+ var import_zustand7 = require("zustand");
1540
+ var makeComposerStore = (useThread, useThreadActions) => (0, import_zustand7.create)()((set, get, store) => {
1517
1541
  return {
1518
1542
  ...makeBaseComposer(set, get, store),
1519
1543
  isEditing: true,
1520
1544
  send: () => {
1521
1545
  const { setValue, value } = get();
1522
1546
  setValue("");
1523
- useThread.getState().append({
1547
+ useThreadActions.getState().append({
1524
1548
  parentId: useThread.getState().messages.at(-1)?.id ?? null,
1525
1549
  content: [{ type: "text", text: value }]
1526
1550
  });
@@ -1528,42 +1552,26 @@ var makeComposerStore = (useThread) => (0, import_zustand6.create)()((set, get,
1528
1552
  cancel: () => {
1529
1553
  const thread = useThread.getState();
1530
1554
  if (!thread.isRunning) return false;
1531
- useThread.getState().cancelRun();
1555
+ useThreadActions.getState().cancelRun();
1532
1556
  return true;
1533
1557
  }
1534
1558
  };
1535
1559
  });
1536
1560
 
1537
1561
  // src/context/stores/Thread.ts
1538
- var import_zustand7 = require("zustand");
1562
+ var import_zustand8 = require("zustand");
1539
1563
  var makeThreadStore = (runtimeRef) => {
1540
- const useThread = (0, import_zustand7.create)(() => ({
1564
+ return (0, import_zustand8.create)(() => ({
1541
1565
  messages: runtimeRef.current.messages,
1542
- isRunning: runtimeRef.current.isRunning,
1543
- getBranches: (messageId) => runtimeRef.current.getBranches(messageId),
1544
- switchToBranch: (branchId) => runtimeRef.current.switchToBranch(branchId),
1545
- startRun: (parentId) => runtimeRef.current.startRun(parentId),
1546
- append: (message) => runtimeRef.current.append(message),
1547
- cancelRun: () => runtimeRef.current.cancelRun(),
1548
- addToolResult: (toolCallId, result) => runtimeRef.current.addToolResult(toolCallId, result)
1566
+ isRunning: runtimeRef.current.isRunning
1549
1567
  }));
1550
- const onRuntimeUpdate = () => {
1551
- useThread.setState({
1552
- messages: runtimeRef.current.messages,
1553
- isRunning: runtimeRef.current.isRunning
1554
- });
1555
- };
1556
- return {
1557
- useThread,
1558
- onRuntimeUpdate
1559
- };
1560
1568
  };
1561
1569
 
1562
1570
  // src/context/stores/ThreadViewport.tsx
1563
- var import_zustand8 = require("zustand");
1571
+ var import_zustand9 = require("zustand");
1564
1572
  var makeThreadViewportStore = () => {
1565
1573
  const scrollToBottomListeners = /* @__PURE__ */ new Set();
1566
- return (0, import_zustand8.create)(() => ({
1574
+ return (0, import_zustand9.create)(() => ({
1567
1575
  isAtBottom: true,
1568
1576
  scrollToBottom: () => {
1569
1577
  for (const listener of scrollToBottomListeners) {
@@ -1579,6 +1587,21 @@ var makeThreadViewportStore = () => {
1579
1587
  }));
1580
1588
  };
1581
1589
 
1590
+ // src/context/stores/ThreadActions.ts
1591
+ var import_zustand10 = require("zustand");
1592
+ var makeThreadActionStore = (runtimeRef) => {
1593
+ return (0, import_zustand10.create)(
1594
+ () => Object.freeze({
1595
+ getBranches: (messageId) => runtimeRef.current.getBranches(messageId),
1596
+ switchToBranch: (branchId) => runtimeRef.current.switchToBranch(branchId),
1597
+ startRun: (parentId) => runtimeRef.current.startRun(parentId),
1598
+ append: (message) => runtimeRef.current.append(message),
1599
+ cancelRun: () => runtimeRef.current.cancelRun(),
1600
+ addToolResult: (toolCallId, result) => runtimeRef.current.addToolResult(toolCallId, result)
1601
+ })
1602
+ );
1603
+ };
1604
+
1582
1605
  // src/context/providers/ThreadProvider.tsx
1583
1606
  var import_jsx_runtime23 = require("react/jsx-runtime");
1584
1607
  var ThreadProvider = ({
@@ -1589,23 +1612,31 @@ var ThreadProvider = ({
1589
1612
  (0, import_react35.useInsertionEffect)(() => {
1590
1613
  runtimeRef.current = runtime;
1591
1614
  });
1592
- const [{ context, onRuntimeUpdate }] = (0, import_react35.useState)(() => {
1593
- const { useThread, onRuntimeUpdate: onRuntimeUpdate2 } = makeThreadStore(runtimeRef);
1615
+ const [context] = (0, import_react35.useState)(() => {
1616
+ const useThread = makeThreadStore(runtimeRef);
1617
+ const useThreadActions = makeThreadActionStore(runtimeRef);
1594
1618
  const useViewport = makeThreadViewportStore();
1595
- const useComposer = makeComposerStore(useThread);
1619
+ const useComposer = makeComposerStore(useThread, useThreadActions);
1596
1620
  return {
1597
- context: {
1598
- useViewport,
1599
- useThread,
1600
- useComposer
1601
- },
1602
- onRuntimeUpdate: onRuntimeUpdate2
1621
+ useThread,
1622
+ useThreadActions,
1623
+ useComposer,
1624
+ useViewport
1603
1625
  };
1604
1626
  });
1605
1627
  (0, import_react35.useEffect)(() => {
1628
+ const onRuntimeUpdate = () => {
1629
+ context.useThread.setState(
1630
+ Object.freeze({
1631
+ messages: runtimeRef.current.messages,
1632
+ isRunning: runtimeRef.current.isRunning
1633
+ }),
1634
+ true
1635
+ );
1636
+ };
1606
1637
  onRuntimeUpdate();
1607
1638
  return runtime.subscribe(onRuntimeUpdate);
1608
- }, [onRuntimeUpdate, runtime]);
1639
+ }, [context, runtime]);
1609
1640
  const RuntimeSynchronizer = runtime.unstable_synchronizer;
1610
1641
  return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(ThreadContext.Provider, { value: context, children: [
1611
1642
  RuntimeSynchronizer && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(RuntimeSynchronizer, {}),