@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.mjs CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  useContentPartContext,
10
10
  useMessageContext,
11
11
  useThreadContext
12
- } from "./chunk-RITM2IUH.mjs";
12
+ } from "./chunk-7O2URLFI.mjs";
13
13
 
14
14
  // src/actions/useCopyMessage.tsx
15
15
  import { useCallback } from "react";
@@ -50,7 +50,7 @@ var getMessageText = (message) => {
50
50
 
51
51
  // src/actions/useCopyMessage.tsx
52
52
  var useCopyMessage = ({ copiedDuration = 3e3 }) => {
53
- const { useMessage, useComposer } = useMessageContext();
53
+ const { useMessage, useMessageUtils, useComposer } = useMessageContext();
54
54
  const hasCopyableContent = useCombinedStore(
55
55
  [useMessage, useComposer],
56
56
  (m, c) => {
@@ -58,13 +58,14 @@ var useCopyMessage = ({ copiedDuration = 3e3 }) => {
58
58
  }
59
59
  );
60
60
  const callback = useCallback(() => {
61
+ const { message } = useMessage.getState();
62
+ const { setIsCopied } = useMessageUtils.getState();
61
63
  const { isEditing, value: composerValue } = useComposer.getState();
62
- const { message, setIsCopied } = useMessage.getState();
63
64
  const valueToCopy = isEditing ? composerValue : getMessageText(message);
64
65
  navigator.clipboard.writeText(valueToCopy);
65
66
  setIsCopied(true);
66
67
  setTimeout(() => setIsCopied(false), copiedDuration);
67
- }, [useComposer, useMessage, copiedDuration]);
68
+ }, [useMessage, useMessageUtils, useComposer, copiedDuration]);
68
69
  if (!hasCopyableContent) return null;
69
70
  return callback;
70
71
  };
@@ -72,7 +73,7 @@ var useCopyMessage = ({ copiedDuration = 3e3 }) => {
72
73
  // src/actions/useReloadMessage.tsx
73
74
  import { useCallback as useCallback2 } from "react";
74
75
  var useReloadMessage = () => {
75
- const { useThread, useViewport } = useThreadContext();
76
+ const { useThread, useThreadActions, useViewport } = useThreadContext();
76
77
  const { useMessage } = useMessageContext();
77
78
  const disabled = useCombinedStore(
78
79
  [useThread, useMessage],
@@ -80,9 +81,9 @@ var useReloadMessage = () => {
80
81
  );
81
82
  const callback = useCallback2(() => {
82
83
  const { parentId } = useMessage.getState();
83
- useThread.getState().startRun(parentId);
84
+ useThreadActions.getState().startRun(parentId);
84
85
  useViewport.getState().scrollToBottom();
85
- }, [useMessage, useThread, useViewport]);
86
+ }, [useThreadActions, useMessage, useViewport]);
86
87
  if (disabled) return null;
87
88
  return callback;
88
89
  };
@@ -106,7 +107,7 @@ var useBeginMessageEdit = () => {
106
107
  // src/actions/useGoToNextBranch.tsx
107
108
  import { useCallback as useCallback4 } from "react";
108
109
  var useGoToNextBranch = () => {
109
- const { useThread } = useThreadContext();
110
+ const { useThreadActions } = useThreadContext();
110
111
  const { useMessage, useComposer } = useMessageContext();
111
112
  const disabled = useCombinedStore(
112
113
  [useMessage, useComposer],
@@ -114,8 +115,8 @@ var useGoToNextBranch = () => {
114
115
  );
115
116
  const callback = useCallback4(() => {
116
117
  const { message, branches } = useMessage.getState();
117
- useThread.getState().switchToBranch(branches[branches.indexOf(message.id) + 1]);
118
- }, [useMessage, useThread]);
118
+ useThreadActions.getState().switchToBranch(branches[branches.indexOf(message.id) + 1]);
119
+ }, [useThreadActions, useMessage]);
119
120
  if (disabled) return null;
120
121
  return callback;
121
122
  };
