@assistant-ui/react 0.5.41 → 0.5.45

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
@@ -164,6 +164,7 @@ var makeComposerStore = (useThreadRuntime) => {
164
164
  var getThreadStateFromRuntime = (runtime) => {
165
165
  const lastMessage = runtime.messages.at(-1);
166
166
  return Object.freeze({
167
+ threadId: runtime.threadId,
167
168
  capabilities: runtime.capabilities,
168
169
  isDisabled: runtime.isDisabled,
169
170
  isRunning: _optionalChain([lastMessage, 'optionalAccess', _10 => _10.role]) !== "assistant" ? false : lastMessage.status.type === "running"
@@ -636,6 +637,9 @@ var useSmooth = (state, smooth = false) => {
636
637
  setDisplayedText(text2);
637
638
  _optionalChain([useSmoothStatus2, 'optionalAccess', _29 => _29.setState, 'call', _30 => _30(text2 !== state.part.text ? SMOOTH_STATUS : state.status)]);
638
639
  });
640
+ _react.useEffect.call(void 0, () => {
641
+ _optionalChain([useSmoothStatus2, 'optionalAccess', _31 => _31.setState, 'call', _32 => _32(text !== displayedText ? SMOOTH_STATUS : state.status)]);
642
+ }, [useSmoothStatus2, text, displayedText, state.status]);
639
643
  const [animatorRef] = _react.useState.call(void 0,
640
644
  new TextStreamAnimator(text, setText)
641
645
  );
@@ -828,7 +832,7 @@ var fromLanguageModelMessages = (lm, { mergeRoundtrips }) => {
828
832
  });
829
833
  if (mergeRoundtrips) {
830
834
  const previousMessage = messages[messages.length - 1];
831
- if (_optionalChain([previousMessage, 'optionalAccess', _31 => _31.role]) === "assistant") {
835
+ if (_optionalChain([previousMessage, 'optionalAccess', _33 => _33.role]) === "assistant") {
832
836
  previousMessage.content.push(...newContent);
833
837
  break;
834
838
  }
@@ -841,7 +845,7 @@ var fromLanguageModelMessages = (lm, { mergeRoundtrips }) => {
841
845
  }
842
846
  case "tool": {
843
847
  const previousMessage = messages[messages.length - 1];
844
- if (_optionalChain([previousMessage, 'optionalAccess', _32 => _32.role]) !== "assistant")
848
+ if (_optionalChain([previousMessage, 'optionalAccess', _34 => _34.role]) !== "assistant")
845
849
  throw new Error(
846
850
  "A tool message must be preceded by an assistant message."
847
851
  );
@@ -1070,61 +1074,14 @@ var useEdgeRuntime = ({
1070
1074
  };
1071
1075
 
1072
1076
  // src/runtimes/local/shouldContinue.tsx
1073
- var shouldContinue = (result) => _optionalChain([result, 'access', _33 => _33.status, 'optionalAccess', _34 => _34.type]) === "requires-action" && result.status.reason === "tool-calls" && result.content.every((c) => c.type !== "tool-call" || !!c.result);
1074
-
1075
- // src/utils/getThreadMessageText.tsx
1076
- var getThreadMessageText = (message) => {
1077
- const textParts = message.content.filter(
1078
- (part) => part.type === "text"
1079
- );
1080
- return textParts.map((part) => part.text).join("\n\n");
1081
- };
1082
-
1083
- // src/runtimes/speech/WebSpeechSynthesisAdapter.ts
1084
- var WebSpeechSynthesisAdapter = class {
1085
- speak(message) {
1086
- const text = getThreadMessageText(message);
1087
- const utterance = new SpeechSynthesisUtterance(text);
1088
- let ended = false;
1089
- const endHandlers = /* @__PURE__ */ new Set();
1090
- const handleEnd = () => {
1091
- if (ended) return;
1092
- ended = true;
1093
- endHandlers.forEach((handler) => handler());
1094
- };
1095
- utterance.addEventListener("end", handleEnd);
1096
- utterance.addEventListener("error", handleEnd);
1097
- window.speechSynthesis.speak(utterance);
1098
- return {
1099
- stop: () => {
1100
- window.speechSynthesis.cancel();
1101
- handleEnd();
1102
- },
1103
- onEnd: (callback) => {
1104
- if (ended) {
1105
- let cancelled = false;
1106
- queueMicrotask(() => {
1107
- if (!cancelled) callback();
1108
- });
1109
- return () => {
1110
- cancelled = true;
1111
- };
1112
- } else {
1113
- endHandlers.add(callback);
1114
- return () => {
1115
- endHandlers.delete(callback);
1116
- };
1117
- }
1118
- }
1119
- };
1120
- }
1121
- };
1077
+ var shouldContinue = (result) => _optionalChain([result, 'access', _35 => _35.status, 'optionalAccess', _36 => _36.type]) === "requires-action" && result.status.reason === "tool-calls" && result.content.every((c) => c.type !== "tool-call" || !!c.result);
1122
1078
 
1123
1079
  // src/runtimes/local/LocalThreadRuntime.tsx
1124
1080
  var LocalThreadRuntime = (_class5 = class {
1125
1081
  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);
1126
1082
  this.configProvider = configProvider;
1127
1083
  this.adapter = adapter;
1084
+ this.threadId = generateId();
1128
1085
  this.options = options;
1129
1086
  if (initialMessages) {
1130
1087
  let parentId = null;
@@ -1146,6 +1103,7 @@ var LocalThreadRuntime = (_class5 = class {
1146
1103
  unstable_copy: true,
1147
1104
  speak: false
1148
1105
  }}
1106
+
1149
1107
  __init15() {this.isDisabled = false}
1150
1108
  get messages() {
1151
1109
  return this.repository.getMessages();
@@ -1158,9 +1116,12 @@ var LocalThreadRuntime = (_class5 = class {
1158
1116
  }
1159
1117
  }}
1160
1118
 
1119
+ get options() {
1120
+ return this._options;
1121
+ }
1161
1122
  set options({ initialMessages, ...options }) {
1162
1123
  this._options = options;
1163
- const canSpeak = _optionalChain([options, 'access', _35 => _35.adapters, 'optionalAccess', _36 => _36.speech]) !== void 0;
1124
+ const canSpeak = _optionalChain([options, 'access', _37 => _37.adapters, 'optionalAccess', _38 => _38.speech]) !== void 0;
1164
1125
  if (this.capabilities.speak !== canSpeak) {
1165
1126
  this.capabilities.speak = canSpeak;
1166
1127
  this.notifySubscribers();
@@ -1204,18 +1165,18 @@ var LocalThreadRuntime = (_class5 = class {
1204
1165
  }
1205
1166
  async performRoundtrip(parentId, message) {
1206
1167
  const messages = this.repository.getMessages();
1207
- _optionalChain([this, 'access', _37 => _37.abortController, 'optionalAccess', _38 => _38.abort, 'call', _39 => _39()]);
1168
+ _optionalChain([this, 'access', _39 => _39.abortController, 'optionalAccess', _40 => _40.abort, 'call', _41 => _41()]);
1208
1169
  this.abortController = new AbortController();
1209
1170
  const initialContent = message.content;
1210
- const initialRoundtrips = _optionalChain([message, 'access', _40 => _40.metadata, 'optionalAccess', _41 => _41.roundtrips]);
1211
- const initalCustom = _optionalChain([message, 'access', _42 => _42.metadata, 'optionalAccess', _43 => _43.custom]);
1171
+ const initialRoundtrips = _optionalChain([message, 'access', _42 => _42.metadata, 'optionalAccess', _43 => _43.roundtrips]);
1172
+ const initalCustom = _optionalChain([message, 'access', _44 => _44.metadata, 'optionalAccess', _45 => _45.custom]);
1212
1173
  const updateMessage = (m) => {
1213
1174
  message = {
1214
1175
  ...message,
1215
1176
  ...m.content ? { content: [...initialContent, ..._nullishCoalesce(m.content, () => ( []))] } : void 0,
1216
1177
  status: _nullishCoalesce(m.status, () => ( message.status)),
1217
1178
  // TODO deprecated, remove in v0.6
1218
- ..._optionalChain([m, 'access', _44 => _44.metadata, 'optionalAccess', _45 => _45.roundtrips]) ? {
1179
+ ..._optionalChain([m, 'access', _46 => _46.metadata, 'optionalAccess', _47 => _47.roundtrips]) ? {
1219
1180
  roundtrips: [
1220
1181
  ..._nullishCoalesce(initialRoundtrips, () => ( [])),
1221
1182
  ...m.metadata.roundtrips
@@ -1230,7 +1191,7 @@ var LocalThreadRuntime = (_class5 = class {
1230
1191
  ...m.metadata.roundtrips
1231
1192
  ]
1232
1193
  } : void 0,
1233
- ..._optionalChain([m, 'access', _46 => _46.metadata, 'optionalAccess', _47 => _47.custom]) ? {
1194
+ ..._optionalChain([m, 'access', _48 => _48.metadata, 'optionalAccess', _49 => _49.custom]) ? {
1234
1195
  custom: { ..._nullishCoalesce(initalCustom, () => ( {})), ...m.metadata.custom }
1235
1196
  } : void 0
1236
1197
  }
@@ -1239,8 +1200,8 @@ var LocalThreadRuntime = (_class5 = class {
1239
1200
  this.repository.addOrUpdateMessage(parentId, message);
1240
1201
  this.notifySubscribers();
1241
1202
  };
1242
- const maxToolRoundtrips = _nullishCoalesce(this._options.maxToolRoundtrips, () => ( 1));
1243
- const toolRoundtrips = _nullishCoalesce(_optionalChain([message, 'access', _48 => _48.metadata, 'optionalAccess', _49 => _49.roundtrips, 'optionalAccess', _50 => _50.length]), () => ( 0));
1203
+ const maxToolRoundtrips = _nullishCoalesce(this.options.maxToolRoundtrips, () => ( 1));
1204
+ const toolRoundtrips = _nullishCoalesce(_optionalChain([message, 'access', _50 => _50.metadata, 'optionalAccess', _51 => _51.roundtrips, 'optionalAccess', _52 => _52.length]), () => ( 0));
1244
1205
  if (toolRoundtrips > maxToolRoundtrips) {
1245
1206
  updateMessage({
1246
1207
  status: {
@@ -1334,10 +1295,24 @@ var LocalThreadRuntime = (_class5 = class {
1334
1295
  this.performRoundtrip(parentId, message);
1335
1296
  }
1336
1297
  }
1298
+ // TODO lift utterance state to thread runtime
1299
+
1337
1300
  speak(messageId) {
1301
+ const adapter = _optionalChain([this, 'access', _53 => _53.options, 'access', _54 => _54.adapters, 'optionalAccess', _55 => _55.speech]);
1302
+ if (!adapter) throw new Error("Speech adapter not configured");
1338
1303
  const { message } = this.repository.getMessage(messageId);
1339
- const adapter = new WebSpeechSynthesisAdapter();
1340
- return adapter.speak(message);
1304
+ if (this._utterance) {
1305
+ this._utterance.cancel();
1306
+ this._utterance = void 0;
1307
+ }
1308
+ const utterance = adapter.speak(message);
1309
+ utterance.onEnd(() => {
1310
+ if (this._utterance === utterance) {
1311
+ this._utterance = void 0;
1312
+ }
1313
+ });
1314
+ this._utterance = utterance;
1315
+ return this._utterance;
1341
1316
  }
1342
1317
  export() {
1343
1318
  return this.repository.export();
@@ -1384,7 +1359,7 @@ var LocalRuntime = class extends BaseAssistantRuntime {
1384
1359
  const messages = fromCoreMessages(initialMessages);
1385
1360
  this.thread.import({
1386
1361
  messages: messages.map((m, idx) => ({
1387
- parentId: _nullishCoalesce(_optionalChain([messages, 'access', _51 => _51[idx - 1], 'optionalAccess', _52 => _52.id]), () => ( null)),
1362
+ parentId: _nullishCoalesce(_optionalChain([messages, 'access', _56 => _56[idx - 1], 'optionalAccess', _57 => _57.id]), () => ( null)),
1388
1363
  message: m
1389
1364
  }))
1390
1365
  });
@@ -1431,11 +1406,12 @@ var getAutoStatus = (isLast, isRunning) => isLast && isRunning ? AUTO_STATUS_RUN
1431
1406
 
1432
1407
  // src/runtimes/external-store/ThreadMessageLike.tsx
1433
1408
  var fromThreadMessageLike = (like, fallbackId, fallbackStatus) => {
1434
- const { role, content, id, createdAt, status } = like;
1409
+ const { role, id, createdAt, status } = like;
1435
1410
  const common = {
1436
1411
  id: _nullishCoalesce(id, () => ( fallbackId)),
1437
1412
  createdAt: _nullishCoalesce(createdAt, () => ( /* @__PURE__ */ new Date()))
1438
1413
  };
1414
+ const content = typeof like.content === "string" ? [{ type: "text", text: like.content }] : like.content;
1439
1415
  switch (role) {
1440
1416
  case "assistant":
1441
1417
  return {
@@ -1445,6 +1421,8 @@ var fromThreadMessageLike = (like, fallbackId, fallbackStatus) => {
1445
1421
  const type = part.type;
1446
1422
  switch (type) {
1447
1423
  case "text":
1424
+ if (part.text.trim().length === 0) return null;
1425
+ return part;
1448
1426
  case "ui":
1449
1427
  return part;
1450
1428
  case "tool-call": {
@@ -1459,7 +1437,7 @@ var fromThreadMessageLike = (like, fallbackId, fallbackStatus) => {
1459
1437
  throw new Error(`Unknown content part type: ${unhandledType}`);
1460
1438
  }
1461
1439
  }
1462
- }),
1440
+ }).filter((c) => !!c),
1463
1441
  status: _nullishCoalesce(status, () => ( fallbackStatus))
1464
1442
  };
1465
1443
  case "user":
@@ -1497,9 +1475,17 @@ var fromThreadMessageLike = (like, fallbackId, fallbackStatus) => {
1497
1475
  }
1498
1476
  };
1499
1477
 
1478
+ // src/utils/getThreadMessageText.tsx
1479
+ var getThreadMessageText = (message) => {
1480
+ const textParts = message.content.filter(
1481
+ (part) => part.type === "text"
1482
+ );
1483
+ return textParts.map((part) => part.text).join("\n\n");
1484
+ };
1485
+
1500
1486
  // src/runtimes/external-store/ExternalStoreThreadRuntime.tsx
1501
1487
  var hasUpcomingMessage = (isRunning, messages) => {
1502
- return isRunning && _optionalChain([messages, 'access', _53 => _53[messages.length - 1], 'optionalAccess', _54 => _54.role]) !== "assistant";
1488
+ return isRunning && _optionalChain([messages, 'access', _58 => _58[messages.length - 1], 'optionalAccess', _59 => _59.role]) !== "assistant";
1503
1489
  };
1504
1490
  var ExternalStoreThreadRuntime = (_class7 = class {
1505
1491
  __init18() {this._subscriptions = /* @__PURE__ */ new Set()}
@@ -1516,22 +1502,27 @@ var ExternalStoreThreadRuntime = (_class7 = class {
1516
1502
  get capabilities() {
1517
1503
  return this._capabilities;
1518
1504
  }
1519
- __init22() {this.messages = []}
1520
- __init23() {this.isDisabled = false}
1521
- __init24() {this.converter = new ThreadMessageConverter()}
1522
1505
 
1523
- __init25() {this.composer = {
1506
+
1507
+
1508
+ __init22() {this.converter = new ThreadMessageConverter()}
1509
+
1510
+ __init23() {this.composer = {
1524
1511
  text: "",
1525
1512
  setText: (value) => {
1526
1513
  this.composer.text = value;
1527
1514
  this.notifySubscribers();
1528
1515
  }
1529
1516
  }}
1530
- constructor(store) {;_class7.prototype.__init18.call(this);_class7.prototype.__init19.call(this);_class7.prototype.__init20.call(this);_class7.prototype.__init21.call(this);_class7.prototype.__init22.call(this);_class7.prototype.__init23.call(this);_class7.prototype.__init24.call(this);_class7.prototype.__init25.call(this);_class7.prototype.__init26.call(this);
1517
+ constructor(store) {;_class7.prototype.__init18.call(this);_class7.prototype.__init19.call(this);_class7.prototype.__init20.call(this);_class7.prototype.__init21.call(this);_class7.prototype.__init22.call(this);_class7.prototype.__init23.call(this);_class7.prototype.__init24.call(this);
1531
1518
  this.store = store;
1532
1519
  }
1520
+ get store() {
1521
+ return this._store;
1522
+ }
1533
1523
  set store(store) {
1534
1524
  if (this._store === store) return;
1525
+ this.threadId = _nullishCoalesce(_nullishCoalesce(store.threadId, () => ( this.threadId)), () => ( generateId()));
1535
1526
  const isRunning = _nullishCoalesce(store.isRunning, () => ( false));
1536
1527
  this.isDisabled = _nullishCoalesce(store.isDisabled, () => ( false));
1537
1528
  const oldStore = this._store;
@@ -1541,7 +1532,7 @@ var ExternalStoreThreadRuntime = (_class7 = class {
1541
1532
  edit: this._store.onEdit !== void 0,
1542
1533
  reload: this._store.onReload !== void 0,
1543
1534
  cancel: this._store.onCancel !== void 0,
1544
- unstable_copy: _optionalChain([this, 'access', _58 => _58._store, 'access', _59 => _59.unstable_capabilities, 'optionalAccess', _60 => _60.copy]) !== null,
1535
+ unstable_copy: _optionalChain([this, 'access', _63 => _63._store, 'access', _64 => _64.unstable_capabilities, 'optionalAccess', _65 => _65.copy]) !== null,
1545
1536
  speak: this._store.onSpeak !== void 0
1546
1537
  };
1547
1538
  if (oldStore) {
@@ -1569,7 +1560,7 @@ var ExternalStoreThreadRuntime = (_class7 = class {
1569
1560
  for (let i = 0; i < messages.length; i++) {
1570
1561
  const message = messages[i];
1571
1562
  const parent = messages[i - 1];
1572
- this.repository.addOrUpdateMessage(_nullishCoalesce(_optionalChain([parent, 'optionalAccess', _61 => _61.id]), () => ( null)), message);
1563
+ this.repository.addOrUpdateMessage(_nullishCoalesce(_optionalChain([parent, 'optionalAccess', _66 => _66.id]), () => ( null)), message);
1573
1564
  }
1574
1565
  if (this.assistantOptimisticId) {
1575
1566
  this.repository.deleteMessage(this.assistantOptimisticId);
@@ -1577,7 +1568,7 @@ var ExternalStoreThreadRuntime = (_class7 = class {
1577
1568
  }
1578
1569
  if (hasUpcomingMessage(isRunning, messages)) {
1579
1570
  this.assistantOptimisticId = this.repository.appendOptimisticMessage(
1580
- _nullishCoalesce(_optionalChain([messages, 'access', _62 => _62.at, 'call', _63 => _63(-1), 'optionalAccess', _64 => _64.id]), () => ( null)),
1571
+ _nullishCoalesce(_optionalChain([messages, 'access', _67 => _67.at, 'call', _68 => _68(-1), 'optionalAccess', _69 => _69.id]), () => ( null)),
1581
1572
  {
1582
1573
  role: "assistant",
1583
1574
  content: []
@@ -1585,7 +1576,7 @@ var ExternalStoreThreadRuntime = (_class7 = class {
1585
1576
  );
1586
1577
  }
1587
1578
  this.repository.resetHead(
1588
- _nullishCoalesce(_nullishCoalesce(this.assistantOptimisticId, () => ( _optionalChain([messages, 'access', _65 => _65.at, 'call', _66 => _66(-1), 'optionalAccess', _67 => _67.id]))), () => ( null))
1579
+ _nullishCoalesce(_nullishCoalesce(this.assistantOptimisticId, () => ( _optionalChain([messages, 'access', _70 => _70.at, 'call', _71 => _71(-1), 'optionalAccess', _72 => _72.id]))), () => ( null))
1589
1580
  );
1590
1581
  this.messages = this.repository.getMessages();
1591
1582
  this.notifySubscribers();
@@ -1603,7 +1594,7 @@ var ExternalStoreThreadRuntime = (_class7 = class {
1603
1594
  this.updateMessages(this.repository.getMessages());
1604
1595
  }
1605
1596
  async append(message) {
1606
- if (message.parentId !== (_nullishCoalesce(_optionalChain([this, 'access', _68 => _68.messages, 'access', _69 => _69.at, 'call', _70 => _70(-1), 'optionalAccess', _71 => _71.id]), () => ( null)))) {
1597
+ if (message.parentId !== (_nullishCoalesce(_optionalChain([this, 'access', _73 => _73.messages, 'access', _74 => _74.at, 'call', _75 => _75(-1), 'optionalAccess', _76 => _76.id]), () => ( null)))) {
1607
1598
  if (!this._store.onEdit)
1608
1599
  throw new Error("Runtime does not support editing messages.");
1609
1600
  await this._store.onEdit(message);
@@ -1626,7 +1617,7 @@ var ExternalStoreThreadRuntime = (_class7 = class {
1626
1617
  }
1627
1618
  let messages = this.repository.getMessages();
1628
1619
  const previousMessage = messages[messages.length - 1];
1629
- if (_optionalChain([previousMessage, 'optionalAccess', _72 => _72.role]) === "user" && previousMessage.id === _optionalChain([messages, 'access', _73 => _73.at, 'call', _74 => _74(-1), 'optionalAccess', _75 => _75.id])) {
1620
+ if (_optionalChain([previousMessage, 'optionalAccess', _77 => _77.role]) === "user" && previousMessage.id === _optionalChain([messages, 'access', _78 => _78.at, 'call', _79 => _79(-1), 'optionalAccess', _80 => _80.id])) {
1630
1621
  this.repository.deleteMessage(previousMessage.id);
1631
1622
  if (!this.composer.text.trim()) {
1632
1623
  this.composer.setText(getThreadMessageText(previousMessage));
@@ -1654,8 +1645,8 @@ var ExternalStoreThreadRuntime = (_class7 = class {
1654
1645
  this._subscriptions.add(callback);
1655
1646
  return () => this._subscriptions.delete(callback);
1656
1647
  }
1657
- __init26() {this.updateMessages = (messages) => {
1658
- _optionalChain([this, 'access', _76 => _76._store, 'access', _77 => _77.setMessages, 'optionalCall', _78 => _78(
1648
+ __init24() {this.updateMessages = (messages) => {
1649
+ _optionalChain([this, 'access', _81 => _81._store, 'access', _82 => _82.setMessages, 'optionalCall', _83 => _83(
1659
1650
  messages.flatMap(getExternalStoreMessage).filter((m) => m != null)
1660
1651
  )]);
1661
1652
  }}
@@ -1663,9 +1654,12 @@ var ExternalStoreThreadRuntime = (_class7 = class {
1663
1654
 
1664
1655
  // src/runtimes/external-store/ExternalStoreRuntime.tsx
1665
1656
  var ExternalStoreRuntime = (_class8 = class extends BaseAssistantRuntime {
1666
- __init27() {this._proxyConfigProvider = new ProxyConfigProvider()}
1657
+ __init25() {this._proxyConfigProvider = new ProxyConfigProvider()}
1667
1658
  constructor(store) {
1668
- super(new ExternalStoreThreadRuntime(store));_class8.prototype.__init27.call(this);;
1659
+ super(new ExternalStoreThreadRuntime(store));_class8.prototype.__init25.call(this);;
1660
+ }
1661
+ get store() {
1662
+ return this.thread.store;
1669
1663
  }
1670
1664
  set store(store) {
1671
1665
  this.thread.store = store;
@@ -1707,6 +1701,153 @@ var useExternalStoreRuntime = (store) => {
1707
1701
  return runtime;
1708
1702
  };
1709
1703
 
1704
+ // src/runtimes/external-store/external-message-converter.tsx
1705
+
1706
+ var joinExternalMessages = (messages) => {
1707
+ const assistantMessage = {
1708
+ role: "assistant",
1709
+ content: []
1710
+ };
1711
+ for (const output of messages) {
1712
+ if (output.role === "tool") {
1713
+ const toolCallIdx = assistantMessage.content.findIndex(
1714
+ (c) => c.type === "tool-call" && c.toolCallId === output.toolCallId
1715
+ );
1716
+ if (toolCallIdx !== -1) {
1717
+ const toolCall = assistantMessage.content[toolCallIdx];
1718
+ if (output.toolName) {
1719
+ if (toolCall.toolName !== output.toolName)
1720
+ throw new Error(
1721
+ `Tool call name ${output.toolCallId} ${output.toolName} does not match existing tool call ${toolCall.toolName}`
1722
+ );
1723
+ }
1724
+ assistantMessage.content[toolCallIdx] = {
1725
+ ...toolCall,
1726
+ result: output.result
1727
+ };
1728
+ } else {
1729
+ throw new Error(
1730
+ `Tool call ${output.toolCallId} ${output.toolName} not found in assistant message`
1731
+ );
1732
+ }
1733
+ } else {
1734
+ const content = output.content;
1735
+ const role = output.role;
1736
+ switch (role) {
1737
+ case "system":
1738
+ case "user":
1739
+ return { role, content };
1740
+ case "assistant":
1741
+ if (assistantMessage.content.length === 0) {
1742
+ assistantMessage.id = output.id;
1743
+ assistantMessage.createdAt ??= output.createdAt;
1744
+ assistantMessage.status ??= output.status;
1745
+ }
1746
+ assistantMessage.content.push(...content);
1747
+ break;
1748
+ default: {
1749
+ const unsupportedRole = role;
1750
+ throw new Error(`Unknown message role: ${unsupportedRole}`);
1751
+ }
1752
+ }
1753
+ }
1754
+ }
1755
+ return assistantMessage;
1756
+ };
1757
+ var chunkExternalMessages = (callbackResults) => {
1758
+ const results = [];
1759
+ let isAssistant = false;
1760
+ let inputs = [];
1761
+ let outputs = [];
1762
+ const flush = () => {
1763
+ if (outputs.length) {
1764
+ results.push({
1765
+ inputs,
1766
+ outputs
1767
+ });
1768
+ }
1769
+ inputs = [];
1770
+ outputs = [];
1771
+ };
1772
+ for (const callbackResult of callbackResults) {
1773
+ for (const output of callbackResult.outputs) {
1774
+ if (!isAssistant || output.role === "user" || output.role === "system") {
1775
+ flush();
1776
+ }
1777
+ isAssistant = output.role === "assistant" || output.role === "tool";
1778
+ if (inputs.at(-1) !== callbackResult.input) {
1779
+ inputs.push(callbackResult.input);
1780
+ }
1781
+ outputs.push(output);
1782
+ }
1783
+ }
1784
+ flush();
1785
+ return results;
1786
+ };
1787
+ var useExternalMessageConverter = ({
1788
+ callback,
1789
+ messages,
1790
+ isRunning
1791
+ }) => {
1792
+ const state = _react.useMemo.call(void 0,
1793
+ () => ({
1794
+ callback,
1795
+ callbackCache: /* @__PURE__ */ new WeakMap(),
1796
+ chunkCache: /* @__PURE__ */ new WeakMap(),
1797
+ converterCache: new ThreadMessageConverter()
1798
+ }),
1799
+ [callback]
1800
+ );
1801
+ return _react.useMemo.call(void 0, () => {
1802
+ const callbackResults = [];
1803
+ for (const message of messages) {
1804
+ let result = state.callbackCache.get(message);
1805
+ if (!result) {
1806
+ const output = state.callback(message);
1807
+ const outputs = Array.isArray(output) ? output : [output];
1808
+ result = { input: message, outputs };
1809
+ state.callbackCache.set(message, result);
1810
+ }
1811
+ callbackResults.push(result);
1812
+ }
1813
+ const chunks = chunkExternalMessages(callbackResults).map((m) => {
1814
+ const key = m.outputs[0];
1815
+ if (!key) return m;
1816
+ const cached = state.chunkCache.get(key);
1817
+ if (cached && shallowArrayEqual(cached.outputs, m.outputs)) return cached;
1818
+ state.chunkCache.set(key, m);
1819
+ return m;
1820
+ });
1821
+ return state.converterCache.convertMessages(
1822
+ chunks,
1823
+ (cache, message, idx) => {
1824
+ const isLast = idx === chunks.length - 1;
1825
+ const autoStatus = getAutoStatus(isLast, isRunning);
1826
+ if (cache && (cache.role !== "assistant" || !isAutoStatus(cache.status) || cache.status === autoStatus)) {
1827
+ const inputs = getExternalStoreMessage(cache);
1828
+ if (shallowArrayEqual(inputs, message.inputs)) {
1829
+ return cache;
1830
+ }
1831
+ }
1832
+ const newMessage = fromThreadMessageLike(
1833
+ joinExternalMessages(message.outputs),
1834
+ idx.toString(),
1835
+ autoStatus
1836
+ );
1837
+ newMessage[symbolInnerMessage] = message.inputs;
1838
+ return newMessage;
1839
+ }
1840
+ );
1841
+ }, [state, messages, isRunning]);
1842
+ };
1843
+ var shallowArrayEqual = (a, b) => {
1844
+ if (a.length !== b.length) return false;
1845
+ for (let i = 0; i < a.length; i++) {
1846
+ if (a[i] !== b[i]) return false;
1847
+ }
1848
+ return true;
1849
+ };
1850
+
1710
1851
  // src/runtimes/dangerous-in-browser/useDangerousInBrowserRuntime.ts
1711
1852
 
1712
1853
 
@@ -1743,6 +1884,47 @@ var useDangerousInBrowserRuntime = ({
1743
1884
  return useLocalRuntime(adapter, { initialMessages });
1744
1885
  };
1745
1886
 
1887
+ // src/runtimes/speech/WebSpeechSynthesisAdapter.ts
1888
+ var WebSpeechSynthesisAdapter = class {
1889
+ speak(message) {
1890
+ const text = getThreadMessageText(message);
1891
+ const utterance = new SpeechSynthesisUtterance(text);
1892
+ const endHandlers = /* @__PURE__ */ new Set();
1893
+ const handleEnd = (reason, error) => {
1894
+ if (res.status.type === "ended") return;
1895
+ res.status = { type: "ended", reason, error };
1896
+ endHandlers.forEach((handler) => handler());
1897
+ };
1898
+ utterance.addEventListener("end", () => handleEnd("finished"));
1899
+ utterance.addEventListener("error", (e) => handleEnd("error", e.error));
1900
+ window.speechSynthesis.speak(utterance);
1901
+ const res = {
1902
+ status: { type: "running" },
1903
+ cancel: () => {
1904
+ window.speechSynthesis.cancel();
1905
+ handleEnd("cancelled");
1906
+ },
1907
+ onEnd: (callback) => {
1908
+ if (res.status.type === "ended") {
1909
+ let cancelled = false;
1910
+ queueMicrotask(() => {
1911
+ if (!cancelled) callback();
1912
+ });
1913
+ return () => {
1914
+ cancelled = true;
1915
+ };
1916
+ } else {
1917
+ endHandlers.add(callback);
1918
+ return () => {
1919
+ endHandlers.delete(callback);
1920
+ };
1921
+ }
1922
+ }
1923
+ };
1924
+ return res;
1925
+ }
1926
+ };
1927
+
1746
1928
  // src/context/providers/ThreadProvider.tsx
1747
1929
 
1748
1930
  var ThreadProvider = ({
@@ -1770,7 +1952,7 @@ var ThreadProvider = ({
1770
1952
  const thread = provider.thread;
1771
1953
  const oldState = context.useThread.getState();
1772
1954
  const state = getThreadStateFromRuntime(thread);
1773
- if (oldState.isDisabled !== state.isDisabled || oldState.isRunning !== state.isRunning || // TODO ensure capabilities is memoized
1955
+ if (oldState.threadId !== state.threadId || oldState.isDisabled !== state.isDisabled || oldState.isRunning !== state.isRunning || // TODO ensure capabilities is memoized
1774
1956
  oldState.capabilities !== state.capabilities) {
1775
1957
  context.useThread.setState(
1776
1958
  state,
@@ -1866,7 +2048,7 @@ var AssistantRuntimeProvider = _react.memo.call(void 0, AssistantRuntimeProvider
1866
2048
  var MessageContext = _react.createContext.call(void 0, null);
1867
2049
  function useMessageContext(options) {
1868
2050
  const context = _react.useContext.call(void 0, MessageContext);
1869
- if (!_optionalChain([options, 'optionalAccess', _79 => _79.optional]) && !context)
2051
+ if (!_optionalChain([options, 'optionalAccess', _84 => _84.optional]) && !context)
1870
2052
  throw new Error(
1871
2053
  "This component can only be used inside a component passed to <ThreadPrimitive.Messages components={...} />."
1872
2054
  );
@@ -1893,7 +2075,7 @@ var ContentPartContext = _react.createContext.call(void 0,
1893
2075
  );
1894
2076
  function useContentPartContext(options) {
1895
2077
  const context = _react.useContext.call(void 0, ContentPartContext);
1896
- if (!_optionalChain([options, 'optionalAccess', _80 => _80.optional]) && !context)
2078
+ if (!_optionalChain([options, 'optionalAccess', _85 => _85.optional]) && !context)
1897
2079
  throw new Error(
1898
2080
  "This component can only be used inside a component passed to <MessagePrimitive.Content components={...} >."
1899
2081
  );
@@ -1905,13 +2087,13 @@ function useContentPartContext(options) {
1905
2087
  var toAppendMessage = (useThreadMessages, message) => {
1906
2088
  if (typeof message === "string") {
1907
2089
  return {
1908
- parentId: _nullishCoalesce(_optionalChain([useThreadMessages, 'access', _81 => _81.getState, 'call', _82 => _82(), 'access', _83 => _83.at, 'call', _84 => _84(-1), 'optionalAccess', _85 => _85.id]), () => ( null)),
2090
+ parentId: _nullishCoalesce(_optionalChain([useThreadMessages, 'access', _86 => _86.getState, 'call', _87 => _87(), 'access', _88 => _88.at, 'call', _89 => _89(-1), 'optionalAccess', _90 => _90.id]), () => ( null)),
1909
2091
  role: "user",
1910
2092
  content: [{ type: "text", text: message }]
1911
2093
  };
1912
2094
  }
1913
2095
  return {
1914
- parentId: _nullishCoalesce(_nullishCoalesce(message.parentId, () => ( _optionalChain([useThreadMessages, 'access', _86 => _86.getState, 'call', _87 => _87(), 'access', _88 => _88.at, 'call', _89 => _89(-1), 'optionalAccess', _90 => _90.id]))), () => ( null)),
2096
+ parentId: _nullishCoalesce(_nullishCoalesce(message.parentId, () => ( _optionalChain([useThreadMessages, 'access', _91 => _91.getState, 'call', _92 => _92(), 'access', _93 => _93.at, 'call', _94 => _94(-1), 'optionalAccess', _95 => _95.id]))), () => ( null)),
1915
2097
  role: _nullishCoalesce(message.role, () => ( "user")),
1916
2098
  content: message.content
1917
2099
  };
@@ -1963,7 +2145,7 @@ var useAssistantTool = (tool) => {
1963
2145
  const unsub2 = render ? setToolUI(toolName, render) : void 0;
1964
2146
  return () => {
1965
2147
  unsub1();
1966
- _optionalChain([unsub2, 'optionalCall', _91 => _91()]);
2148
+ _optionalChain([unsub2, 'optionalCall', _96 => _96()]);
1967
2149
  };
1968
2150
  }, [registerModelConfigProvider, setToolUI, tool]);
1969
2151
  };
@@ -2428,7 +2610,7 @@ var createActionButton = (displayName, useActionButton, forwardProps = []) => {
2428
2610
  ...primitiveProps,
2429
2611
  ref: forwardedRef,
2430
2612
  onClick: _primitive.composeEventHandlers.call(void 0, primitiveProps.onClick, () => {
2431
- _optionalChain([callback, 'optionalCall', _92 => _92()]);
2613
+ _optionalChain([callback, 'optionalCall', _97 => _97()]);
2432
2614
  })
2433
2615
  }
2434
2616
  );
@@ -2484,7 +2666,7 @@ var ActionBarPrimitiveStopSpeaking = _react.forwardRef.call(void 0, (props, ref)
2484
2666
  ...props,
2485
2667
  ref,
2486
2668
  onClick: _primitive.composeEventHandlers.call(void 0, props.onClick, () => {
2487
- _optionalChain([callback, 'optionalCall', _93 => _93()]);
2669
+ _optionalChain([callback, 'optionalCall', _98 => _98()]);
2488
2670
  })
2489
2671
  }
2490
2672
  );
@@ -2770,7 +2952,7 @@ var getContentPartState = ({ message }, useContentPart, partIndex) => {
2770
2952
  }
2771
2953
  }
2772
2954
  const status = toContentPartStatus(message, partIndex, part);
2773
- const currentState = _optionalChain([useContentPart, 'optionalAccess', _94 => _94.getState, 'call', _95 => _95()]);
2955
+ const currentState = _optionalChain([useContentPart, 'optionalAccess', _99 => _99.getState, 'call', _100 => _100()]);
2774
2956
  if (currentState && currentState.part === part && currentState.status === status)
2775
2957
  return null;
2776
2958
  return Object.freeze({ part, status });
@@ -2900,6 +3082,7 @@ var MessageContentPartComponent = ({
2900
3082
  const Tool = by_name[part.toolName] || Fallback2;
2901
3083
  const addResult = (result) => addToolResult({
2902
3084
  messageId: useMessage.getState().message.id,
3085
+ toolName: part.toolName,
2903
3086
  toolCallId: part.toolCallId,
2904
3087
  result
2905
3088
  });
@@ -2918,7 +3101,7 @@ var MessageContentPartImpl = ({
2918
3101
  };
2919
3102
  var MessageContentPart = _react.memo.call(void 0,
2920
3103
  MessageContentPartImpl,
2921
- (prev, next) => prev.partIndex === next.partIndex && _optionalChain([prev, 'access', _96 => _96.components, 'optionalAccess', _97 => _97.Text]) === _optionalChain([next, 'access', _98 => _98.components, 'optionalAccess', _99 => _99.Text]) && _optionalChain([prev, 'access', _100 => _100.components, 'optionalAccess', _101 => _101.Image]) === _optionalChain([next, 'access', _102 => _102.components, 'optionalAccess', _103 => _103.Image]) && _optionalChain([prev, 'access', _104 => _104.components, 'optionalAccess', _105 => _105.UI]) === _optionalChain([next, 'access', _106 => _106.components, 'optionalAccess', _107 => _107.UI]) && _optionalChain([prev, 'access', _108 => _108.components, 'optionalAccess', _109 => _109.tools]) === _optionalChain([next, 'access', _110 => _110.components, 'optionalAccess', _111 => _111.tools])
3104
+ (prev, next) => prev.partIndex === next.partIndex && _optionalChain([prev, 'access', _101 => _101.components, 'optionalAccess', _102 => _102.Text]) === _optionalChain([next, 'access', _103 => _103.components, 'optionalAccess', _104 => _104.Text]) && _optionalChain([prev, 'access', _105 => _105.components, 'optionalAccess', _106 => _106.Image]) === _optionalChain([next, 'access', _107 => _107.components, 'optionalAccess', _108 => _108.Image]) && _optionalChain([prev, 'access', _109 => _109.components, 'optionalAccess', _110 => _110.UI]) === _optionalChain([next, 'access', _111 => _111.components, 'optionalAccess', _112 => _112.UI]) && _optionalChain([prev, 'access', _113 => _113.components, 'optionalAccess', _114 => _114.tools]) === _optionalChain([next, 'access', _115 => _115.components, 'optionalAccess', _116 => _116.tools])
2922
3105
  );
2923
3106
  var MessagePrimitiveContent = ({
2924
3107
  components
@@ -3033,7 +3216,7 @@ var ComposerPrimitiveInput = _react.forwardRef.call(void 0,
3033
3216
  const { isRunning } = useThread.getState();
3034
3217
  if (!isRunning) {
3035
3218
  e.preventDefault();
3036
- _optionalChain([textareaRef, 'access', _112 => _112.current, 'optionalAccess', _113 => _113.closest, 'call', _114 => _114("form"), 'optionalAccess', _115 => _115.requestSubmit, 'call', _116 => _116()]);
3219
+ _optionalChain([textareaRef, 'access', _117 => _117.current, 'optionalAccess', _118 => _118.closest, 'call', _119 => _119("form"), 'optionalAccess', _120 => _120.requestSubmit, 'call', _121 => _121()]);
3037
3220
  }
3038
3221
  }
3039
3222
  };
@@ -3335,7 +3518,7 @@ var makeMessageUtilsStore = () => _zustand.create.call(void 0, (set) => {
3335
3518
  },
3336
3519
  isSpeaking: false,
3337
3520
  stopSpeaking: () => {
3338
- _optionalChain([utterance, 'optionalAccess', _117 => _117.stop, 'call', _118 => _118()]);
3521
+ _optionalChain([utterance, 'optionalAccess', _122 => _122.cancel, 'call', _123 => _123()]);
3339
3522
  },
3340
3523
  addUtterance: (utt) => {
3341
3524
  utterance = utt;
@@ -3350,15 +3533,15 @@ var makeMessageUtilsStore = () => _zustand.create.call(void 0, (set) => {
3350
3533
  // src/context/providers/MessageProvider.tsx
3351
3534
 
3352
3535
  var getIsLast = (messages, message) => {
3353
- return _optionalChain([messages, 'access', _119 => _119[messages.length - 1], 'optionalAccess', _120 => _120.id]) === message.id;
3536
+ return _optionalChain([messages, 'access', _124 => _124[messages.length - 1], 'optionalAccess', _125 => _125.id]) === message.id;
3354
3537
  };
3355
3538
  var getMessageState = (messages, getBranches, useMessage, messageIndex) => {
3356
- const parentId = _nullishCoalesce(_optionalChain([messages, 'access', _121 => _121[messageIndex - 1], 'optionalAccess', _122 => _122.id]), () => ( null));
3539
+ const parentId = _nullishCoalesce(_optionalChain([messages, 'access', _126 => _126[messageIndex - 1], 'optionalAccess', _127 => _127.id]), () => ( null));
3357
3540
  const message = messages[messageIndex];
3358
3541
  if (!message) return null;
3359
3542
  const isLast = getIsLast(messages, message);
3360
3543
  const branches = getBranches(message.id);
3361
- const currentState = _optionalChain([useMessage, 'optionalAccess', _123 => _123.getState, 'call', _124 => _124()]);
3544
+ const currentState = _optionalChain([useMessage, 'optionalAccess', _128 => _128.getState, 'call', _129 => _129()]);
3362
3545
  if (currentState && currentState.message === message && currentState.parentId === parentId && currentState.branches === branches && currentState.isLast === isLast)
3363
3546
  return null;
3364
3547
  return Object.freeze({
@@ -3485,7 +3668,7 @@ var ThreadPrimitiveMessagesImpl = ({
3485
3668
  ThreadPrimitiveMessagesImpl.displayName = "ThreadPrimitive.Messages";
3486
3669
  var ThreadPrimitiveMessages = _react.memo.call(void 0,
3487
3670
  ThreadPrimitiveMessagesImpl,
3488
- (prev, next) => _optionalChain([prev, 'access', _125 => _125.components, 'optionalAccess', _126 => _126.Message]) === _optionalChain([next, 'access', _127 => _127.components, 'optionalAccess', _128 => _128.Message]) && _optionalChain([prev, 'access', _129 => _129.components, 'optionalAccess', _130 => _130.UserMessage]) === _optionalChain([next, 'access', _131 => _131.components, 'optionalAccess', _132 => _132.UserMessage]) && _optionalChain([prev, 'access', _133 => _133.components, 'optionalAccess', _134 => _134.EditComposer]) === _optionalChain([next, 'access', _135 => _135.components, 'optionalAccess', _136 => _136.EditComposer]) && _optionalChain([prev, 'access', _137 => _137.components, 'optionalAccess', _138 => _138.AssistantMessage]) === _optionalChain([next, 'access', _139 => _139.components, 'optionalAccess', _140 => _140.AssistantMessage]) && _optionalChain([prev, 'access', _141 => _141.components, 'optionalAccess', _142 => _142.SystemMessage]) === _optionalChain([next, 'access', _143 => _143.components, 'optionalAccess', _144 => _144.SystemMessage])
3671
+ (prev, next) => _optionalChain([prev, 'access', _130 => _130.components, 'optionalAccess', _131 => _131.Message]) === _optionalChain([next, 'access', _132 => _132.components, 'optionalAccess', _133 => _133.Message]) && _optionalChain([prev, 'access', _134 => _134.components, 'optionalAccess', _135 => _135.UserMessage]) === _optionalChain([next, 'access', _136 => _136.components, 'optionalAccess', _137 => _137.UserMessage]) && _optionalChain([prev, 'access', _138 => _138.components, 'optionalAccess', _139 => _139.EditComposer]) === _optionalChain([next, 'access', _140 => _140.components, 'optionalAccess', _141 => _141.EditComposer]) && _optionalChain([prev, 'access', _142 => _142.components, 'optionalAccess', _143 => _143.AssistantMessage]) === _optionalChain([next, 'access', _144 => _144.components, 'optionalAccess', _145 => _145.AssistantMessage]) && _optionalChain([prev, 'access', _146 => _146.components, 'optionalAccess', _147 => _147.SystemMessage]) === _optionalChain([next, 'access', _148 => _148.components, 'optionalAccess', _149 => _149.SystemMessage])
3489
3672
  );
3490
3673
 
3491
3674
  // src/primitives/thread/ThreadScrollToBottom.tsx
@@ -3517,7 +3700,7 @@ var ThreadConfigProvider = ({
3517
3700
  }) => {
3518
3701
  const assistant = useAssistantContext({ optional: true });
3519
3702
  const configProvider = config && Object.keys(_nullishCoalesce(config, () => ( {}))).length > 0 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThreadConfigContext.Provider, { value: config, children }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children });
3520
- if (!_optionalChain([config, 'optionalAccess', _145 => _145.runtime])) return configProvider;
3703
+ if (!_optionalChain([config, 'optionalAccess', _150 => _150.runtime])) return configProvider;
3521
3704
  if (assistant) {
3522
3705
  throw new Error(
3523
3706
  "You provided a runtime to <Thread> while simulataneously using <AssistantRuntimeProvider>. This is not allowed."
@@ -3537,28 +3720,29 @@ ThreadConfigProvider.displayName = "ThreadConfigProvider";
3537
3720
 
3538
3721
  var _lucidereact = require('lucide-react');
3539
3722
 
3540
- var useAllowCopy = () => {
3723
+ var useAllowCopy = (ensureCapability = false) => {
3541
3724
  const { assistantMessage: { allowCopy = true } = {} } = useThreadConfig();
3542
3725
  const { useThread } = useThreadContext();
3543
3726
  const copySupported = useThread((t) => t.capabilities.unstable_copy);
3544
- return copySupported && allowCopy;
3727
+ return allowCopy && (!ensureCapability || copySupported);
3545
3728
  };
3546
- var useAllowSpeak = () => {
3729
+ var useAllowSpeak = (ensureCapability = false) => {
3547
3730
  const { assistantMessage: { allowSpeak = true } = {} } = useThreadConfig();
3548
3731
  const { useThread } = useThreadContext();
3549
3732
  const speakSupported = useThread((t) => t.capabilities.speak);
3550
- return speakSupported && allowSpeak;
3733
+ return allowSpeak && (!ensureCapability || speakSupported);
3551
3734
  };
3552
- var useAllowReload = () => {
3735
+ var useAllowReload = (ensureCapability = false) => {
3553
3736
  const { assistantMessage: { allowReload = true } = {} } = useThreadConfig();
3554
3737
  const { useThread } = useThreadContext();
3555
3738
  const reloadSupported = useThread((t) => t.capabilities.reload);
3556
- return reloadSupported && allowReload;
3739
+ return allowReload && (!ensureCapability || reloadSupported);
3557
3740
  };
3558
3741
  var AssistantActionBar = () => {
3559
- const allowCopy = useAllowCopy();
3560
- const allowReload = useAllowReload();
3561
- if (!allowCopy && !allowReload) return null;
3742
+ const allowCopy = useAllowCopy(true);
3743
+ const allowReload = useAllowReload(true);
3744
+ const allowSpeak = useAllowSpeak(true);
3745
+ if (!allowCopy && !allowReload && !allowSpeak) return null;
3562
3746
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3563
3747
  AssistantActionBarRoot,
3564
3748
  {
@@ -3566,9 +3750,9 @@ var AssistantActionBar = () => {
3566
3750
  autohide: "not-last",
3567
3751
  autohideFloat: "single-branch",
3568
3752
  children: [
3569
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AssistantActionBarSpeechControl, {}),
3570
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AssistantActionBarCopy, {}),
3571
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AssistantActionBarReload, {})
3753
+ allowSpeak && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AssistantActionBarSpeechControl, {}),
3754
+ allowCopy && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AssistantActionBarCopy, {}),
3755
+ allowReload && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AssistantActionBarReload, {})
3572
3756
  ]
3573
3757
  }
3574
3758
  );
@@ -3584,8 +3768,6 @@ var AssistantActionBarCopy = _react.forwardRef.call(void 0, (props, ref) => {
3584
3768
  assistantMessage: { copy: { tooltip = "Copy" } = {} } = {}
3585
3769
  } = {}
3586
3770
  } = useThreadConfig();
3587
- const allowCopy = useAllowCopy();
3588
- if (!allowCopy) return null;
3589
3771
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, actionBar_exports.Copy, { asChild: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TooltipIconButton, { tooltip, ...props, ref, children: _nullishCoalesce(props.children, () => ( /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
3590
3772
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, message_exports.If, { copied: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CheckIcon, {}) }),
3591
3773
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, message_exports.If, { copied: false, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CopyIcon, {}) })
@@ -3779,7 +3961,7 @@ var AssistantMessageContent = _react.forwardRef.call(void 0, ({ components: comp
3779
3961
  {
3780
3962
  components: {
3781
3963
  ...componentsProp,
3782
- Text: _nullishCoalesce(_nullishCoalesce(_optionalChain([componentsProp, 'optionalAccess', _146 => _146.Text]), () => ( components.Text)), () => ( content_part_default.Text))
3964
+ Text: _nullishCoalesce(_nullishCoalesce(_optionalChain([componentsProp, 'optionalAccess', _151 => _151.Text]), () => ( components.Text)), () => ( content_part_default.Text))
3783
3965
  }
3784
3966
  }
3785
3967
  ) });
@@ -3956,7 +4138,7 @@ var ThreadWelcomeSuggestion = ({
3956
4138
  };
3957
4139
  var ThreadWelcomeSuggestions = () => {
3958
4140
  const { welcome: { suggestions } = {} } = useThreadConfig();
3959
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThreadWelcomeSuggestionContainer, { children: _optionalChain([suggestions, 'optionalAccess', _147 => _147.map, 'call', _148 => _148((suggestion, idx) => {
4141
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThreadWelcomeSuggestionContainer, { children: _optionalChain([suggestions, 'optionalAccess', _152 => _152.map, 'call', _153 => _153((suggestion, idx) => {
3960
4142
  const key = `${suggestion.prompt}-${idx}`;
3961
4143
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThreadWelcomeSuggestion, { suggestion }, key);
3962
4144
  })]) });
@@ -3979,14 +4161,14 @@ var thread_welcome_default = Object.assign(ThreadWelcome, exports6);
3979
4161
 
3980
4162
 
3981
4163
 
3982
- var useAllowEdit = () => {
4164
+ var useAllowEdit = (ensureCapability = false) => {
3983
4165
  const { userMessage: { allowEdit = true } = {} } = useThreadConfig();
3984
4166
  const { useThread } = useThreadContext();
3985
4167
  const editSupported = useThread((t) => t.capabilities.edit);
3986
- return editSupported && allowEdit;
4168
+ return allowEdit && (!ensureCapability || editSupported);
3987
4169
  };
3988
4170
  var UserActionBar = () => {
3989
- const allowEdit = useAllowEdit();
4171
+ const allowEdit = useAllowEdit(true);
3990
4172
  if (!allowEdit) return null;
3991
4173
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, UserActionBarRoot, { hideWhenRunning: true, autohide: "not-last", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, UserActionBarEdit, {}) });
3992
4174
  };
@@ -4034,7 +4216,7 @@ var UserMessageContent = _react.forwardRef.call(void 0,
4034
4216
  {
4035
4217
  components: {
4036
4218
  ...components,
4037
- Text: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _149 => _149.Text]), () => ( content_part_default.Text))
4219
+ Text: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _154 => _154.Text]), () => ( content_part_default.Text))
4038
4220
  }
4039
4221
  }
4040
4222
  ) });
@@ -4136,10 +4318,10 @@ var ThreadMessages = ({ components, ...rest }) => {
4136
4318
  thread_exports.Messages,
4137
4319
  {
4138
4320
  components: {
4139
- UserMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _150 => _150.UserMessage]), () => ( user_message_default)),
4140
- EditComposer: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _151 => _151.EditComposer]), () => ( edit_composer_default)),
4141
- AssistantMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _152 => _152.AssistantMessage]), () => ( assistant_message_default)),
4142
- SystemMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _153 => _153.SystemMessage]), () => ( SystemMessage))
4321
+ UserMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _155 => _155.UserMessage]), () => ( user_message_default)),
4322
+ EditComposer: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _156 => _156.EditComposer]), () => ( edit_composer_default)),
4323
+ AssistantMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _157 => _157.AssistantMessage]), () => ( assistant_message_default)),
4324
+ SystemMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _158 => _158.SystemMessage]), () => ( SystemMessage))
4143
4325
  },
4144
4326
  ...rest
4145
4327
  }
@@ -4321,5 +4503,6 @@ var assistant_modal_default = Object.assign(AssistantModal, exports11);
4321
4503
 
4322
4504
 
4323
4505
 
4324
- 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;
4506
+
4507
+ 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.useExternalMessageConverter = useExternalMessageConverter; 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;
4325
4508
  //# sourceMappingURL=index.js.map