@assistant-ui/react 0.1.8 → 0.1.9

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