@@ -123,7 +124,7 @@ var useGoToNextBranch = () => {
123
124
  // src/actions/useGoToPreviousBranch.tsx
124
125
  import { useCallback as useCallback5 } from "react";
125
126
  var useGoToPreviousBranch = () => {
126
- const { useThread } = useThreadContext();
127
+ const { useThreadActions } = useThreadContext();
127
128
  const { useMessage, useComposer } = useMessageContext();
128
129
  const disabled = useCombinedStore(
129
130
  [useMessage, useComposer],
@@ -131,8 +132,8 @@ var useGoToPreviousBranch = () => {
131
132
  );
132
133
  const callback = useCallback5(() => {
133
134
  const { message, branches } = useMessage.getState();
134
- useThread.getState().switchToBranch(branches[branches.indexOf(message.id) - 1]);
135
- }, [useMessage, useThread]);
135
+ useThreadActions.getState().switchToBranch(branches[branches.indexOf(message.id) - 1]);
136
+ }, [useThreadActions, useMessage]);
136
137
  if (disabled) return null;
137
138
  return callback;
138
139
  };
@@ -278,7 +279,9 @@ var ThreadViewport = forwardRef2(({ autoScroll = true, onScroll, children, ...re
278
279
  if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {
279
280
  } else if (newIsAtBottom !== isAtBottom) {
280
281
  isScrollingToBottomRef.current = false;
281
- useViewport.setState({ isAtBottom: newIsAtBottom });
282
+ useViewport.setState({
283
+ isAtBottom: newIsAtBottom
284
+ });
282
285
  }
283
286
  lastScrollTop.current = div.scrollTop;
284
287
  };
@@ -302,7 +305,7 @@ import { memo } from "react";
302
305
 
303
306
  // src/context/providers/MessageProvider.tsx
304
307
  import { useEffect as useEffect3, useState } from "react";
305
- import { create as create2 } from "zustand";
308
+ import { create as create3 } from "zustand";
306
309
 
307
310
  // src/context/stores/MessageComposer.ts
308
311
  import { create } from "zustand";
@@ -338,17 +341,34 @@ var makeEditComposerStore = ({
338
341
  }
339
342
  }));
340
343
 
344
+ // src/context/stores/MessageUtils.ts
345
+ import { create as create2 } from "zustand";
346
+ var makeMessageUtilsStore = () => create2((set) => ({
347
+ inProgressIndicator: null,
348
+ setInProgressIndicator: (value) => {
349
+ set({ inProgressIndicator: value });
350
+ },
351
+ isCopied: false,
352
+ setIsCopied: (value) => {
353
+ set({ isCopied: value });
354
+ },
355
+ isHovering: false,
356
+ setIsHovering: (value) => {
357
+ set({ isHovering: value });
358
+ }
359
+ }));
360
+
341
361
  // src/context/providers/MessageProvider.tsx
342
362
  import { jsx as jsx4 } from "react/jsx-runtime";
343
363
  var getIsLast = (thread, message) => {
344
364
  return thread.messages[thread.messages.length - 1]?.id === message.id;
345
365
  };
346
- var syncMessage = (thread, useMessage, messageIndex) => {
366
+ var syncMessage = (thread, getBranches, useMessage, messageIndex) => {
347
367
  const parentId = thread.messages[messageIndex - 1]?.id ?? null;
348
368
  const message = thread.messages[messageIndex];
349
369
  if (!message) return;
350
370
  const isLast = getIsLast(thread, message);
351
- const branches = thread.getBranches(message.id);
371
+ const branches = getBranches(message.id);
352
372
  const currentState = useMessage.getState();
353
373
  if (currentState.message === message && currentState.parentId === parentId && currentState.branches === branches && currentState.isLast === isLast)
354
374
  return;
@@ -360,26 +380,10 @@ var syncMessage = (thread, useMessage, messageIndex) => {
360
380
  });
361
381
  };
