@assistant-ui/react 0.5.40 → 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
@@ -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