@assistant-ui/react 0.5.40 → 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
@@ -204,7 +204,8 @@ var makeThreadActionStore = (runtimeStore) => {
204
204
  startRun: (parentId) => runtimeStore.getState().startRun(parentId),
205
205
  append: (message) => runtimeStore.getState().append(message),
206
206
  cancelRun: () => runtimeStore.getState().cancelRun(),
207
- addToolResult: (options) => runtimeStore.getState().addToolResult(options)
207
+ addToolResult: (options) => runtimeStore.getState().addToolResult(options),
208
+ speak: (messageId) => runtimeStore.getState().speak(messageId)
208
209
  })
209
210
  );
210
211
  };
@@ -1057,31 +1058,29 @@ var EdgeChatAdapter = class {
1057
1058
  var useEdgeRuntime = ({
1058
1059
  initialMessages,
1059
1060
  maxToolRoundtrips,
1061
+ adapters,
1060
1062
  ...options
1061
1063
  }) => {
1062
1064
  const [adapter] = _react.useState.call(void 0, () => new EdgeChatAdapter(options));
1063
- return useLocalRuntime(adapter, { initialMessages, maxToolRoundtrips });
1065
+ return useLocalRuntime(adapter, {
1066
+ initialMessages,
1067
+ maxToolRoundtrips,
1068
+ adapters
1069
+ });
1064
1070
  };
1065
1071
 
1066
1072
  // src/runtimes/local/shouldContinue.tsx
1067
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);
1068
1074
 
1069
1075
  // src/runtimes/local/LocalThreadRuntime.tsx