362
382
  var useMessageContext2 = (messageIndex) => {
363
- const { useThread } = useThreadContext();
383
+ const { useThread, useThreadActions } = useThreadContext();
364
384
  const [context] = useState(() => {
365
- const useMessage = create2((set) => ({
366
- message: null,
367
- parentId: null,
368
- branches: [],
369
- isLast: false,
370
- inProgressIndicator: null,
371
- isCopied: false,
372
- isHovering: false,
373
- setInProgressIndicator: (value) => {
374
- set({ inProgressIndicator: value });
375
- },
376
- setIsCopied: (value) => {
377
- set({ isCopied: value });
378
- },
379
- setIsHovering: (value) => {
380
- set({ isHovering: value });
381
- }
382
- }));
385
+ const useMessage = create3(() => ({}));
386
+ const useMessageUtils = makeMessageUtilsStore();
383
387
  const useComposer = makeEditComposerStore({
384
388
  onEdit: () => {
385
389
  const message = useMessage.getState().message;
@@ -399,20 +403,30 @@ var useMessageContext2 = (messageIndex) => {
399
403
  const nonTextParts = message.content.filter(
400
404
  (part) => part.type !== "text" && part.type !== "ui"
401
405
  );
402
- useThread.getState().append({
406
+ useThreadActions.getState().append({
403
407
  parentId,
404
408
  content: [{ type: "text", text }, ...nonTextParts]
405
409
  });
406
410
  }
407
411
  });
408
- syncMessage(useThread.getState(), useMessage, messageIndex);
409
- return { useMessage, useComposer };
412
+ syncMessage(
413
+ useThread.getState(),
414
+ useThreadActions.getState().getBranches,
415
+ useMessage,
416
+ messageIndex
417
+ );
418
+ return { useMessage, useMessageUtils, useComposer };
410
419
  });
411
420
  useEffect3(() => {
412
421
  return useThread.subscribe((thread) => {
413
- syncMessage(thread, context.useMessage, messageIndex);
422
+ syncMessage(
423
+ thread,
424
+ useThreadActions.getState().getBranches,
425
+ context.useMessage,
426
+ messageIndex
427
+ );
414
428
  });
415
- }, [context, useThread, messageIndex]);
429
+ }, [useThread, useThreadActions, context, messageIndex]);
416
430
  return context;
417
431
  };
418
432
  var MessageProvider = ({
@@ -439,16 +453,19 @@ var ComposerIf = ({ children, ...query }) => {
439
453
 
440
454
  // src/primitives/message/MessageIf.tsx
441
455
  var useMessageIf = (props) => {
442
- const { useMessage } = useMessageContext();
443
- return useMessage(({ message, branches, isLast, isCopied, isHovering }) => {
444
- if (props.hasBranches === true && branches.length < 2) return false;
445
- if (props.user && message.role !== "user") return false;
446
- if (props.assistant && message.role !== "assistant") return false;
447
- if (props.lastOrHover === true && !isHovering && !isLast) return false;
448
- if (props.copied === true && !isCopied) return false;
449
- if (props.copied === false && isCopied) return false;
450
- return true;
451
- });
456
+ const { useMessage, useMessageUtils } = useMessageContext();
457
+ return useCombinedStore(
458
+ [useMessage, useMessageUtils],
459
+ ({ message, branches, isLast }, { isCopied, isHovering }) => {
460
+ if (props.hasBranches === true && branches.length < 2) return false;
461
+ if (props.user && message.role !== "user") return false;
462
+ if (props.assistant && message.role !== "assistant") return false;
463
+ if (props.lastOrHover === true && !isHovering && !isLast) return false;
464
+ if (props.copied === true && !isCopied) return false;
465
+ if (props.copied === false && isCopied) return false;
466
+ return true;
467
+ }
468
+ );
452
469
  };
453
470
  var MessageIf = ({ children, ...query }) => {
454
471
  const result = useMessageIf(query);
@@ -727,8 +744,8 @@ import { forwardRef as forwardRef9 } from "react";
727
744
  import { jsx as jsx12 } from "react/jsx-runtime";
728
745
  var MessageRoot = forwardRef9(
729
746
  ({ onMouseEnter, onMouseLeave, ...rest }, ref) => {
730
- const { useMessage } = useMessageContext();
731
- const setIsHovering = useMessage((s) => s.setIsHovering);
747
+ const { useMessageUtils } = useMessageContext();
748
+ const setIsHovering = useMessageUtils((s) => s.setIsHovering);
732
749
  const handleMouseEnter = () => {
733
750
  setIsHovering(true);
734
751
  };
@@ -753,7 +770,7 @@ import { memo as memo2 } from "react";
753
770
 
754
771
  // src/context/providers/ContentPartProvider.tsx
755
772
  import { useEffect as useEffect5, useState as useState2 } from "react";
756
- import { create as create3 } from "zustand";
773
+ import { create as create4 } from "zustand";
757
774
  import { jsx as jsx13 } from "react/jsx-runtime";
758
775
  var syncContentPart = ({ message }, useContentPart, partIndex) => {
759
776
  const part = message.content[partIndex];
@@ -762,19 +779,24 @@ var syncContentPart = ({ message }, useContentPart, partIndex) => {
762
779
  const status = partIndex === message.content.length - 1 ? messageStatus : "done";
763
780
  const currentState = useContentPart.getState();
764
781
  if (currentState.part === part && currentState.status === status) return;
765
- useContentPart.setState({ part, status });
782
+ useContentPart.setState(
783
+ Object.freeze({
784
+ part,
785
+ status
786
+ })
787
+ );
766
788
  };
767
789
  var useContentPartContext2 = (partIndex) => {
768
790
  const { useMessage } = useMessageContext();
769
791
  const [context] = useState2(() => {
770
- const useContentPart = create3(() => ({
771
- part: { type: "text", text: "" },
772
- status: "done"
773
- }));
792
+ const useContentPart = create4(
793
+ () => ({})
794
+ );
774
795
  syncContentPart(useMessage.getState(), useContentPart, partIndex);
775
796
  return { useContentPart };
776
797
  });
777
798
  useEffect5(() => {
799
+ syncContentPart(useMessage.getState(), context.useContentPart, partIndex);
778
800
  return useMessage.subscribe((message) => {
779
801
  syncContentPart(message, context.useContentPart, partIndex);
780
802
  });
@@ -804,10 +826,10 @@ var ContentPartDisplay = () => {
804
826
 
805
827
  // src/primitives/contentPart/ContentPartInProgressIndicator.tsx
806
828
  var ContentPartInProgressIndicator = () => {
807
- const { useMessage } = useMessageContext();
829
+ const { useMessageUtils } = useMessageContext();
808
830
  const { useContentPart } = useContentPartContext();
809
831
  const indicator = useCombinedStore(
810
- [useMessage, useContentPart],
832
+ [useMessageUtils, useContentPart],
811
833
  (m, c) => c.status === "in_progress" ? m.inProgressIndicator : null
812
834
  );
813
835
  return indicator;
@@ -856,8 +878,8 @@ var MessageContentPartComponent = ({
856
878
  tools: { by_name = {}, Fallback = defaultComponents.tools.Fallback } = {}
857
879
  } = {}
858
880
  }) => {
859
- const { useThread } = useThreadContext();
860
- const addToolResult = useThread((t) => t.addToolResult);
881
+ const { useThreadActions } = useThreadContext();
882
+ const addToolResult = useThreadActions((t) => t.addToolResult);
861
883
  const { useContentPart } = useContentPartContext();
862
884
  const { part, status } = useContentPart();
863
885
  const type = part.type;
@@ -911,10 +933,10 @@ import {
911
933
  } from "react";
912
934
  import { jsx as jsx16 } from "react/jsx-runtime";
913
935
  var MessageInProgress = forwardRef11((props, ref) => {
914
- const { useMessage } = useMessageContext();
936
+ const { useMessageUtils } = useMessageContext();
915
937
  useMemo2(() => {
916
- useMessage.getState().setInProgressIndicator(/* @__PURE__ */ jsx16(Primitive10.span, { ...props, ref }));
917
- }, [useMessage, props, ref]);
938
+ useMessageUtils.getState().setInProgressIndicator(/* @__PURE__ */ jsx16(Primitive10.span, { ...props, ref }));
939
+ }, [useMessageUtils, props, ref]);
918
940
  return null;
919
941
  });
920
942
  MessageInProgress.displayName = "MessageInProgress";
@@ -998,14 +1020,14 @@ import { forwardRef as forwardRef14 } from "react";
998
1020
  import { jsx as jsx21 } from "react/jsx-runtime";
999
1021
  var ActionBarRoot = forwardRef14(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
1000
1022
  const { useThread } = useThreadContext();
1001
- const { useMessage } = useMessageContext();
1023
+ const { useMessage, useMessageUtils } = useMessageContext();
1002
1024
  const hideAndfloatStatus = useCombinedStore(
1003
- [useThread, useMessage],
1004
- (t, m) => {
1025
+ [useThread, useMessage, useMessageUtils],
1026
+ (t, m, mu) => {
1005
1027
  if (hideWhenRunning && t.isRunning) return "hidden" /* Hidden */;
1006
1028
  const autohideEnabled = autohide === "always" || autohide === "not-last" && !m.isLast;
1007
1029
  if (!autohideEnabled) return "normal" /* Normal */;
1008
- if (!m.isHovering) return "hidden" /* Hidden */;
1030
+ if (!mu.isHovering) return "hidden" /* Hidden */;
1009
1031
  if (autohideFloat === "always" || autohideFloat === "single-branch" && m.branches.length <= 1)
1010
1032
  return "floating" /* Floating */;
1011
1033
  return "normal" /* Normal */;
@@ -1359,7 +1381,7 @@ import { memo as memo3 } from "react";
1359
1381
  import { useEffect as useEffect7, useInsertionEffect as useInsertionEffect3, useRef as useRef5, useState as useState5 } from "react";
1360
1382
 
1361
1383
  // src/context/stores/AssistantModelConfig.ts
1362
- import { create as create4 } from "zustand";
1384
+ import { create as create5 } from "zustand";
1363
1385
 
1364
1386
  // src/utils/ProxyConfigProvider.ts
1365
1387
  var ProxyConfigProvider = class {
@@ -1376,23 +1398,23 @@ var ProxyConfigProvider = class {
1376
1398
  };
1377
1399
 
1378
1400
  // src/context/stores/AssistantModelConfig.ts
1379
- var makeAssistantModelConfigStore = () => create4(() => {
1401
+ var makeAssistantModelConfigStore = () => create5(() => {
1380
1402
  const proxy = new ProxyConfigProvider();
1381
- return {
1403
+ return Object.freeze({
1382
1404
  getModelConfig: () => {
1383
1405
  return proxy.getModelConfig();
1384
1406
  },
1385
1407
  registerModelConfigProvider: (provider) => {
1386
1408
  return proxy.registerModelConfigProvider(provider);
1387
1409
  }
1388
- };
1410
+ });
1389
1411
  });
1390
1412
 
1391
1413
  // src/context/stores/AssistantToolUIs.ts
1392
- import { create as create5 } from "zustand";
1393
- var makeAssistantToolUIsStore = () => create5((set) => {
1414
+ import { create as create6 } from "zustand";
1415
+ var makeAssistantToolUIsStore = () => create6((set) => {
1394
1416
  const renderers = /* @__PURE__ */ new Map();
1395
- return {
1417
+ return Object.freeze({
1396
1418
  getToolUI: (name) => {
1397
1419
  const arr = renderers.get(name);
1398
1420
  const last = arr?.at(-1);
@@ -1412,25 +1434,27 @@ var makeAssistantToolUIsStore = () => create5((set) => {
1412
1434
  if (index !== -1) {
1413
1435
  arr.splice(index, 1);
1414
1436
  }
1415
- set({});
1437
+ if (index === arr.length) {
1438
+ set({});
1439
+ }
1416
1440
  };
1417
1441
  }
1418
- };
1442
+ });
1419
1443
  });
1420
1444
 
1421
1445
  // src/context/providers/ThreadProvider.tsx
1422
1446
  import { useEffect as useEffect6, useInsertionEffect as useInsertionEffect2, useRef as useRef4, useState as useState4 } from "react";
1423
1447
 
1424
1448
  // src/context/stores/Composer.ts
1425
- import { create as create6 } from "zustand";
1426
- var makeComposerStore = (useThread) => create6()((set, get, store) => {
1449
+ import { create as create7 } from "zustand";
1450
+ var makeComposerStore = (useThread, useThreadActions) => create7()((set, get, store) => {
1427
1451
  return {
1428
1452
  ...makeBaseComposer(set, get, store),
1429
1453
  isEditing: true,
1430
1454
  send: () => {
1431
1455
  const { setValue, value } = get();
1432
1456
  setValue("");
1433
- useThread.getState().append({
1457
+ useThreadActions.getState().append({
1434
1458
  parentId: useThread.getState().messages.at(-1)?.id ?? null,
1435
1459
  content: [{ type: "text", text: value }]
1436
1460
  });
@@ -1438,42 +1462,26 @@ var makeComposerStore = (useThread) => create6()((set, get, store) => {
1438
1462
  cancel: () => {
1439
1463
  const thread = useThread.getState();
1440
1464
  if (!thread.isRunning) return false;
1441
- useThread.getState().cancelRun();
1465
+ useThreadActions.getState().cancelRun();
1442
1466
  return true;
1443
1467
  }
1444
1468
  };
1445
1469
  });
1446
1470
 
1447
1471
  // src/context/stores/Thread.ts
1448
- import { create as create7 } from "zustand";
1472
+ import { create as create8 } from "zustand";
1449
1473
  var makeThreadStore = (runtimeRef) => {
1450
- const useThread = create7(() => ({
1474
+ return create8(() => ({
1451
1475
  messages: runtimeRef.current.messages,
1452
- isRunning: runtimeRef.current.isRunning,
1453
- getBranches: (messageId) => runtimeRef.current.getBranches(messageId),
1454
- switchToBranch: (branchId) => runtimeRef.current.switchToBranch(branchId),
1455
- startRun: (parentId) => runtimeRef.current.startRun(parentId),
1456
- append: (message) => runtimeRef.current.append(message),
1457
- cancelRun: () => runtimeRef.current.cancelRun(),
1458
- addToolResult: (toolCallId, result) => runtimeRef.current.addToolResult(toolCallId, result)
1476
+ isRunning: runtimeRef.current.isRunning
1459
1477
  }));
1460
- const onRuntimeUpdate = () => {
1461
- useThread.setState({
1462
- messages: runtimeRef.current.messages,
1463
- isRunning: runtimeRef.current.isRunning
1464
- });
1465
- };
1466
- return {
1467
- useThread,
1468
- onRuntimeUpdate
1469
- };
1470
1478
  };
1471
1479
 
1472
1480
  // src/context/stores/ThreadViewport.tsx
1473
- import { create as create8 } from "zustand";
1481
+ import { create as create9 } from "zustand";
1474
1482
  var makeThreadViewportStore = () => {
1475
1483
  const scrollToBottomListeners = /* @__PURE__ */ new Set();
1476
- return create8(() => ({
1484
+ return create9(() => ({
1477
1485
  isAtBottom: true,
1478
1486
  scrollToBottom: () => {
1479
1487
  for (const listener of scrollToBottomListeners) {
@@ -1489,6 +1497,21 @@ var makeThreadViewportStore = () => {
1489
1497
  }));
1490
1498
  };
1491
1499
 
1500
+ // src/context/stores/ThreadActions.ts
1501
+ import { create as create10 } from "zustand";
1502
+ var makeThreadActionStore = (runtimeRef) => {
1503
+ return create10(
1504
+ () => Object.freeze({
1505
+ getBranches: (messageId) => runtimeRef.current.getBranches(messageId),
1506
+ switchToBranch: (branchId) => runtimeRef.current.switchToBranch(branchId),
1507
+ startRun: (parentId) => runtimeRef.current.startRun(parentId),
1508
+ append: (message) => runtimeRef.current.append(message),
1509
+ cancelRun: () => runtimeRef.current.cancelRun(),
1510
+ addToolResult: (toolCallId, result) => runtimeRef.current.addToolResult(toolCallId, result)
1511
+ })
1512
+ );
1513
+ };
1514
+
1492
1515
  // src/context/providers/ThreadProvider.tsx
1493
1516
  import { jsx as jsx23, jsxs as jsxs4 } from "react/jsx-runtime";
1494
1517
  var ThreadProvider = ({
@@ -1499,23 +1522,31 @@ var ThreadProvider = ({
1499
1522
  useInsertionEffect2(() => {
1500
1523
  runtimeRef.current = runtime;
1501
1524
  });
1502
- const [{ context, onRuntimeUpdate }] = useState4(() => {
1503
- const { useThread, onRuntimeUpdate: onRuntimeUpdate2 } = makeThreadStore(runtimeRef);
1525
+ const [context] = useState4(() => {
1526
+ const useThread = makeThreadStore(runtimeRef);
1527
+ const useThreadActions = makeThreadActionStore(runtimeRef);
1504
1528
  const useViewport = makeThreadViewportStore();
1505
- const useComposer = makeComposerStore(useThread);
1529
+ const useComposer = makeComposerStore(useThread, useThreadActions);
1506
1530
  return {
1507
- context: {
1508
- useViewport,
1509
- useThread,
1510
- useComposer
1511
- },
1512
- onRuntimeUpdate: onRuntimeUpdate2
1531
+ useThread,
1532
+ useThreadActions,
1533
+ useComposer,
1534
+ useViewport
1513
1535
  };
1514
1536
  });
1515
1537
  useEffect6(() => {
1538
+ const onRuntimeUpdate = () => {
1539
+ context.useThread.setState(
1540
+ Object.freeze({
1541
+ messages: runtimeRef.current.messages,
1542
+ isRunning: runtimeRef.current.isRunning
1543
+ }),
1544
+ true
1545
+ );
1546
+ };
1516
1547
  onRuntimeUpdate();
1517
1548
  return runtime.subscribe(onRuntimeUpdate);
1518
- }, [onRuntimeUpdate, runtime]);
1549
+ }, [context, runtime]);
1519
1550
  const RuntimeSynchronizer = runtime.unstable_synchronizer;
1520
1551
  return /* @__PURE__ */ jsxs4(ThreadContext.Provider, { value: context, children: [
1521
1552
  RuntimeSynchronizer && /* @__PURE__ */ jsx23(RuntimeSynchronizer, {}),