@assistant-ui/react 0.5.41 → 0.5.42

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
@@ -1072,54 +1072,6 @@ var useEdgeRuntime = ({
1072
1072
  // src/runtimes/local/shouldContinue.tsx
1073
1073
  var shouldContinue = (result) => _optionalChain([result, 'access', _33 => _33.status, 'optionalAccess', _34 => _34.type]) === "requires-action" && result.status.reason === "tool-calls" && result.content.every((c) => c.type !== "tool-call" || !!c.result);
1074
1074
 
1075
- // src/utils/getThreadMessageText.tsx
1076
- var getThreadMessageText = (message) => {
1077
- const textParts = message.content.filter(
1078
- (part) => part.type === "text"
1079
- );
1080
- return textParts.map((part) => part.text).join("\n\n");
1081
- };
1082
-
1083
- // src/runtimes/speech/WebSpeechSynthesisAdapter.ts
1084
- var WebSpeechSynthesisAdapter = class {
1085
- speak(message) {
1086
- const text = getThreadMessageText(message);
1087
- const utterance = new SpeechSynthesisUtterance(text);
1088
- let ended = false;
1089
- const endHandlers = /* @__PURE__ */ new Set();
1090
- const handleEnd = () => {
1091
- if (ended) return;
1092
- ended = true;
1093
- endHandlers.forEach((handler) => handler());
1094
- };
1095
- utterance.addEventListener("end", handleEnd);
1096
- utterance.addEventListener("error", handleEnd);
1097
- window.speechSynthesis.speak(utterance);
1098
- return {
1099
- stop: () => {
1100
- window.speechSynthesis.cancel();
1101
- handleEnd();
1102
- },
1103
- onEnd: (callback) => {
1104
- if (ended) {
1105
- let cancelled = false;
1106
- queueMicrotask(() => {
1107
- if (!cancelled) callback();
1108
- });
1109
- return () => {
1110
- cancelled = true;
1111
- };
1112
- } else {
1113
- endHandlers.add(callback);
1114
- return () => {
1115
- endHandlers.delete(callback);
1116
- };
1117
- }
1118
- }
1119
- };
1120
- }
1121
- };
1122
-
1123
1075
  // src/runtimes/local/LocalThreadRuntime.tsx
1124
1076
  var LocalThreadRuntime = (_class5 = class {
1125
1077
  constructor(configProvider, adapter, { initialMessages, ...options }) {;_class5.prototype.__init11.call(this);_class5.prototype.__init12.call(this);_class5.prototype.__init13.call(this);_class5.prototype.__init14.call(this);_class5.prototype.__init15.call(this);_class5.prototype.__init16.call(this);
@@ -1158,6 +1110,9 @@ var LocalThreadRuntime = (_class5 = class {
1158
1110
  }
1159
1111
  }}
1160
1112
 
1113
+ get options() {
1114
+ return this._options;
1115
+ }
1161
1116
  set options({ initialMessages, ...options }) {
1162
1117
  this._options = options;
1163
1118
  const canSpeak = _optionalChain([options, 'access', _35 => _35.adapters, 'optionalAccess', _36 => _36.speech]) !== void 0;
@@ -1239,7 +1194,7 @@ var LocalThreadRuntime = (_class5 = class {
1239
1194
  this.repository.addOrUpdateMessage(parentId, message);
1240
1195
  this.notifySubscribers();
1241
1196
  };
1242
- const maxToolRoundtrips = _nullishCoalesce(this._options.maxToolRoundtrips, () => ( 1));
1197
+ const maxToolRoundtrips = _nullishCoalesce(this.options.maxToolRoundtrips, () => ( 1));
1243
1198
  const toolRoundtrips = _nullishCoalesce(_optionalChain([message, 'access', _48 => _48.metadata, 'optionalAccess', _49 => _49.roundtrips, 'optionalAccess', _50 => _50.length]), () => ( 0));
1244
1199
  if (toolRoundtrips > maxToolRoundtrips) {
1245
1200
  updateMessage({
@@ -1334,10 +1289,24 @@ var LocalThreadRuntime = (_class5 = class {
1334
1289
  this.performRoundtrip(parentId, message);
1335
1290
  }
1336
1291
  }
1292
+ // TODO lift utterance state to thread runtime
1293
+
1337
1294
  speak(messageId) {
1295
+ const adapter = _optionalChain([this, 'access', _51 => _51.options, 'access', _52 => _52.adapters, 'optionalAccess', _53 => _53.speech]);
1296
+ if (!adapter) throw new Error("Speech adapter not configured");
1338
1297
  const { message } = this.repository.getMessage(messageId);
1339
- const adapter = new WebSpeechSynthesisAdapter();
1340
- return adapter.speak(message);
1298
+ if (this._utterance) {
1299
+ this._utterance.cancel();
1300
+ this._utterance = void 0;
1301
+ }
1302
+ const utterance = adapter.speak(message);
1303
+ utterance.onEnd(() => {
1304
+ if (this._utterance === utterance) {
1305
+ this._utterance = void 0;
1306
+ }
1307
+ });
1308
+ this._utterance = utterance;
1309
+ return this._utterance;
1341
1310
  }
1342
1311
  export() {
1343
1312
  return this.repository.export();
@@ -1384,7 +1353,7 @@ var LocalRuntime = class extends BaseAssistantRuntime {
1384
1353
  const messages = fromCoreMessages(initialMessages);
1385
1354
  this.thread.import({
1386
1355
  messages: messages.map((m, idx) => ({
1387
- parentId: _nullishCoalesce(_optionalChain([messages, 'access', _51 => _51[idx - 1], 'optionalAccess', _52 => _52.id]), () => ( null)),
1356
+ parentId: _nullishCoalesce(_optionalChain([messages, 'access', _54 => _54[idx - 1], 'optionalAccess', _55 => _55.id]), () => ( null)),
1388
1357
  message: m
1389
1358
  }))
1390
1359
  });
@@ -1497,9 +1466,17 @@ var fromThreadMessageLike = (like, fallbackId, fallbackStatus) => {
1497
1466
  }
1498
1467
  };
1499
1468
 
1469
+ // src/utils/getThreadMessageText.tsx
1470
+ var getThreadMessageText = (message) => {
1471
+ const textParts = message.content.filter(
1472
+ (part) => part.type === "text"
1473
+ );
1474
+ return textParts.map((part) => part.text).join("\n\n");
1475
+ };
1476
+
1500
1477
  // src/runtimes/external-store/ExternalStoreThreadRuntime.tsx
1501
1478
  var hasUpcomingMessage = (isRunning, messages) => {
1502
- return isRunning && _optionalChain([messages, 'access', _53 => _53[messages.length - 1], 'optionalAccess', _54 => _54.role]) !== "assistant";
1479
+ return isRunning && _optionalChain([messages, 'access', _56 => _56[messages.length - 1], 'optionalAccess', _57 => _57.role]) !== "assistant";
1503
1480
  };
1504
1481
  var ExternalStoreThreadRuntime = (_class7 = class {
1505
1482
  __init18() {this._subscriptions = /* @__PURE__ */ new Set()}
@@ -1541,7 +1518,7 @@ var ExternalStoreThreadRuntime = (_class7 = class {
1541
1518
  edit: this._store.onEdit !== void 0,
1542
1519
  reload: this._store.onReload !== void 0,
1543
1520
  cancel: this._store.onCancel !== void 0,
1544
- unstable_copy: _optionalChain([this, 'access', _58 => _58._store, 'access', _59 => _59.unstable_capabilities, 'optionalAccess', _60 => _60.copy]) !== null,
1521
+ unstable_copy: _optionalChain([this, 'access', _61 => _61._store, 'access', _62 => _62.unstable_capabilities, 'optionalAccess', _63 => _63.copy]) !== null,
1545
1522
  speak: this._store.onSpeak !== void 0
1546
1523
  };
1547
1524
  if (oldStore) {
@@ -1569,7 +1546,7 @@ var ExternalStoreThreadRuntime = (_class7 = class {
1569
1546
  for (let i = 0; i < messages.length; i++) {
1570
1547
  const message = messages[i];
1571
1548
  const parent = messages[i - 1];
1572
- this.repository.addOrUpdateMessage(_nullishCoalesce(_optionalChain([parent, 'optionalAccess', _61 => _61.id]), () => ( null)), message);
1549
+ this.repository.addOrUpdateMessage(_nullishCoalesce(_optionalChain([parent, 'optionalAccess', _64 => _64.id]), () => ( null)), message);
1573
1550
  }
1574
1551
  if (this.assistantOptimisticId) {
1575
1552
  this.repository.deleteMessage(this.assistantOptimisticId);
@@ -1577,7 +1554,7 @@ var ExternalStoreThreadRuntime = (_class7 = class {
1577
1554
  }
1578
1555
  if (hasUpcomingMessage(isRunning, messages)) {
1579
1556
  this.assistantOptimisticId = this.repository.appendOptimisticMessage(
1580
- _nullishCoalesce(_optionalChain([messages, 'access', _62 => _62.at, 'call', _63 => _63(-1), 'optionalAccess', _64 => _64.id]), () => ( null)),
1557
+ _nullishCoalesce(_optionalChain([messages, 'access', _65 => _65.at, 'call', _66 => _66(-1), 'optionalAccess', _67 => _67.id]), () => ( null)),
1581
1558
  {
1582
1559
  role: "assistant",
1583
1560
  content: []
@@ -1585,7 +1562,7 @@ var ExternalStoreThreadRuntime = (_class7 = class {
1585
1562
  );
1586
1563
  }
1587
1564
  this.repository.resetHead(
1588
- _nullishCoalesce(_nullishCoalesce(this.assistantOptimisticId, () => ( _optionalChain([messages, 'access', _65 => _65.at, 'call', _66 => _66(-1), 'optionalAccess', _67 => _67.id]))), () => ( null))
1565
+ _nullishCoalesce(_nullishCoalesce(this.assistantOptimisticId, () => ( _optionalChain([messages, 'access', _68 => _68.at, 'call', _69 => _69(-1), 'optionalAccess', _70 => _70.id]))), () => ( null))
1589
1566
  );
1590
1567
  this.messages = this.repository.getMessages();
1591
1568
  this.notifySubscribers();
@@ -1603,7 +1580,7 @@ var ExternalStoreThreadRuntime = (_class7 = class {
1603
1580
  this.updateMessages(this.repository.getMessages());
1604
1581
  }
1605
1582
  async append(message) {
1606
- if (message.parentId !== (_nullishCoalesce(_optionalChain([this, 'access', _68 => _68.messages, 'access', _69 => _69.at, 'call', _70 => _70(-1), 'optionalAccess', _71 => _71.id]), () => ( null)))) {
1583
+ if (message.parentId !== (_nullishCoalesce(_optionalChain([this, 'access', _71 => _71.messages, 'access', _72 => _72.at, 'call', _73 => _73(-1), 'optionalAccess', _74 => _74.id]), () => ( null)))) {
1607
1584
  if (!this._store.onEdit)
1608
1585
  throw new Error("Runtime does not support editing messages.");
1609
1586
  await this._store.onEdit(message);
@@ -1626,7 +1603,7 @@ var ExternalStoreThreadRuntime = (_class7 = class {
1626
1603
  }
1627
1604
  let messages = this.repository.getMessages();
1628
1605
  const previousMessage = messages[messages.length - 1];
1629
- if (_optionalChain([previousMessage, 'optionalAccess', _72 => _72.role]) === "user" && previousMessage.id === _optionalChain([messages, 'access', _73 => _73.at, 'call', _74 => _74(-1), 'optionalAccess', _75 => _75.id])) {
1606
+ if (_optionalChain([previousMessage, 'optionalAccess', _75 => _75.role]) === "user" && previousMessage.id === _optionalChain([messages, 'access', _76 => _76.at, 'call', _77 => _77(-1), 'optionalAccess', _78 => _78.id])) {
1630
1607
  this.repository.deleteMessage(previousMessage.id);
1631
1608
  if (!this.composer.text.trim()) {
1632
1609
  this.composer.setText(getThreadMessageText(previousMessage));
@@ -1655,7 +1632,7 @@ var ExternalStoreThreadRuntime = (_class7 = class {
1655
1632
  return () => this._subscriptions.delete(callback);
1656
1633
  }
1657
1634
  __init26() {this.updateMessages = (messages) => {
1658
- _optionalChain([this, 'access', _76 => _76._store, 'access', _77 => _77.setMessages, 'optionalCall', _78 => _78(
1635
+ _optionalChain([this, 'access', _79 => _79._store, 'access', _80 => _80.setMessages, 'optionalCall', _81 => _81(
1659
1636
  messages.flatMap(getExternalStoreMessage).filter((m) => m != null)
1660
1637
  )]);
1661
1638
  }}
@@ -1743,6 +1720,47 @@ var useDangerousInBrowserRuntime = ({
1743
1720
  return useLocalRuntime(adapter, { initialMessages });
1744
1721
  };
1745
1722
 
1723
+ // src/runtimes/speech/WebSpeechSynthesisAdapter.ts
1724
+ var WebSpeechSynthesisAdapter = class {
1725
+ speak(message) {
1726
+ const text = getThreadMessageText(message);
1727
+ const utterance = new SpeechSynthesisUtterance(text);
1728
+ const endHandlers = /* @__PURE__ */ new Set();
1729
+ const handleEnd = (reason, error) => {
1730
+ if (res.status.type === "ended") return;
1731
+ res.status = { type: "ended", reason, error };
1732
+ endHandlers.forEach((handler) => handler());
1733
+ };
1734
+ utterance.addEventListener("end", () => handleEnd("finished"));
1735
+ utterance.addEventListener("error", (e) => handleEnd("error", e.error));
1736
+ window.speechSynthesis.speak(utterance);
1737
+ const res = {
1738
+ status: { type: "running" },
1739
+ cancel: () => {
1740
+ window.speechSynthesis.cancel();
1741
+ handleEnd("cancelled");
1742
+ },
1743
+ onEnd: (callback) => {
1744
+ if (res.status.type === "ended") {
1745
+ let cancelled = false;
1746
+ queueMicrotask(() => {
1747
+ if (!cancelled) callback();
1748
+ });
1749
+ return () => {
1750
+ cancelled = true;
1751
+ };
1752
+ } else {
1753
+ endHandlers.add(callback);
1754
+ return () => {
1755
+ endHandlers.delete(callback);
1756
+ };
1757
+ }
1758
+ }
1759
+ };
1760
+ return res;
1761
+ }
1762
+ };
1763
+
1746
1764
  // src/context/providers/ThreadProvider.tsx
1747
1765
 
1748
1766
  var ThreadProvider = ({
@@ -1866,7 +1884,7 @@ var AssistantRuntimeProvider = _react.memo.call(void 0, AssistantRuntimeProvider
1866
1884
  var MessageContext = _react.createContext.call(void 0, null);
1867
1885
  function useMessageContext(options) {
1868
1886
  const context = _react.useContext.call(void 0, MessageContext);
1869
- if (!_optionalChain([options, 'optionalAccess', _79 => _79.optional]) && !context)
1887
+ if (!_optionalChain([options, 'optionalAccess', _82 => _82.optional]) && !context)
1870
1888
  throw new Error(
1871
1889
  "This component can only be used inside a component passed to <ThreadPrimitive.Messages components={...} />."
1872
1890
  );
@@ -1893,7 +1911,7 @@ var ContentPartContext = _react.createContext.call(void 0,
1893
1911
  );
1894
1912
  function useContentPartContext(options) {
1895
1913
  const context = _react.useContext.call(void 0, ContentPartContext);
1896
- if (!_optionalChain([options, 'optionalAccess', _80 => _80.optional]) && !context)
1914
+ if (!_optionalChain([options, 'optionalAccess', _83 => _83.optional]) && !context)
1897
1915
  throw new Error(
1898
1916
  "This component can only be used inside a component passed to <MessagePrimitive.Content components={...} >."
1899
1917
  );
@@ -1905,13 +1923,13 @@ function useContentPartContext(options) {
1905
1923
  var toAppendMessage = (useThreadMessages, message) => {
1906
1924
  if (typeof message === "string") {
1907
1925
  return {
1908
- parentId: _nullishCoalesce(_optionalChain([useThreadMessages, 'access', _81 => _81.getState, 'call', _82 => _82(), 'access', _83 => _83.at, 'call', _84 => _84(-1), 'optionalAccess', _85 => _85.id]), () => ( null)),
1926
+ parentId: _nullishCoalesce(_optionalChain([useThreadMessages, 'access', _84 => _84.getState, 'call', _85 => _85(), 'access', _86 => _86.at, 'call', _87 => _87(-1), 'optionalAccess', _88 => _88.id]), () => ( null)),
1909
1927
  role: "user",
1910
1928
  content: [{ type: "text", text: message }]
1911
1929
  };
1912
1930
  }
1913
1931
  return {
1914
- parentId: _nullishCoalesce(_nullishCoalesce(message.parentId, () => ( _optionalChain([useThreadMessages, 'access', _86 => _86.getState, 'call', _87 => _87(), 'access', _88 => _88.at, 'call', _89 => _89(-1), 'optionalAccess', _90 => _90.id]))), () => ( null)),
1932
+ parentId: _nullishCoalesce(_nullishCoalesce(message.parentId, () => ( _optionalChain([useThreadMessages, 'access', _89 => _89.getState, 'call', _90 => _90(), 'access', _91 => _91.at, 'call', _92 => _92(-1), 'optionalAccess', _93 => _93.id]))), () => ( null)),
1915
1933
  role: _nullishCoalesce(message.role, () => ( "user")),
1916
1934
  content: message.content
1917
1935
  };
@@ -1963,7 +1981,7 @@ var useAssistantTool = (tool) => {
1963
1981
  const unsub2 = render ? setToolUI(toolName, render) : void 0;
1964
1982
  return () => {
1965
1983
  unsub1();
1966
- _optionalChain([unsub2, 'optionalCall', _91 => _91()]);
1984
+ _optionalChain([unsub2, 'optionalCall', _94 => _94()]);
1967
1985
  };
1968
1986
  }, [registerModelConfigProvider, setToolUI, tool]);
1969
1987
  };
@@ -2428,7 +2446,7 @@ var createActionButton = (displayName, useActionButton, forwardProps = []) => {
2428
2446
  ...primitiveProps,
2429
2447
  ref: forwardedRef,
2430
2448
  onClick: _primitive.composeEventHandlers.call(void 0, primitiveProps.onClick, () => {
2431
- _optionalChain([callback, 'optionalCall', _92 => _92()]);
2449
+ _optionalChain([callback, 'optionalCall', _95 => _95()]);
2432
2450
  })
2433
2451
  }
2434
2452
  );
@@ -2484,7 +2502,7 @@ var ActionBarPrimitiveStopSpeaking = _react.forwardRef.call(void 0, (props, ref)
2484
2502
  ...props,
2485
2503
  ref,
2486
2504
  onClick: _primitive.composeEventHandlers.call(void 0, props.onClick, () => {
2487
- _optionalChain([callback, 'optionalCall', _93 => _93()]);
2505
+ _optionalChain([callback, 'optionalCall', _96 => _96()]);
2488
2506
  })
2489
2507
  }
2490
2508
  );
@@ -2770,7 +2788,7 @@ var getContentPartState = ({ message }, useContentPart, partIndex) => {
2770
2788
  }
2771
2789
  }
2772
2790
  const status = toContentPartStatus(message, partIndex, part);
2773
- const currentState = _optionalChain([useContentPart, 'optionalAccess', _94 => _94.getState, 'call', _95 => _95()]);
2791
+ const currentState = _optionalChain([useContentPart, 'optionalAccess', _97 => _97.getState, 'call', _98 => _98()]);
2774
2792
  if (currentState && currentState.part === part && currentState.status === status)
2775
2793
  return null;
2776
2794
  return Object.freeze({ part, status });
@@ -2918,7 +2936,7 @@ var MessageContentPartImpl = ({
2918
2936
  };
2919
2937
  var MessageContentPart = _react.memo.call(void 0,
2920
2938
  MessageContentPartImpl,
2921
- (prev, next) => prev.partIndex === next.partIndex && _optionalChain([prev, 'access', _96 => _96.components, 'optionalAccess', _97 => _97.Text]) === _optionalChain([next, 'access', _98 => _98.components, 'optionalAccess', _99 => _99.Text]) && _optionalChain([prev, 'access', _100 => _100.components, 'optionalAccess', _101 => _101.Image]) === _optionalChain([next, 'access', _102 => _102.components, 'optionalAccess', _103 => _103.Image]) && _optionalChain([prev, 'access', _104 => _104.components, 'optionalAccess', _105 => _105.UI]) === _optionalChain([next, 'access', _106 => _106.components, 'optionalAccess', _107 => _107.UI]) && _optionalChain([prev, 'access', _108 => _108.components, 'optionalAccess', _109 => _109.tools]) === _optionalChain([next, 'access', _110 => _110.components, 'optionalAccess', _111 => _111.tools])
2939
+ (prev, next) => prev.partIndex === next.partIndex && _optionalChain([prev, 'access', _99 => _99.components, 'optionalAccess', _100 => _100.Text]) === _optionalChain([next, 'access', _101 => _101.components, 'optionalAccess', _102 => _102.Text]) && _optionalChain([prev, 'access', _103 => _103.components, 'optionalAccess', _104 => _104.Image]) === _optionalChain([next, 'access', _105 => _105.components, 'optionalAccess', _106 => _106.Image]) && _optionalChain([prev, 'access', _107 => _107.components, 'optionalAccess', _108 => _108.UI]) === _optionalChain([next, 'access', _109 => _109.components, 'optionalAccess', _110 => _110.UI]) && _optionalChain([prev, 'access', _111 => _111.components, 'optionalAccess', _112 => _112.tools]) === _optionalChain([next, 'access', _113 => _113.components, 'optionalAccess', _114 => _114.tools])
2922
2940
  );
2923
2941
  var MessagePrimitiveContent = ({
2924
2942
  components
@@ -3033,7 +3051,7 @@ var ComposerPrimitiveInput = _react.forwardRef.call(void 0,
3033
3051
  const { isRunning } = useThread.getState();
3034
3052
  if (!isRunning) {
3035
3053
  e.preventDefault();
3036
- _optionalChain([textareaRef, 'access', _112 => _112.current, 'optionalAccess', _113 => _113.closest, 'call', _114 => _114("form"), 'optionalAccess', _115 => _115.requestSubmit, 'call', _116 => _116()]);
3054
+ _optionalChain([textareaRef, 'access', _115 => _115.current, 'optionalAccess', _116 => _116.closest, 'call', _117 => _117("form"), 'optionalAccess', _118 => _118.requestSubmit, 'call', _119 => _119()]);
3037
3055
  }
3038
3056
  }
3039
3057
  };
@@ -3335,7 +3353,7 @@ var makeMessageUtilsStore = () => _zustand.create.call(void 0, (set) => {
3335
3353
  },
3336
3354
  isSpeaking: false,
3337
3355
  stopSpeaking: () => {
3338
- _optionalChain([utterance, 'optionalAccess', _117 => _117.stop, 'call', _118 => _118()]);
3356
+ _optionalChain([utterance, 'optionalAccess', _120 => _120.cancel, 'call', _121 => _121()]);
3339
3357
  },
3340
3358
  addUtterance: (utt) => {
3341
3359
  utterance = utt;
@@ -3350,15 +3368,15 @@ var makeMessageUtilsStore = () => _zustand.create.call(void 0, (set) => {
3350
3368
  // src/context/providers/MessageProvider.tsx
3351
3369
 
3352
3370
  var getIsLast = (messages, message) => {
3353
- return _optionalChain([messages, 'access', _119 => _119[messages.length - 1], 'optionalAccess', _120 => _120.id]) === message.id;
3371
+ return _optionalChain([messages, 'access', _122 => _122[messages.length - 1], 'optionalAccess', _123 => _123.id]) === message.id;
3354
3372
  };
3355
3373
  var getMessageState = (messages, getBranches, useMessage, messageIndex) => {
3356
- const parentId = _nullishCoalesce(_optionalChain([messages, 'access', _121 => _121[messageIndex - 1], 'optionalAccess', _122 => _122.id]), () => ( null));
3374
+ const parentId = _nullishCoalesce(_optionalChain([messages, 'access', _124 => _124[messageIndex - 1], 'optionalAccess', _125 => _125.id]), () => ( null));
3357
3375
  const message = messages[messageIndex];
3358
3376
  if (!message) return null;
3359
3377
  const isLast = getIsLast(messages, message);
3360
3378
  const branches = getBranches(message.id);
3361
- const currentState = _optionalChain([useMessage, 'optionalAccess', _123 => _123.getState, 'call', _124 => _124()]);
3379
+ const currentState = _optionalChain([useMessage, 'optionalAccess', _126 => _126.getState, 'call', _127 => _127()]);
3362
3380
  if (currentState && currentState.message === message && currentState.parentId === parentId && currentState.branches === branches && currentState.isLast === isLast)
3363
3381
  return null;
3364
3382
  return Object.freeze({
@@ -3485,7 +3503,7 @@ var ThreadPrimitiveMessagesImpl = ({
3485
3503
  ThreadPrimitiveMessagesImpl.displayName = "ThreadPrimitive.Messages";
3486
3504
  var ThreadPrimitiveMessages = _react.memo.call(void 0,
3487
3505
  ThreadPrimitiveMessagesImpl,
3488
- (prev, next) => _optionalChain([prev, 'access', _125 => _125.components, 'optionalAccess', _126 => _126.Message]) === _optionalChain([next, 'access', _127 => _127.components, 'optionalAccess', _128 => _128.Message]) && _optionalChain([prev, 'access', _129 => _129.components, 'optionalAccess', _130 => _130.UserMessage]) === _optionalChain([next, 'access', _131 => _131.components, 'optionalAccess', _132 => _132.UserMessage]) && _optionalChain([prev, 'access', _133 => _133.components, 'optionalAccess', _134 => _134.EditComposer]) === _optionalChain([next, 'access', _135 => _135.components, 'optionalAccess', _136 => _136.EditComposer]) && _optionalChain([prev, 'access', _137 => _137.components, 'optionalAccess', _138 => _138.AssistantMessage]) === _optionalChain([next, 'access', _139 => _139.components, 'optionalAccess', _140 => _140.AssistantMessage]) && _optionalChain([prev, 'access', _141 => _141.components, 'optionalAccess', _142 => _142.SystemMessage]) === _optionalChain([next, 'access', _143 => _143.components, 'optionalAccess', _144 => _144.SystemMessage])
3506
+ (prev, next) => _optionalChain([prev, 'access', _128 => _128.components, 'optionalAccess', _129 => _129.Message]) === _optionalChain([next, 'access', _130 => _130.components, 'optionalAccess', _131 => _131.Message]) && _optionalChain([prev, 'access', _132 => _132.components, 'optionalAccess', _133 => _133.UserMessage]) === _optionalChain([next, 'access', _134 => _134.components, 'optionalAccess', _135 => _135.UserMessage]) && _optionalChain([prev, 'access', _136 => _136.components, 'optionalAccess', _137 => _137.EditComposer]) === _optionalChain([next, 'access', _138 => _138.components, 'optionalAccess', _139 => _139.EditComposer]) && _optionalChain([prev, 'access', _140 => _140.components, 'optionalAccess', _141 => _141.AssistantMessage]) === _optionalChain([next, 'access', _142 => _142.components, 'optionalAccess', _143 => _143.AssistantMessage]) && _optionalChain([prev, 'access', _144 => _144.components, 'optionalAccess', _145 => _145.SystemMessage]) === _optionalChain([next, 'access', _146 => _146.components, 'optionalAccess', _147 => _147.SystemMessage])
3489
3507
  );
3490
3508
 
3491
3509
  // src/primitives/thread/ThreadScrollToBottom.tsx
@@ -3517,7 +3535,7 @@ var ThreadConfigProvider = ({
3517
3535
  }) => {
3518
3536
  const assistant = useAssistantContext({ optional: true });
3519
3537
  const configProvider = config && Object.keys(_nullishCoalesce(config, () => ( {}))).length > 0 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThreadConfigContext.Provider, { value: config, children }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children });
3520
- if (!_optionalChain([config, 'optionalAccess', _145 => _145.runtime])) return configProvider;
3538
+ if (!_optionalChain([config, 'optionalAccess', _148 => _148.runtime])) return configProvider;
3521
3539
  if (assistant) {
3522
3540
  throw new Error(
3523
3541
  "You provided a runtime to <Thread> while simulataneously using <AssistantRuntimeProvider>. This is not allowed."
@@ -3537,28 +3555,29 @@ ThreadConfigProvider.displayName = "ThreadConfigProvider";
3537
3555
 
3538
3556
  var _lucidereact = require('lucide-react');
3539
3557
 
3540
- var useAllowCopy = () => {
3558
+ var useAllowCopy = (ensureCapability = false) => {
3541
3559
  const { assistantMessage: { allowCopy = true } = {} } = useThreadConfig();
3542
3560
  const { useThread } = useThreadContext();
3543
3561
  const copySupported = useThread((t) => t.capabilities.unstable_copy);
3544
- return copySupported && allowCopy;
3562
+ return allowCopy && (!ensureCapability || copySupported);
3545
3563
  };
3546
- var useAllowSpeak = () => {
3564
+ var useAllowSpeak = (ensureCapability = false) => {
3547
3565
  const { assistantMessage: { allowSpeak = true } = {} } = useThreadConfig();
3548
3566
  const { useThread } = useThreadContext();
3549
3567
  const speakSupported = useThread((t) => t.capabilities.speak);
3550
- return speakSupported && allowSpeak;
3568
+ return allowSpeak && (!ensureCapability || speakSupported);
3551
3569
  };
3552
- var useAllowReload = () => {
3570
+ var useAllowReload = (ensureCapability = false) => {
3553
3571
  const { assistantMessage: { allowReload = true } = {} } = useThreadConfig();
3554
3572
  const { useThread } = useThreadContext();
3555
3573
  const reloadSupported = useThread((t) => t.capabilities.reload);
3556
- return reloadSupported && allowReload;
3574
+ return allowReload && (!ensureCapability || reloadSupported);
3557
3575
  };
3558
3576
  var AssistantActionBar = () => {
3559
- const allowCopy = useAllowCopy();
3560
- const allowReload = useAllowReload();
3561
- if (!allowCopy && !allowReload) return null;
3577
+ const allowCopy = useAllowCopy(true);
3578
+ const allowReload = useAllowReload(true);
3579
+ const allowSpeak = useAllowSpeak(true);
3580
+ if (!allowCopy && !allowReload && !allowSpeak) return null;
3562
3581
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3563
3582
  AssistantActionBarRoot,
3564
3583
  {
@@ -3566,9 +3585,9 @@ var AssistantActionBar = () => {
3566
3585
  autohide: "not-last",
3567
3586
  autohideFloat: "single-branch",
3568
3587
  children: [
3569
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AssistantActionBarSpeechControl, {}),
3570
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AssistantActionBarCopy, {}),
3571
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AssistantActionBarReload, {})
3588
+ allowSpeak && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AssistantActionBarSpeechControl, {}),
3589
+ allowCopy && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AssistantActionBarCopy, {}),
3590
+ allowReload && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AssistantActionBarReload, {})
3572
3591
  ]
3573
3592
  }
3574
3593
  );
@@ -3584,8 +3603,6 @@ var AssistantActionBarCopy = _react.forwardRef.call(void 0, (props, ref) => {
3584
3603
  assistantMessage: { copy: { tooltip = "Copy" } = {} } = {}
3585
3604
  } = {}
3586
3605
  } = useThreadConfig();
3587
- const allowCopy = useAllowCopy();
3588
- if (!allowCopy) return null;
3589
3606
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, actionBar_exports.Copy, { asChild: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TooltipIconButton, { tooltip, ...props, ref, children: _nullishCoalesce(props.children, () => ( /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
3590
3607
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, message_exports.If, { copied: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CheckIcon, {}) }),
3591
3608
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, message_exports.If, { copied: false, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CopyIcon, {}) })
@@ -3779,7 +3796,7 @@ var AssistantMessageContent = _react.forwardRef.call(void 0, ({ components: comp
3779
3796
  {
3780
3797
  components: {
3781
3798
  ...componentsProp,
3782
- Text: _nullishCoalesce(_nullishCoalesce(_optionalChain([componentsProp, 'optionalAccess', _146 => _146.Text]), () => ( components.Text)), () => ( content_part_default.Text))
3799
+ Text: _nullishCoalesce(_nullishCoalesce(_optionalChain([componentsProp, 'optionalAccess', _149 => _149.Text]), () => ( components.Text)), () => ( content_part_default.Text))
3783
3800
  }
3784
3801
  }
3785
3802
  ) });
@@ -3956,7 +3973,7 @@ var ThreadWelcomeSuggestion = ({
3956
3973
  };
3957
3974
  var ThreadWelcomeSuggestions = () => {
3958
3975
  const { welcome: { suggestions } = {} } = useThreadConfig();
3959
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThreadWelcomeSuggestionContainer, { children: _optionalChain([suggestions, 'optionalAccess', _147 => _147.map, 'call', _148 => _148((suggestion, idx) => {
3976
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThreadWelcomeSuggestionContainer, { children: _optionalChain([suggestions, 'optionalAccess', _150 => _150.map, 'call', _151 => _151((suggestion, idx) => {
3960
3977
  const key = `${suggestion.prompt}-${idx}`;
3961
3978
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThreadWelcomeSuggestion, { suggestion }, key);
3962
3979
  })]) });
@@ -3979,14 +3996,14 @@ var thread_welcome_default = Object.assign(ThreadWelcome, exports6);
3979
3996
 
3980
3997
 
3981
3998
 
3982
- var useAllowEdit = () => {
3999
+ var useAllowEdit = (ensureCapability = false) => {
3983
4000
  const { userMessage: { allowEdit = true } = {} } = useThreadConfig();
3984
4001
  const { useThread } = useThreadContext();
3985
4002
  const editSupported = useThread((t) => t.capabilities.edit);
3986
- return editSupported && allowEdit;
4003
+ return allowEdit && (!ensureCapability || editSupported);
3987
4004
  };
3988
4005
  var UserActionBar = () => {
3989
- const allowEdit = useAllowEdit();
4006
+ const allowEdit = useAllowEdit(true);
3990
4007
  if (!allowEdit) return null;
3991
4008
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, UserActionBarRoot, { hideWhenRunning: true, autohide: "not-last", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, UserActionBarEdit, {}) });
3992
4009
  };
@@ -4034,7 +4051,7 @@ var UserMessageContent = _react.forwardRef.call(void 0,
4034
4051
  {
4035
4052
  components: {
4036
4053
  ...components,
4037
- Text: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _149 => _149.Text]), () => ( content_part_default.Text))
4054
+ Text: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _152 => _152.Text]), () => ( content_part_default.Text))
4038
4055
  }
4039
4056
  }
4040
4057
  ) });
@@ -4136,10 +4153,10 @@ var ThreadMessages = ({ components, ...rest }) => {
4136
4153
  thread_exports.Messages,
4137
4154
  {
4138
4155
  components: {
4139
- UserMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _150 => _150.UserMessage]), () => ( user_message_default)),
4140
- EditComposer: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _151 => _151.EditComposer]), () => ( edit_composer_default)),
4141
- AssistantMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _152 => _152.AssistantMessage]), () => ( assistant_message_default)),
4142
- SystemMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _153 => _153.SystemMessage]), () => ( SystemMessage))
4156
+ UserMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _153 => _153.UserMessage]), () => ( user_message_default)),
4157
+ EditComposer: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _154 => _154.EditComposer]), () => ( edit_composer_default)),
4158
+ AssistantMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _155 => _155.AssistantMessage]), () => ( assistant_message_default)),
4159
+ SystemMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _156 => _156.SystemMessage]), () => ( SystemMessage))
4143
4160
  },
4144
4161
  ...rest
4145
4162
  }