@assistant-ui/react 0.5.41 → 0.5.42

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