1070
- var CAPABILITIES = Object.freeze({
1071
- switchToBranch: true,
1072
- edit: true,
1073
- reload: true,
1074
- cancel: true,
1075
- copy: true
1076
- });
1077
1076
  var LocalThreadRuntime = (_class5 = class {
1078
- constructor(configProvider, adapter, 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);
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);
1079
1078
  this.configProvider = configProvider;
1080
1079
  this.adapter = adapter;
1081
1080
  this.options = options;
1082
- if (options.initialMessages) {
1081
+ if (initialMessages) {
1083
1082
  let parentId = null;
1084
- const messages = fromCoreMessages(options.initialMessages);
1083
+ const messages = fromCoreMessages(initialMessages);
1085
1084
  for (const message of messages) {
1086
1085
  this.repository.addOrUpdateMessage(parentId, message);
1087
1086
  parentId = message.id;
@@ -1091,7 +1090,14 @@ var LocalThreadRuntime = (_class5 = class {
1091
1090
  __init11() {this._subscriptions = /* @__PURE__ */ new Set()}
1092
1091
  __init12() {this.abortController = null}
1093
1092
  __init13() {this.repository = new MessageRepository()}
1094
- __init14() {this.capabilities = CAPABILITIES}
1093
+ __init14() {this.capabilities = {
1094
+ switchToBranch: true,
1095
+ edit: true,
1096
+ reload: true,
1097
+ cancel: true,
1098
+ unstable_copy: true,
1099
+ speak: false
1100
+ }}
1095
1101
  __init15() {this.isDisabled = false}
1096
1102
  get messages() {
1097
1103
  return this.repository.getMessages();
@@ -1103,6 +1109,18 @@ var LocalThreadRuntime = (_class5 = class {
1103
1109
  this.notifySubscribers();
1104
1110
  }
1105
1111
  }}
1112
+
1113
+ get options() {
1114
+ return this._options;
1115
+ }
1116
+ set options({ initialMessages, ...options }) {
1117
+ this._options = options;
1118
+ const canSpeak = _optionalChain([options, 'access', _35 => _35.adapters, 'optionalAccess', _36 => _36.speech]) !== void 0;
1119
+ if (this.capabilities.speak !== canSpeak) {
1120
+ this.capabilities.speak = canSpeak;
1121
+ this.notifySubscribers();
1122
+ }
1123
+ }
1106
1124
  getBranches(messageId) {
1107
1125
  return this.repository.getBranches(messageId);
1108
1126
  }
@@ -1141,18 +1159,18 @@ var LocalThreadRuntime = (_class5 = class {
1141
1159
  }
1142
1160
  async performRoundtrip(parentId, message) {
1143
1161
  const messages = this.repository.getMessages();
1144
- _optionalChain([this, 'access', _35 => _35.abortController, 'optionalAccess', _36 => _36.abort, 'call', _37 => _37()]);
1162
+ _optionalChain([this, 'access', _37 => _37.abortController, 'optionalAccess', _38 => _38.abort, 'call', _39 => _39()]);
1145
1163
  this.abortController = new AbortController();
1146
1164
  const initialContent = message.content;
1147
- const initialRoundtrips = _optionalChain([message, 'access', _38 => _38.metadata, 'optionalAccess', _39 => _39.roundtrips]);
1148
- const initalCustom = _optionalChain([message, 'access', _40 => _40.metadata, 'optionalAccess', _41 => _41.custom]);
1165
+ const initialRoundtrips = _optionalChain([message, 'access', _40 => _40.metadata, 'optionalAccess', _41 => _41.roundtrips]);
1166
+ const initalCustom = _optionalChain([message, 'access', _42 => _42.metadata, 'optionalAccess', _43 => _43.custom]);
1149
1167
  const updateMessage = (m) => {
1150
1168
  message = {
1151
1169
  ...message,
1152
1170
  ...m.content ? { content: [...initialContent, ..._nullishCoalesce(m.content, () => ( []))] } : void 0,
1153
1171
  status: _nullishCoalesce(m.status, () => ( message.status)),
1154
1172
  // TODO deprecated, remove in v0.6
1155
- ..._optionalChain([m, 'access', _42 => _42.metadata, 'optionalAccess', _43 => _43.roundtrips]) ? {
1173
+ ..._optionalChain([m, 'access', _44 => _44.metadata, 'optionalAccess', _45 => _45.roundtrips]) ? {
1156
1174
  roundtrips: [
1157
1175
  ..._nullishCoalesce(initialRoundtrips, () => ( [])),
1158
1176
  ...m.metadata.roundtrips
@@ -1167,7 +1185,7 @@ var LocalThreadRuntime = (_class5 = class {
1167
1185
  ...m.metadata.roundtrips
1168
1186
  ]
1169
1187
  } : void 0,
1170
- ..._optionalChain([m, 'access', _44 => _44.metadata, 'optionalAccess', _45 => _45.custom]) ? {
1188
+ ..._optionalChain([m, 'access', _46 => _46.metadata, 'optionalAccess', _47 => _47.custom]) ? {
1171
1189
  custom: { ..._nullishCoalesce(initalCustom, () => ( {})), ...m.metadata.custom }
1172
1190
  } : void 0
1173
1191
  }
@@ -1177,7 +1195,7 @@ var LocalThreadRuntime = (_class5 = class {
1177
1195
  this.notifySubscribers();
1178
1196
  };
1179
1197
  const maxToolRoundtrips = _nullishCoalesce(this.options.maxToolRoundtrips, () => ( 1));
1180
- const toolRoundtrips = _nullishCoalesce(_optionalChain([message, 'access', _46 => _46.metadata, 'optionalAccess', _47 => _47.roundtrips, 'optionalAccess', _48 => _48.length]), () => ( 0));
1198
+ const toolRoundtrips = _nullishCoalesce(_optionalChain([message, 'access', _48 => _48.metadata, 'optionalAccess', _49 => _49.roundtrips, 'optionalAccess', _50 => _50.length]), () => ( 0));
1181
1199
  if (toolRoundtrips > maxToolRoundtrips) {
1182
1200
  updateMessage({
1183
1201
  status: {
@@ -1240,7 +1258,11 @@ var LocalThreadRuntime = (_class5 = class {
1240
1258
  this._subscriptions.add(callback);
1241
1259
  return () => this._subscriptions.delete(callback);
1242
1260
  }
1243
- addToolResult({ messageId, toolCallId, result }) {
1261
+ addToolResult({
1262
+ messageId,
1263
+ toolCallId,
1264
+ result
1265
+ }) {
1244
1266
  let { parentId, message } = this.repository.getMessage(messageId);
1245
1267
  if (message.role !== "assistant")
1246
1268
  throw new Error("Tried to add tool result to non-assistant message");
@@ -1267,6 +1289,25 @@ var LocalThreadRuntime = (_class5 = class {
1267
1289
  this.performRoundtrip(parentId, message);
1268
1290
  }
1269
1291
  }
1292
+ // TODO lift utterance state to thread runtime
1293
+
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");
1297
+ const { message } = this.repository.getMessage(messageId);
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;
1310
+ }
1270
1311
  export() {
1271
1312
  return this.repository.export();
1272
1313
  }
@@ -1312,7 +1353,7 @@ var LocalRuntime = class extends BaseAssistantRuntime {
1312
1353
  const messages = fromCoreMessages(initialMessages);
1313
1354
  this.thread.import({
1314
1355
  messages: messages.map((m, idx) => ({
1315
- parentId: _nullishCoalesce(_optionalChain([messages, 'access', _49 => _49[idx - 1], 'optionalAccess', _50 => _50.id]), () => ( null)),
1356
+ parentId: _nullishCoalesce(_optionalChain([messages, 'access', _54 => _54[idx - 1], 'optionalAccess', _55 => _55.id]), () => ( null)),
1316
1357
  message: m
1317
1358
  }))
1318
1359
  });
@@ -1435,7 +1476,7 @@ var getThreadMessageText = (message) => {
1435
1476
 
1436
1477
  // src/runtimes/external-store/ExternalStoreThreadRuntime.tsx
1437
1478
  var hasUpcomingMessage = (isRunning, messages) => {
1438
- return isRunning && _optionalChain([messages, 'access', _51 => _51[messages.length - 1], 'optionalAccess', _52 => _52.role]) !== "assistant";
1479
+ return isRunning && _optionalChain([messages, 'access', _56 => _56[messages.length - 1], 'optionalAccess', _57 => _57.role]) !== "assistant";
1439
1480
  };
1440
1481
  var ExternalStoreThreadRuntime = (_class7 = class {
1441
1482
  __init18() {this._subscriptions = /* @__PURE__ */ new Set()}
@@ -1446,7 +1487,8 @@ var ExternalStoreThreadRuntime = (_class7 = class {
1446
1487
  edit: false,
1447
1488
  reload: false,
1448
1489
  cancel: false,
1449
- copy: false
1490
+ unstable_copy: false,
1491
+ speak: false
1450
1492
  }}
1451
1493
  get capabilities() {
1452
1494
  return this._capabilities;
@@ -1476,7 +1518,8 @@ var ExternalStoreThreadRuntime = (_class7 = class {
1476
1518
  edit: this._store.onEdit !== void 0,
1477
1519
  reload: this._store.onReload !== void 0,
1478
1520
  cancel: this._store.onCancel !== void 0,
1479
- copy: this._store.onCopy !== null
1521
+ unstable_copy: _optionalChain([this, 'access', _61 => _61._store, 'access', _62 => _62.unstable_capabilities, 'optionalAccess', _63 => _63.copy]) !== null,
1522
+ speak: this._store.onSpeak !== void 0
1480
1523
  };
1481
1524
  if (oldStore) {
1482
1525
  if (oldStore.convertMessage !== store.convertMessage) {
@@ -1503,7 +1546,7 @@ var ExternalStoreThreadRuntime = (_class7 = class {
1503
1546
  for (let i = 0; i < messages.length; i++) {
1504
1547
  const message = messages[i];
1505
1548
  const parent = messages[i - 1];
1506
- this.repository.addOrUpdateMessage(_nullishCoalesce(_optionalChain([parent, 'optionalAccess', _56 => _56.id]), () => ( null)), message);
1549
+ this.repository.addOrUpdateMessage(_nullishCoalesce(_optionalChain([parent, 'optionalAccess', _64 => _64.id]), () => ( null)), message);
1507
1550
  }
1508
1551
  if (this.assistantOptimisticId) {
1509
1552
  this.repository.deleteMessage(this.assistantOptimisticId);
@@ -1511,7 +1554,7 @@ var ExternalStoreThreadRuntime = (_class7 = class {
1511
1554
  }
1512
1555
  if (hasUpcomingMessage(isRunning, messages)) {
1513
1556
  this.assistantOptimisticId = this.repository.appendOptimisticMessage(
1514
- _nullishCoalesce(_optionalChain([messages, 'access', _57 => _57.at, 'call', _58 => _58(-1), 'optionalAccess', _59 => _59.id]), () => ( null)),
1557
+ _nullishCoalesce(_optionalChain([messages, 'access', _65 => _65.at, 'call', _66 => _66(-1), 'optionalAccess', _67 => _67.id]), () => ( null)),
1515
1558
  {
1516
1559
  role: "assistant",
1517
1560
  content: []
@@ -1519,7 +1562,7 @@ var ExternalStoreThreadRuntime = (_class7 = class {
1519
1562
  );
1520
1563
  }
1521
1564
  this.repository.resetHead(
1522
- _nullishCoalesce(_nullishCoalesce(this.assistantOptimisticId, () => ( _optionalChain([messages, 'access', _60 => _60.at, 'call', _61 => _61(-1), 'optionalAccess', _62 => _62.id]))), () => ( null))
1565
+ _nullishCoalesce(_nullishCoalesce(this.assistantOptimisticId, () => ( _optionalChain([messages, 'access', _68 => _68.at, 'call', _69 => _69(-1), 'optionalAccess', _70 => _70.id]))), () => ( null))
1523
1566
  );
1524
1567
  this.messages = this.repository.getMessages();
1525
1568
  this.notifySubscribers();
@@ -1537,7 +1580,7 @@ var ExternalStoreThreadRuntime = (_class7 = class {
1537
1580
  this.updateMessages(this.repository.getMessages());
1538
1581
  }
1539
1582
  async append(message) {
1540
- if (message.parentId !== (_nullishCoalesce(_optionalChain([this, 'access', _63 => _63.messages, 'access', _64 => _64.at, 'call', _65 => _65(-1), 'optionalAccess', _66 => _66.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)))) {
1541
1584
  if (!this._store.onEdit)
1542
1585
  throw new Error("Runtime does not support editing messages.");
1543
1586
  await this._store.onEdit(message);
@@ -1560,7 +1603,7 @@ var ExternalStoreThreadRuntime = (_class7 = class {
1560
1603
  }
1561
1604
  let messages = this.repository.getMessages();
1562
1605
  const previousMessage = messages[messages.length - 1];
1563
- if (_optionalChain([previousMessage, 'optionalAccess', _67 => _67.role]) === "user" && previousMessage.id === _optionalChain([messages, 'access', _68 => _68.at, 'call', _69 => _69(-1), 'optionalAccess', _70 => _70.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])) {
1564
1607
  this.repository.deleteMessage(previousMessage.id);
1565
1608
  if (!this.composer.text.trim()) {
1566
1609
  this.composer.setText(getThreadMessageText(previousMessage));
@@ -1573,20 +1616,26 @@ var ExternalStoreThreadRuntime = (_class7 = class {
1573
1616
  this.updateMessages(messages);
1574
1617
  }, 0);
1575
1618
  }
1619
+ addToolResult(options) {
1620
+ if (!this._store.onAddToolResult)
1621
+ throw new Error("Runtime does not support tool results.");
1622
+ this._store.onAddToolResult(options);
1623
+ }
1624
+ speak(messageId) {
1625
+ if (!this._store.onSpeak)
1626
+ throw new Error("Runtime does not support speaking.");
1627
+ const { message } = this.repository.getMessage(messageId);
1628
+ return this._store.onSpeak(message);
1629
+ }
1576
1630
  subscribe(callback) {
1577
1631
  this._subscriptions.add(callback);
1578
1632
  return () => this._subscriptions.delete(callback);
1579
1633
  }
1580
1634
  __init26() {this.updateMessages = (messages) => {
1581
- _optionalChain([this, 'access', _71 => _71._store, 'access', _72 => _72.setMessages, 'optionalCall', _73 => _73(
1635
+ _optionalChain([this, 'access', _79 => _79._store, 'access', _80 => _80.setMessages, 'optionalCall', _81 => _81(
1582
1636
  messages.flatMap(getExternalStoreMessage).filter((m) => m != null)
1583
1637
  )]);
1584
1638
  }}
1585
- addToolResult(options) {
1586
- if (!this._store.onAddToolResult)
1587
- throw new Error("Runtime does not support tool results.");
1588
- this._store.onAddToolResult(options);
1589
- }
1590
1639
  }, _class7);
1591
1640
 
1592
1641
  // src/runtimes/external-store/ExternalStoreRuntime.tsx
@@ -1671,6 +1720,47 @@ var useDangerousInBrowserRuntime = ({
1671
1720
  return useLocalRuntime(adapter, { initialMessages });
1672
1721
  };
1673
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
+
1674
1764
  // src/context/providers/ThreadProvider.tsx
1675
1765
 
1676
1766
  var ThreadProvider = ({
@@ -1794,7 +1884,7 @@ var AssistantRuntimeProvider = _react.memo.call(void 0, AssistantRuntimeProvider
1794
1884
  var MessageContext = _react.createContext.call(void 0, null);
1795
1885
  function useMessageContext(options) {
1796
1886
  const context = _react.useContext.call(void 0, MessageContext);
1797
- if (!_optionalChain([options, 'optionalAccess', _74 => _74.optional]) && !context)
1887
+ if (!_optionalChain([options, 'optionalAccess', _82 => _82.optional]) && !context)
1798
1888
  throw new Error(
1799
1889
  "This component can only be used inside a component passed to <ThreadPrimitive.Messages components={...} />."
1800
1890
  );
@@ -1821,7 +1911,7 @@ var ContentPartContext = _react.createContext.call(void 0,
1821
1911
  );
1822
1912
  function useContentPartContext(options) {
1823
1913
  const context = _react.useContext.call(void 0, ContentPartContext);
1824
- if (!_optionalChain([options, 'optionalAccess', _75 => _75.optional]) && !context)
1914
+ if (!_optionalChain([options, 'optionalAccess', _83 => _83.optional]) && !context)
1825
1915
  throw new Error(
1826
1916
  "This component can only be used inside a component passed to <MessagePrimitive.Content components={...} >."
1827
1917
  );
@@ -1833,13 +1923,13 @@ function useContentPartContext(options) {
1833
1923
  var toAppendMessage = (useThreadMessages, message) => {
1834
1924
  if (typeof message === "string") {
1835
1925
  return {
1836
- parentId: _nullishCoalesce(_optionalChain([useThreadMessages, 'access', _76 => _76.getState, 'call', _77 => _77(), 'access', _78 => _78.at, 'call', _79 => _79(-1), 'optionalAccess', _80 => _80.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)),
1837
1927
  role: "user",
1838
1928
  content: [{ type: "text", text: message }]
1839
1929
  };
1840
1930
  }
1841
1931
  return {
1842
- parentId: _nullishCoalesce(_nullishCoalesce(message.parentId, () => ( _optionalChain([useThreadMessages, 'access', _81 => _81.getState, 'call', _82 => _82(), 'access', _83 => _83.at, 'call', _84 => _84(-1), 'optionalAccess', _85 => _85.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)),
1843
1933
  role: _nullishCoalesce(message.role, () => ( "user")),
1844
1934
  content: message.content
1845
1935
  };
@@ -1891,7 +1981,7 @@ var useAssistantTool = (tool) => {
1891
1981
  const unsub2 = render ? setToolUI(toolName, render) : void 0;
1892
1982
  return () => {
1893
1983
  unsub1();
1894
- _optionalChain([unsub2, 'optionalCall', _86 => _86()]);
1984
+ _optionalChain([unsub2, 'optionalCall', _94 => _94()]);
1895
1985
  };
1896
1986
  }, [registerModelConfigProvider, setToolUI, tool]);
1897
1987
  };
@@ -1977,8 +2067,8 @@ var useActionBarCopy = ({
1977
2067
  const { useMessage, useMessageUtils, useEditComposer } = useMessageContext();
1978
2068
  const hasCopyableContent = useCombinedStore(
1979
2069
  [useMessage, useEditComposer],
1980
- (m, c) => {
1981
- return !c.isEditing && m.message.content.some((c2) => c2.type === "text" && c2.text.length > 0);
2070
+ ({ message }, c) => {
2071
+ return !c.isEditing && (message.role !== "assistant" || message.status.type !== "running") && message.content.some((c2) => c2.type === "text" && c2.text.length > 0);
1982
2072
  }
1983
2073
  );
1984
2074
  const callback = _react.useCallback.call(void 0, () => {
@@ -2030,6 +2120,38 @@ var useActionBarReload = () => {
2030
2120
  return callback;
2031
2121
  };
2032
2122
 
2123
+ // src/primitive-hooks/actionBar/useActionBarSpeak.tsx
2124
+
2125
+ var useActionBarSpeak = () => {
2126
+ const { useThreadActions } = useThreadContext();
2127
+ const { useMessage, useEditComposer, useMessageUtils } = useMessageContext();
2128
+ const hasSpeakableContent = useCombinedStore(
2129
+ [useMessage, useEditComposer],
2130
+ ({ message }, c) => {
2131
+ return !c.isEditing && (message.role !== "assistant" || message.status.type !== "running") && message.content.some((c2) => c2.type === "text" && c2.text.length > 0);
2132
+ }
2133
+ );
2134
+ const callback = _react.useCallback.call(void 0, async () => {
2135
+ const { message } = useMessage.getState();
2136
+ const utt = useThreadActions.getState().speak(message.id);
2137
+ useMessageUtils.getState().addUtterance(utt);
2138
+ }, [useThreadActions, useMessage, useMessageUtils]);
2139
+ if (!hasSpeakableContent) return null;
2140
+ return callback;
2141
+ };
2142
+
2143
+ // src/primitive-hooks/actionBar/useActionBarStopSpeaking.tsx
2144
+
2145
+ var useActionBarStopSpeaking = () => {
2146
+ const { useMessageUtils } = useMessageContext();
2147
+ const isSpeaking = useMessageUtils((u) => u.isSpeaking);
2148
+ const callback = _react.useCallback.call(void 0, async () => {
2149
+ useMessageUtils.getState().stopSpeaking();
2150
+ }, [useMessageUtils]);
2151
+ if (!isSpeaking) return null;
2152
+ return callback;
2153
+ };
2154
+
2033
2155
  // src/primitive-hooks/branchPicker/useBranchPickerCount.tsx
2034
2156
  var useBranchPickerCount = () => {
2035
2157
  const { useMessage } = useMessageContext();
@@ -2169,7 +2291,7 @@ var useMessageIf = (props) => {
2169
2291
  const { useMessage, useMessageUtils } = useMessageContext();
2170
2292
  return useCombinedStore(
2171
2293
  [useMessage, useMessageUtils],
2172
- ({ message, branches, isLast }, { isCopied, isHovering }) => {
2294
+ ({ message, branches, isLast }, { isCopied, isHovering, isSpeaking }) => {
2173
2295
  if (props.hasBranches === true && branches.length < 2) return false;
2174
2296
  if (props.user && message.role !== "user") return false;
2175
2297
  if (props.assistant && message.role !== "assistant") return false;
@@ -2177,6 +2299,8 @@ var useMessageIf = (props) => {
2177
2299
  if (props.lastOrHover === true && !isHovering && !isLast) return false;
2178
2300
  if (props.copied === true && !isCopied) return false;
2179
2301
  if (props.copied === false && isCopied) return false;
2302
+ if (props.speaking === true && !isSpeaking) return false;
2303
+ if (props.speaking === false && isSpeaking) return false;
2180
2304
  return true;
2181
2305
  }
2182
2306
  );
@@ -2246,7 +2370,9 @@ _chunkDCHYNTHIjs.__export.call(void 0, actionBar_exports, {
2246
2370
  Copy: () => ActionBarPrimitiveCopy,
2247
2371
  Edit: () => ActionBarPrimitiveEdit,
2248
2372
  Reload: () => ActionBarPrimitiveReload,
2249
- Root: () => ActionBarPrimitiveRoot
2373
+ Root: () => ActionBarPrimitiveRoot,
2374
+ Speak: () => ActionBarPrimitiveSpeak,
2375
+ StopSpeaking: () => ActionBarPrimitiveStopSpeaking
2250
2376
  });
2251
2377
 
2252
2378
  // src/primitives/actionBar/ActionBarRoot.tsx
@@ -2320,7 +2446,7 @@ var createActionButton = (displayName, useActionButton, forwardProps = []) => {
2320
2446
  ...primitiveProps,
2321
2447
  ref: forwardedRef,
2322
2448
  onClick: _primitive.composeEventHandlers.call(void 0, primitiveProps.onClick, () => {
2323
- _optionalChain([callback, 'optionalCall', _87 => _87()]);
2449
+ _optionalChain([callback, 'optionalCall', _95 => _95()]);
2324
2450
  })
2325
2451
  }
2326
2452
  );
@@ -2348,6 +2474,40 @@ var ActionBarPrimitiveEdit = createActionButton(
2348
2474
  useActionBarEdit
2349
2475
  );
2350
2476
 
2477
+ // src/primitives/actionBar/ActionBarSpeak.tsx
2478
+ var ActionBarPrimitiveSpeak = createActionButton(
2479
+ "ActionBarPrimitive.Speak",
2480
+ useActionBarSpeak
2481
+ );
2482
+
2483
+ // src/primitives/actionBar/ActionBarStopSpeaking.tsx
2484
+
2485
+ var _reactuseescapekeydown = require('@radix-ui/react-use-escape-keydown');
2486
+
2487
+
2488
+
2489
+ var ActionBarPrimitiveStopSpeaking = _react.forwardRef.call(void 0, (props, ref) => {
2490
+ const callback = useActionBarStopSpeaking();
2491
+ _reactuseescapekeydown.useEscapeKeydown.call(void 0, (e) => {
2492
+ if (callback) {
2493
+ e.preventDefault();
2494
+ callback();
2495
+ }
2496
+ });
2497
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2498
+ _reactprimitive.Primitive.button,
2499
+ {
2500
+ type: "button",
2501
+ disabled: !callback,
2502
+ ...props,
2503
+ ref,
2504
+ onClick: _primitive.composeEventHandlers.call(void 0, props.onClick, () => {
2505
+ _optionalChain([callback, 'optionalCall', _96 => _96()]);
2506
+ })
2507
+ }
2508
+ );
2509
+ });
2510
+
2351
2511
  // src/primitives/assistantModal/index.ts
2352
2512
  var assistantModal_exports = {};
2353
2513
  _chunkDCHYNTHIjs.__export.call(void 0, assistantModal_exports, {
@@ -2575,9 +2735,9 @@ var useIsHoveringRef = () => {
2575
2735
  );
2576
2736
  return useManagedRef(callbackRef);
2577
2737
  };
2578
- var MessagePrimitiveRoot = _react.forwardRef.call(void 0, ({ onMouseEnter, onMouseLeave, ...rest }, forwardRef29) => {
2738
+ var MessagePrimitiveRoot = _react.forwardRef.call(void 0, ({ onMouseEnter, onMouseLeave, ...rest }, forwardRef30) => {
2579
2739
  const isHoveringRef = useIsHoveringRef();
2580
- const ref = _reactcomposerefs.useComposedRefs.call(void 0, forwardRef29, isHoveringRef);
2740
+ const ref = _reactcomposerefs.useComposedRefs.call(void 0, forwardRef30, isHoveringRef);
2581
2741
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactprimitive.Primitive.div, { ...rest, ref });
2582
2742
  });
2583
2743
  MessagePrimitiveRoot.displayName = "MessagePrimitive.Root";
@@ -2628,7 +2788,7 @@ var getContentPartState = ({ message }, useContentPart, partIndex) => {
2628
2788
  }
2629
2789
  }
2630
2790
  const status = toContentPartStatus(message, partIndex, part);
2631
- const currentState = _optionalChain([useContentPart, 'optionalAccess', _88 => _88.getState, 'call', _89 => _89()]);
2791
+ const currentState = _optionalChain([useContentPart, 'optionalAccess', _97 => _97.getState, 'call', _98 => _98()]);
2632
2792
  if (currentState && currentState.part === part && currentState.status === status)
2633
2793
  return null;
2634
2794
  return Object.freeze({ part, status });
@@ -2776,7 +2936,7 @@ var MessageContentPartImpl = ({
2776
2936
  };
2777
2937
  var MessageContentPart = _react.memo.call(void 0,
2778
2938
  MessageContentPartImpl,
2779
- (prev, next) => prev.partIndex === next.partIndex && _optionalChain([prev, 'access', _90 => _90.components, 'optionalAccess', _91 => _91.Text]) === _optionalChain([next, 'access', _92 => _92.components, 'optionalAccess', _93 => _93.Text]) && _optionalChain([prev, 'access', _94 => _94.components, 'optionalAccess', _95 => _95.Image]) === _optionalChain([next, 'access', _96 => _96.components, 'optionalAccess', _97 => _97.Image]) && _optionalChain([prev, 'access', _98 => _98.components, 'optionalAccess', _99 => _99.UI]) === _optionalChain([next, 'access', _100 => _100.components, 'optionalAccess', _101 => _101.UI]) && _optionalChain([prev, 'access', _102 => _102.components, 'optionalAccess', _103 => _103.tools]) === _optionalChain([next, 'access', _104 => _104.components, 'optionalAccess', _105 => _105.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])
2780
2940
  );
2781
2941
  var MessagePrimitiveContent = ({
2782
2942
  components
@@ -2856,7 +3016,7 @@ var _reactslot = require('@radix-ui/react-slot');
2856
3016
 
2857
3017
 
2858
3018
  var _reacttextareaautosize = require('react-textarea-autosize'); var _reacttextareaautosize2 = _interopRequireDefault(_reacttextareaautosize);
2859
- var _reactuseescapekeydown = require('@radix-ui/react-use-escape-keydown');
3019
+
2860
3020
 
2861
3021
  var ComposerPrimitiveInput = _react.forwardRef.call(void 0,
2862
3022
  ({
@@ -2891,7 +3051,7 @@ var ComposerPrimitiveInput = _react.forwardRef.call(void 0,
2891
3051
  const { isRunning } = useThread.getState();
2892
3052
  if (!isRunning) {
2893
3053
  e.preventDefault();
2894
- _optionalChain([textareaRef, 'access', _106 => _106.current, 'optionalAccess', _107 => _107.closest, 'call', _108 => _108("form"), 'optionalAccess', _109 => _109.requestSubmit, 'call', _110 => _110()]);
3054
+ _optionalChain([textareaRef, 'access', _115 => _115.current, 'optionalAccess', _116 => _116.closest, 'call', _117 => _117("form"), 'optionalAccess', _118 => _118.requestSubmit, 'call', _119 => _119()]);
2895
3055
  }
2896
3056
  }
2897
3057
  };
@@ -3180,29 +3340,43 @@ var makeEditComposerStore = ({
3180
3340
 
3181
3341
  // src/context/stores/MessageUtils.ts
3182
3342
 
3183
- var makeMessageUtilsStore = () => _zustand.create.call(void 0, (set) => ({
3184
- isCopied: false,
3185
- setIsCopied: (value) => {
3186
- set({ isCopied: value });
3187
- },
3188
- isHovering: false,
3189
- setIsHovering: (value) => {
3190
- set({ isHovering: value });
3191
- }
3192
- }));
3343
+ var makeMessageUtilsStore = () => _zustand.create.call(void 0, (set) => {
3344
+ let utterance = null;
3345
+ return {
3346
+ isCopied: false,
3347
+ setIsCopied: (value) => {
3348
+ set({ isCopied: value });
3349
+ },
3350
+ isHovering: false,
3351
+ setIsHovering: (value) => {
3352
+ set({ isHovering: value });
3353
+ },
3354
+ isSpeaking: false,
3355
+ stopSpeaking: () => {
3356
+ _optionalChain([utterance, 'optionalAccess', _120 => _120.cancel, 'call', _121 => _121()]);
3357
+ },
3358
+ addUtterance: (utt) => {
3359
+ utterance = utt;
3360
+ set({ isSpeaking: true });
3361
+ utt.onEnd(() => {
3362
+ set({ isSpeaking: false });
3363
+ });
3364
+ }
3365
+ };
3366
+ });
3193
3367
 
3194
3368
  // src/context/providers/MessageProvider.tsx
3195
3369
 
3196
3370
  var getIsLast = (messages, message) => {
3197
- return _optionalChain([messages, 'access', _111 => _111[messages.length - 1], 'optionalAccess', _112 => _112.id]) === message.id;
3371
+ return _optionalChain([messages, 'access', _122 => _122[messages.length - 1], 'optionalAccess', _123 => _123.id]) === message.id;
3198
3372
  };
3199
3373
  var getMessageState = (messages, getBranches, useMessage, messageIndex) => {
3200
- const parentId = _nullishCoalesce(_optionalChain([messages, 'access', _113 => _113[messageIndex - 1], 'optionalAccess', _114 => _114.id]), () => ( null));
3374
+ const parentId = _nullishCoalesce(_optionalChain([messages, 'access', _124 => _124[messageIndex - 1], 'optionalAccess', _125 => _125.id]), () => ( null));
3201
3375
  const message = messages[messageIndex];
3202
3376
  if (!message) return null;
3203
3377
  const isLast = getIsLast(messages, message);
3204
3378
  const branches = getBranches(message.id);
3205
- const currentState = _optionalChain([useMessage, 'optionalAccess', _115 => _115.getState, 'call', _116 => _116()]);
3379
+ const currentState = _optionalChain([useMessage, 'optionalAccess', _126 => _126.getState, 'call', _127 => _127()]);
3206
3380
  if (currentState && currentState.message === message && currentState.parentId === parentId && currentState.branches === branches && currentState.isLast === isLast)
3207
3381
  return null;
3208
3382
  return Object.freeze({
@@ -3329,7 +3503,7 @@ var ThreadPrimitiveMessagesImpl = ({
3329
3503
  ThreadPrimitiveMessagesImpl.displayName = "ThreadPrimitive.Messages";
3330
3504
  var ThreadPrimitiveMessages = _react.memo.call(void 0,
3331
3505
  ThreadPrimitiveMessagesImpl,
3332
- (prev, next) => _optionalChain([prev, 'access', _117 => _117.components, 'optionalAccess', _118 => _118.Message]) === _optionalChain([next, 'access', _119 => _119.components, 'optionalAccess', _120 => _120.Message]) && _optionalChain([prev, 'access', _121 => _121.components, 'optionalAccess', _122 => _122.UserMessage]) === _optionalChain([next, 'access', _123 => _123.components, 'optionalAccess', _124 => _124.UserMessage]) && _optionalChain([prev, 'access', _125 => _125.components, 'optionalAccess', _126 => _126.EditComposer]) === _optionalChain([next, 'access', _127 => _127.components, 'optionalAccess', _128 => _128.EditComposer]) && _optionalChain([prev, 'access', _129 => _129.components, 'optionalAccess', _130 => _130.AssistantMessage]) === _optionalChain([next, 'access', _131 => _131.components, 'optionalAccess', _132 => _132.AssistantMessage]) && _optionalChain([prev, 'access', _133 => _133.components, 'optionalAccess', _134 => _134.SystemMessage]) === _optionalChain([next, 'access', _135 => _135.components, 'optionalAccess', _136 => _136.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])
3333
3507
  );
3334
3508
 
3335
3509
  // src/primitives/thread/ThreadScrollToBottom.tsx
@@ -3361,7 +3535,7 @@ var ThreadConfigProvider = ({
3361
3535
  }) => {
3362
3536
  const assistant = useAssistantContext({ optional: true });
3363
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 });
3364
- if (!_optionalChain([config, 'optionalAccess', _137 => _137.runtime])) return configProvider;
3538
+ if (!_optionalChain([config, 'optionalAccess', _148 => _148.runtime])) return configProvider;
3365
3539
  if (assistant) {
3366
3540
  throw new Error(
3367
3541
  "You provided a runtime to <Thread> while simulataneously using <AssistantRuntimeProvider>. This is not allowed."
@@ -3373,24 +3547,37 @@ ThreadConfigProvider.displayName = "ThreadConfigProvider";
3373
3547
 
3374
3548
  // src/ui/assistant-action-bar.tsx
3375
3549
 
3550
+
3551
+
3552
+
3553
+
3554
+
3555
+
3376
3556
  var _lucidereact = require('lucide-react');
3377
3557
 
3378
- var useAllowCopy = () => {
3558
+ var useAllowCopy = (ensureCapability = false) => {
3379
3559
  const { assistantMessage: { allowCopy = true } = {} } = useThreadConfig();
3380
3560
  const { useThread } = useThreadContext();
3381
- const copySupported = useThread((t) => t.capabilities.copy);
3382
- return copySupported && allowCopy;
3561
+ const copySupported = useThread((t) => t.capabilities.unstable_copy);
3562
+ return allowCopy && (!ensureCapability || copySupported);
3563
+ };
3564
+ var useAllowSpeak = (ensureCapability = false) => {
3565
+ const { assistantMessage: { allowSpeak = true } = {} } = useThreadConfig();
3566
+ const { useThread } = useThreadContext();
3567
+ const speakSupported = useThread((t) => t.capabilities.speak);
3568
+ return allowSpeak && (!ensureCapability || speakSupported);
3383
3569
  };
3384
- var useAllowReload = () => {
3570
+ var useAllowReload = (ensureCapability = false) => {
3385
3571
  const { assistantMessage: { allowReload = true } = {} } = useThreadConfig();
3386
3572
  const { useThread } = useThreadContext();
3387
3573
  const reloadSupported = useThread((t) => t.capabilities.reload);
3388
- return reloadSupported && allowReload;
3574
+ return allowReload && (!ensureCapability || reloadSupported);
3389
3575
  };
3390
3576
  var AssistantActionBar = () => {
3391
- const allowCopy = useAllowCopy();
3392
- const allowReload = useAllowReload();
3393
- 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;
3394
3581
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3395
3582
  AssistantActionBarRoot,
3396
3583
  {
@@ -3398,8 +3585,9 @@ var AssistantActionBar = () => {
3398
3585
  autohide: "not-last",
3399
3586
  autohideFloat: "single-branch",
3400
3587
  children: [
3401
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AssistantActionBarCopy, {}),
3402
- /* @__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, {})
3403
3591
  ]
3404
3592
  }
3405
3593
  );
@@ -3412,17 +3600,45 @@ AssistantActionBarRoot.displayName = "AssistantActionBarRoot";
3412
3600
  var AssistantActionBarCopy = _react.forwardRef.call(void 0, (props, ref) => {
3413
3601
  const {
3414
3602
  strings: {
3415
- assistantMessage: { reload: { tooltip = "Copy" } = {} } = {}
3603
+ assistantMessage: { copy: { tooltip = "Copy" } = {} } = {}
3416
3604
  } = {}
3417
3605
  } = useThreadConfig();
3418
- const allowCopy = useAllowCopy();
3419
- if (!allowCopy) return null;
3420
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: [
3421
3607
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, message_exports.If, { copied: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CheckIcon, {}) }),
3422
3608
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, message_exports.If, { copied: false, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CopyIcon, {}) })
3423
3609
  ] }))) }) });
3424
3610
  });
3425
3611
  AssistantActionBarCopy.displayName = "AssistantActionBarCopy";
3612
+ var AssistantActionBarSpeechControl = () => {
3613
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
3614
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, message_exports.If, { speaking: false, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AssistantActionBarSpeak, {}) }),
3615
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, message_exports.If, { speaking: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AssistantActionBarStopSpeaking, {}) })
3616
+ ] });
3617
+ };
3618
+ var AssistantActionBarSpeak = _react.forwardRef.call(void 0, (props, ref) => {
3619
+ const {
3620
+ strings: {
3621
+ assistantMessage: { speak: { tooltip = "Read aloud" } = {} } = {}
3622
+ } = {}
3623
+ } = useThreadConfig();
3624
+ const allowSpeak = useAllowSpeak();
3625
+ if (!allowSpeak) return null;
3626
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, actionBar_exports.Speak, { asChild: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TooltipIconButton, { tooltip, ...props, ref, children: _nullishCoalesce(props.children, () => ( /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.AudioLinesIcon, {}))) }) });
3627
+ });
3628
+ AssistantActionBarSpeak.displayName = "AssistantActionBarSpeak";
3629
+ var AssistantActionBarStopSpeaking = _react.forwardRef.call(void 0, (props, ref) => {
3630
+ const {
3631
+ strings: {
3632
+ assistantMessage: {
3633
+ speak: { stop: { tooltip: stopTooltip = "Stop" } = {} } = {}
3634
+ } = {}
3635
+ } = {}
3636
+ } = useThreadConfig();
3637
+ const allowSpeak = useAllowSpeak();
3638
+ if (!allowSpeak) return null;
3639
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, actionBar_exports.StopSpeaking, { asChild: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TooltipIconButton, { tooltip: stopTooltip, ...props, ref, children: _nullishCoalesce(props.children, () => ( /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.StopCircleIcon, {}))) }) });
3640
+ });
3641
+ AssistantActionBarStopSpeaking.displayName = "AssistantActionBarStopSpeaking";
3426
3642
  var AssistantActionBarReload = _react.forwardRef.call(void 0, (props, ref) => {
3427
3643
  const {
3428
3644
  strings: {
@@ -3437,7 +3653,10 @@ AssistantActionBarReload.displayName = "AssistantActionBarReload";
3437
3653
  var exports = {
3438
3654
  Root: AssistantActionBarRoot,
3439
3655
  Reload: AssistantActionBarReload,
3440
- Copy: AssistantActionBarCopy
3656
+ Copy: AssistantActionBarCopy,
3657
+ Speak: AssistantActionBarSpeak,
3658
+ StopSpeaking: AssistantActionBarStopSpeaking,
3659
+ SpeechControl: AssistantActionBarSpeechControl
3441
3660
  };
3442
3661
  var assistant_action_bar_default = Object.assign(
3443
3662
  AssistantActionBar,
@@ -3577,7 +3796,7 @@ var AssistantMessageContent = _react.forwardRef.call(void 0, ({ components: comp
3577
3796
  {
3578
3797
  components: {
3579
3798
  ...componentsProp,
3580
- Text: _nullishCoalesce(_nullishCoalesce(_optionalChain([componentsProp, 'optionalAccess', _138 => _138.Text]), () => ( components.Text)), () => ( content_part_default.Text))
3799
+ Text: _nullishCoalesce(_nullishCoalesce(_optionalChain([componentsProp, 'optionalAccess', _149 => _149.Text]), () => ( components.Text)), () => ( content_part_default.Text))
3581
3800
  }
3582
3801
  }
3583
3802
  ) });
@@ -3754,7 +3973,7 @@ var ThreadWelcomeSuggestion = ({
3754
3973
  };
3755
3974
  var ThreadWelcomeSuggestions = () => {
3756
3975
  const { welcome: { suggestions } = {} } = useThreadConfig();
3757
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThreadWelcomeSuggestionContainer, { children: _optionalChain([suggestions, 'optionalAccess', _139 => _139.map, 'call', _140 => _140((suggestion, idx) => {
3976
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThreadWelcomeSuggestionContainer, { children: _optionalChain([suggestions, 'optionalAccess', _150 => _150.map, 'call', _151 => _151((suggestion, idx) => {
3758
3977
  const key = `${suggestion.prompt}-${idx}`;
3759
3978
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThreadWelcomeSuggestion, { suggestion }, key);
3760
3979
  })]) });
@@ -3777,14 +3996,14 @@ var thread_welcome_default = Object.assign(ThreadWelcome, exports6);
3777
3996
 
3778
3997
 
3779
3998
 
3780
- var useAllowEdit = () => {
3999
+ var useAllowEdit = (ensureCapability = false) => {
3781
4000
  const { userMessage: { allowEdit = true } = {} } = useThreadConfig();
3782
4001
  const { useThread } = useThreadContext();
3783
4002
  const editSupported = useThread((t) => t.capabilities.edit);
3784
- return editSupported && allowEdit;
4003
+ return allowEdit && (!ensureCapability || editSupported);
3785
4004
  };
3786
4005
  var UserActionBar = () => {
3787
- const allowEdit = useAllowEdit();
4006
+ const allowEdit = useAllowEdit(true);
3788
4007
  if (!allowEdit) return null;
3789
4008
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, UserActionBarRoot, { hideWhenRunning: true, autohide: "not-last", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, UserActionBarEdit, {}) });
3790
4009
  };
@@ -3832,7 +4051,7 @@ var UserMessageContent = _react.forwardRef.call(void 0,
3832
4051
  {
3833
4052
  components: {
3834
4053
  ...components,
3835
- Text: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _141 => _141.Text]), () => ( content_part_default.Text))
4054
+ Text: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _152 => _152.Text]), () => ( content_part_default.Text))
3836
4055
  }
3837
4056
  }
3838
4057
  ) });
@@ -3934,10 +4153,10 @@ var ThreadMessages = ({ components, ...rest }) => {
3934
4153
  thread_exports.Messages,
3935
4154
  {
3936
4155
  components: {
3937
- UserMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _142 => _142.UserMessage]), () => ( user_message_default)),
3938
- EditComposer: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _143 => _143.EditComposer]), () => ( edit_composer_default)),
3939
- AssistantMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _144 => _144.AssistantMessage]), () => ( assistant_message_default)),
3940
- SystemMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _145 => _145.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))
3941
4160
  },
3942
4161
  ...rest
3943
4162
  }
@@ -4116,5 +4335,8 @@ var assistant_modal_default = Object.assign(AssistantModal, exports11);
4116
4335
 
4117
4336
 
4118
4337
 
4119
- exports.ActionBarPrimitive = actionBar_exports; exports.AssistantActionBar = assistant_action_bar_default; exports.AssistantMessage = assistant_message_default; exports.AssistantModal = assistant_modal_default; exports.AssistantModalPrimitive = assistantModal_exports; exports.AssistantRuntimeProvider = AssistantRuntimeProvider; exports.BranchPicker = branch_picker_default; exports.BranchPickerPrimitive = branchPicker_exports; exports.Composer = composer_default; exports.ComposerPrimitive = composer_exports; exports.ContentPart = content_part_default; exports.ContentPartPrimitive = contentPart_exports; exports.EdgeChatAdapter = EdgeChatAdapter; exports.EditComposer = edit_composer_default; exports.ExternalStoreRuntime = ExternalStoreRuntime; exports.INTERNAL = internal_exports; exports.MessagePrimitive = message_exports; exports.Thread = thread_default; exports.ThreadConfigProvider = ThreadConfigProvider; exports.ThreadPrimitive = thread_exports; exports.ThreadWelcome = thread_welcome_default; exports.UserActionBar = user_action_bar_default; exports.UserMessage = user_message_default; exports.fromCoreMessage = fromCoreMessage; exports.fromCoreMessages = fromCoreMessages; exports.fromLanguageModelMessages = fromLanguageModelMessages; exports.fromLanguageModelTools = fromLanguageModelTools; exports.getExternalStoreMessage = getExternalStoreMessage; exports.makeAssistantTool = makeAssistantTool; exports.makeAssistantToolUI = makeAssistantToolUI; exports.streamUtils = streamUtils; exports.subscribeToMainThread = subscribeToMainThread; exports.toCoreMessage = _chunkBQ3MRWUVjs.toCoreMessage; exports.toCoreMessages = _chunkBQ3MRWUVjs.toCoreMessages; exports.toLanguageModelMessages = _chunkBQ3MRWUVjs.toLanguageModelMessages; exports.toLanguageModelTools = _chunkBQ3MRWUVjs.toLanguageModelTools; exports.useActionBarCopy = useActionBarCopy; exports.useActionBarEdit = useActionBarEdit; exports.useActionBarReload = useActionBarReload; exports.useAppendMessage = useAppendMessage; exports.useAssistantContext = useAssistantContext; exports.useAssistantInstructions = useAssistantInstructions; exports.useAssistantTool = useAssistantTool; exports.useAssistantToolUI = useAssistantToolUI; exports.useBranchPickerCount = useBranchPickerCount; exports.useBranchPickerNext = useBranchPickerNext; exports.useBranchPickerNumber = useBranchPickerNumber; exports.useBranchPickerPrevious = useBranchPickerPrevious; exports.useComposerCancel = useComposerCancel; exports.useComposerContext = useComposerContext; exports.useComposerIf = useComposerIf; exports.useComposerSend = useComposerSend; exports.useContentPartContext = useContentPartContext; exports.useContentPartDisplay = useContentPartDisplay; exports.useContentPartImage = useContentPartImage; exports.useContentPartText = useContentPartText; exports.useDangerousInBrowserRuntime = useDangerousInBrowserRuntime; exports.useEdgeRuntime = useEdgeRuntime; exports.useExternalStoreRuntime = useExternalStoreRuntime; exports.useLocalRuntime = useLocalRuntime; exports.useMessageContext = useMessageContext; exports.useMessageIf = useMessageIf; exports.useSwitchToNewThread = useSwitchToNewThread; exports.useThreadConfig = useThreadConfig; exports.useThreadContext = useThreadContext; exports.useThreadEmpty = useThreadEmpty; exports.useThreadIf = useThreadIf; exports.useThreadScrollToBottom = useThreadScrollToBottom; exports.useThreadSuggestion = useThreadSuggestion;
4338
+
4339
+
4340
+
4341
+ exports.ActionBarPrimitive = actionBar_exports; exports.AssistantActionBar = assistant_action_bar_default; exports.AssistantMessage = assistant_message_default; exports.AssistantModal = assistant_modal_default; exports.AssistantModalPrimitive = assistantModal_exports; exports.AssistantRuntimeProvider = AssistantRuntimeProvider; exports.BranchPicker = branch_picker_default; exports.BranchPickerPrimitive = branchPicker_exports; exports.Composer = composer_default; exports.ComposerPrimitive = composer_exports; exports.ContentPart = content_part_default; exports.ContentPartPrimitive = contentPart_exports; exports.EdgeChatAdapter = EdgeChatAdapter; exports.EditComposer = edit_composer_default; exports.ExternalStoreRuntime = ExternalStoreRuntime; exports.INTERNAL = internal_exports; exports.MessagePrimitive = message_exports; exports.Thread = thread_default; exports.ThreadConfigProvider = ThreadConfigProvider; exports.ThreadPrimitive = thread_exports; exports.ThreadWelcome = thread_welcome_default; exports.UserActionBar = user_action_bar_default; exports.UserMessage = user_message_default; exports.WebSpeechSynthesisAdapter = WebSpeechSynthesisAdapter; exports.fromCoreMessage = fromCoreMessage; exports.fromCoreMessages = fromCoreMessages; exports.fromLanguageModelMessages = fromLanguageModelMessages; exports.fromLanguageModelTools = fromLanguageModelTools; exports.getExternalStoreMessage = getExternalStoreMessage; exports.makeAssistantTool = makeAssistantTool; exports.makeAssistantToolUI = makeAssistantToolUI; exports.streamUtils = streamUtils; exports.subscribeToMainThread = subscribeToMainThread; exports.toCoreMessage = _chunkBQ3MRWUVjs.toCoreMessage; exports.toCoreMessages = _chunkBQ3MRWUVjs.toCoreMessages; exports.toLanguageModelMessages = _chunkBQ3MRWUVjs.toLanguageModelMessages; exports.toLanguageModelTools = _chunkBQ3MRWUVjs.toLanguageModelTools; exports.useActionBarCopy = useActionBarCopy; exports.useActionBarEdit = useActionBarEdit; exports.useActionBarReload = useActionBarReload; exports.useActionBarSpeak = useActionBarSpeak; exports.useActionBarStopSpeaking = useActionBarStopSpeaking; exports.useAppendMessage = useAppendMessage; exports.useAssistantContext = useAssistantContext; exports.useAssistantInstructions = useAssistantInstructions; exports.useAssistantTool = useAssistantTool; exports.useAssistantToolUI = useAssistantToolUI; exports.useBranchPickerCount = useBranchPickerCount; exports.useBranchPickerNext = useBranchPickerNext; exports.useBranchPickerNumber = useBranchPickerNumber; exports.useBranchPickerPrevious = useBranchPickerPrevious; exports.useComposerCancel = useComposerCancel; exports.useComposerContext = useComposerContext; exports.useComposerIf = useComposerIf; exports.useComposerSend = useComposerSend; exports.useContentPartContext = useContentPartContext; exports.useContentPartDisplay = useContentPartDisplay; exports.useContentPartImage = useContentPartImage; exports.useContentPartText = useContentPartText; exports.useDangerousInBrowserRuntime = useDangerousInBrowserRuntime; exports.useEdgeRuntime = useEdgeRuntime; exports.useExternalStoreRuntime = useExternalStoreRuntime; exports.useLocalRuntime = useLocalRuntime; exports.useMessageContext = useMessageContext; exports.useMessageIf = useMessageIf; exports.useSwitchToNewThread = useSwitchToNewThread; exports.useThreadConfig = useThreadConfig; exports.useThreadContext = useThreadContext; exports.useThreadEmpty = useThreadEmpty; exports.useThreadIf = useThreadIf; exports.useThreadScrollToBottom = useThreadScrollToBottom; exports.useThreadSuggestion = useThreadSuggestion;
4120
4342
  //# sourceMappingURL=index.js.map