@assistant-ui/react 0.3.0 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.js CHANGED
@@ -210,11 +210,14 @@ var makeBaseComposer = (set) => ({
210
210
  });
211
211
 
212
212
  // src/context/stores/Composer.ts
213
- var makeComposerStore = (useThread, useThreadMessages, useThreadActions) => {
213
+ var makeComposerStore = (useThreadMessages, useThreadActions) => {
214
214
  const focusListeners = /* @__PURE__ */ new Set();
215
215
  return (0, import_zustand3.create)()((set, get, store) => {
216
216
  return {
217
217
  ...makeBaseComposer(set, get, store),
218
+ get canCancel() {
219
+ return useThreadActions.getState().capabilities.cancel;
220
+ },
218
221
  isEditing: true,
219
222
  send: () => {
220
223
  const { setValue, value } = get();
@@ -226,10 +229,7 @@ var makeComposerStore = (useThread, useThreadMessages, useThreadActions) => {
226
229
  });
227
230
  },
228
231
  cancel: () => {
229
- const thread = useThread.getState();
230
- if (!thread.isRunning) return false;
231
232
  useThreadActions.getState().cancelRun();
232
- return true;
233
233
  },
234
234
  focus: () => {
235
235
  for (const listener of focusListeners) {
@@ -279,6 +279,9 @@ var import_zustand6 = require("zustand");
279
279
  var makeThreadActionStore = (runtimeRef) => {
280
280
  return (0, import_zustand6.create)(
281
281
  () => Object.freeze({
282
+ get capabilities() {
283
+ return runtimeRef.current.capabilities;
284
+ },
282
285
  getBranches: (messageId) => runtimeRef.current.getBranches(messageId),
283
286
  switchToBranch: (branchId) => runtimeRef.current.switchToBranch(branchId),
284
287
  startRun: (parentId) => runtimeRef.current.startRun(parentId),
@@ -310,11 +313,7 @@ var ThreadProvider = ({
310
313
  const useThreadMessages = makeThreadMessagesStore(runtimeRef);
311
314
  const useThreadActions = makeThreadActionStore(runtimeRef);
312
315
  const useViewport = makeThreadViewportStore();
313
- const useComposer = makeComposerStore(
314
- useThread,
315
- useThreadMessages,
316
- useThreadActions
317
- );
316
+ const useComposer = makeComposerStore(useThreadMessages, useThreadActions);
318
317
  return {
319
318
  useThread,
320
319
  useThreadMessages,
@@ -687,7 +686,7 @@ var useBranchPickerPrevious = () => {
687
686
  var import_react21 = require("react");
688
687
  var useComposerCancel = () => {
689
688
  const { useComposer } = useComposerContext();
690
- const disabled = useComposer((c) => !c.isEditing);
689
+ const disabled = useComposer((c) => !c.canCancel);
691
690
  const callback = (0, import_react21.useCallback)(() => {
692
691
  const { cancel } = useComposer.getState();
693
692
  cancel();
@@ -731,7 +730,7 @@ var useContentPartDisplay = () => {
731
730
  throw new Error(
732
731
  "This component can only be used inside ui content parts."
733
732
  );
734
- return c.part.display;
733
+ return c;
735
734
  });
736
735
  return display;
737
736
  };
@@ -744,7 +743,7 @@ var useContentPartImage = () => {
744
743
  throw new Error(
745
744
  "ContentPartImage can only be used inside image content parts."
746
745
  );
747
- return c.part.image;
746
+ return c;
748
747
  });
749
748
  return image;
750
749
  };
@@ -819,15 +818,18 @@ var useThreadSuggestion = ({
819
818
  autoSend
820
819
  }) => {
821
820
  const { useThread, useComposer } = useThreadContext();
821
+ const append = useAppendMessage();
822
822
  const disabled = useThread((t) => t.isRunning);
823
823
  const callback = (0, import_react24.useCallback)(() => {
824
824
  const thread = useThread.getState();
825
825
  const composer = useComposer.getState();
826
- composer.setValue(prompt);
827
826
  if (autoSend && !thread.isRunning) {
828
- composer.send();
827
+ append(prompt);
828
+ composer.setValue("");
829
+ } else {
830
+ composer.setValue(prompt);
829
831
  }
830
- }, [useThread, useComposer, prompt, autoSend]);
832
+ }, [useThread, useComposer, autoSend, append, prompt]);
831
833
  if (disabled) return null;
832
834
  return callback;
833
835
  };
@@ -1095,7 +1097,7 @@ BranchPickerPrimitiveNumber.displayName = "BranchPickerPrimitive.Number";
1095
1097
 
1096
1098
  // src/primitives/branchPicker/BranchPickerRoot.tsx
1097
1099
  var import_react_primitive6 = require("@radix-ui/react-primitive");
1098
- var import_react38 = require("react");
1100
+ var import_react39 = require("react");
1099
1101
 
1100
1102
  // src/primitives/message/index.ts
1101
1103
  var message_exports = {};
@@ -1172,7 +1174,7 @@ var MessagePrimitiveIf = ({
1172
1174
  MessagePrimitiveIf.displayName = "MessagePrimitive.If";
1173
1175
 
1174
1176
  // src/primitives/message/MessageContent.tsx
1175
- var import_react37 = require("react");
1177
+ var import_react38 = require("react");
1176
1178
 
1177
1179
  // src/context/providers/ContentPartProvider.tsx
1178
1180
  var import_react34 = require("react");
@@ -1219,30 +1221,107 @@ var ContentPartProvider = ({
1219
1221
 
1220
1222
  // src/primitives/contentPart/ContentPartText.tsx
1221
1223
  var import_react_primitive4 = require("@radix-ui/react-primitive");
1224
+ var import_react36 = require("react");
1225
+
1226
+ // src/utils/hooks/useSmooth.tsx
1222
1227
  var import_react35 = require("react");
1228
+ var TextStreamAnimator = class {
1229
+ constructor(setText) {
1230
+ this.setText = setText;
1231
+ }
1232
+ animationFrameId = null;
1233
+ lastUpdateTime = Date.now();
1234
+ decayFactor = 0.99;
1235
+ targetText = "";
1236
+ start() {
1237
+ if (this.animationFrameId !== null) return;
1238
+ this.animate();
1239
+ }
1240
+ stop() {
1241
+ if (this.animationFrameId !== null) {
1242
+ cancelAnimationFrame(this.animationFrameId);
1243
+ this.animationFrameId = null;
1244
+ }
1245
+ }
1246
+ animate = () => {
1247
+ const currentTime = Date.now();
1248
+ const deltaTime = currentTime - this.lastUpdateTime;
1249
+ this.lastUpdateTime = currentTime;
1250
+ this.setText((currentText) => {
1251
+ const targetText = this.targetText;
1252
+ if (currentText === targetText) {
1253
+ this.animationFrameId = null;
1254
+ return currentText;
1255
+ }
1256
+ const remainingChars = targetText.length - currentText.length;
1257
+ const charsToAdd = Math.max(
1258
+ 1,
1259
+ Math.floor(
1260
+ remainingChars * (1 - Math.pow(this.decayFactor, deltaTime))
1261
+ )
1262
+ );
1263
+ const newText = targetText.slice(0, currentText.length + charsToAdd);
1264
+ this.animationFrameId = requestAnimationFrame(this.animate);
1265
+ return newText;
1266
+ });
1267
+ };
1268
+ };
1269
+ var useSmooth = (text, smooth = false) => {
1270
+ const [displayedText, setDisplayedText] = (0, import_react35.useState)(text);
1271
+ const [animatorRef] = (0, import_react35.useState)(
1272
+ new TextStreamAnimator(setDisplayedText)
1273
+ );
1274
+ (0, import_react35.useEffect)(() => {
1275
+ if (!smooth) {
1276
+ animatorRef.stop();
1277
+ return;
1278
+ }
1279
+ if (!text.startsWith(animatorRef.targetText)) {
1280
+ setDisplayedText(text);
1281
+ animatorRef.targetText = text;
1282
+ animatorRef.stop();
1283
+ return;
1284
+ }
1285
+ animatorRef.targetText = text;
1286
+ animatorRef.start();
1287
+ }, [animatorRef, smooth, text]);
1288
+ (0, import_react35.useEffect)(() => {
1289
+ return () => {
1290
+ animatorRef.stop();
1291
+ };
1292
+ }, [animatorRef]);
1293
+ return smooth ? displayedText : text;
1294
+ };
1295
+
1296
+ // src/primitives/contentPart/ContentPartText.tsx
1223
1297
  var import_jsx_runtime14 = require("react/jsx-runtime");
1224
- var ContentPartPrimitiveText = (0, import_react35.forwardRef)((props, forwardedRef) => {
1298
+ var ContentPartPrimitiveText = (0, import_react36.forwardRef)(({ smooth, ...rest }, forwardedRef) => {
1225
1299
  const {
1226
- part: { text },
1227
- status
1300
+ status,
1301
+ part: { text }
1228
1302
  } = useContentPartText();
1229
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_primitive4.Primitive.span, { "data-status": status, ...props, ref: forwardedRef, children: text });
1303
+ const smoothText = useSmooth(text, smooth);
1304
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_primitive4.Primitive.span, { "data-status": status, ...rest, ref: forwardedRef, children: smoothText });
1230
1305
  });
1231
1306
  ContentPartPrimitiveText.displayName = "ContentPartPrimitive.Text";
1232
1307
 
1233
1308
  // src/primitives/contentPart/ContentPartImage.tsx
1234
1309
  var import_react_primitive5 = require("@radix-ui/react-primitive");
1235
- var import_react36 = require("react");
1310
+ var import_react37 = require("react");
1236
1311
  var import_jsx_runtime15 = require("react/jsx-runtime");
1237
- var ContentPartPrimitiveImage = (0, import_react36.forwardRef)((props, forwardedRef) => {
1238
- const image = useContentPartImage();
1312
+ var ContentPartPrimitiveImage = (0, import_react37.forwardRef)((props, forwardedRef) => {
1313
+ const {
1314
+ part: { image }
1315
+ } = useContentPartImage();
1239
1316
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_primitive5.Primitive.img, { src: image, ...props, ref: forwardedRef });
1240
1317
  });
1241
1318
  ContentPartPrimitiveImage.displayName = "ContentPartPrimitive.Image";
1242
1319
 
1243
1320
  // src/primitives/contentPart/ContentPartDisplay.tsx
1244
1321
  var ContentPartPrimitiveDisplay = () => {
1245
- const display = useContentPartDisplay();
1322
+ const {
1323
+ part: { display }
1324
+ } = useContentPartDisplay();
1246
1325
  return display ?? null;
1247
1326
  };
1248
1327
  ContentPartPrimitiveDisplay.displayName = "ContentPartPrimitive.Display";
@@ -1262,7 +1341,7 @@ var import_jsx_runtime16 = require("react/jsx-runtime");
1262
1341
  var defaultComponents = {
1263
1342
  Text: () => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("p", { style: { whiteSpace: "pre-line" }, children: [
1264
1343
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ContentPartPrimitiveText, {}),
1265
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ContentPartPrimitiveInProgress, { children: " \u25CF" })
1344
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ContentPartPrimitiveInProgress, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: { fontFamily: "revert" }, children: " \u25CF" }) })
1266
1345
  ] }),
1267
1346
  Image: () => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ContentPartPrimitiveImage, {}),
1268
1347
  UI: () => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ContentPartPrimitiveDisplay, {}),
@@ -1310,7 +1389,7 @@ var MessageContentPartImpl = ({
1310
1389
  }) => {
1311
1390
  return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ContentPartProvider, { partIndex, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MessageContentPartComponent, { components }) });
1312
1391
  };
1313
- var MessageContentPart = (0, import_react37.memo)(
1392
+ var MessageContentPart = (0, import_react38.memo)(
1314
1393
  MessageContentPartImpl,
1315
1394
  (prev, next) => prev.partIndex === next.partIndex && prev.components?.Text === next.components?.Text && prev.components?.Image === next.components?.Image && prev.components?.UI === next.components?.UI && prev.components?.tools === next.components?.tools
1316
1395
  );
@@ -1341,7 +1420,7 @@ MessagePrimitiveInProgress.displayName = "MessagePrimitive.InProgress";
1341
1420
 
1342
1421
  // src/primitives/branchPicker/BranchPickerRoot.tsx
1343
1422
  var import_jsx_runtime17 = require("react/jsx-runtime");
1344
- var BranchPickerPrimitiveRoot = (0, import_react38.forwardRef)(({ hideWhenSingleBranch, ...rest }, ref) => {
1423
+ var BranchPickerPrimitiveRoot = (0, import_react39.forwardRef)(({ hideWhenSingleBranch, ...rest }, ref) => {
1345
1424
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(MessagePrimitiveIf, { hasBranches: hideWhenSingleBranch ? true : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_primitive6.Primitive.div, { ...rest, ref }) });
1346
1425
  });
1347
1426
  BranchPickerPrimitiveRoot.displayName = "BranchPickerPrimitive.Root";
@@ -1359,9 +1438,9 @@ __export(composer_exports, {
1359
1438
  // src/primitives/composer/ComposerRoot.tsx
1360
1439
  var import_primitive4 = require("@radix-ui/primitive");
1361
1440
  var import_react_primitive7 = require("@radix-ui/react-primitive");
1362
- var import_react39 = require("react");
1441
+ var import_react40 = require("react");
1363
1442
  var import_jsx_runtime18 = require("react/jsx-runtime");
1364
- var ComposerPrimitiveRoot = (0, import_react39.forwardRef)(({ onSubmit, ...rest }, forwardedRef) => {
1443
+ var ComposerPrimitiveRoot = (0, import_react40.forwardRef)(({ onSubmit, ...rest }, forwardedRef) => {
1365
1444
  const send = useComposerSend();
1366
1445
  const handleSubmit = (e) => {
1367
1446
  e.preventDefault();
@@ -1383,11 +1462,11 @@ ComposerPrimitiveRoot.displayName = "ComposerPrimitive.Root";
1383
1462
  var import_primitive5 = require("@radix-ui/primitive");
1384
1463
  var import_react_compose_refs2 = require("@radix-ui/react-compose-refs");
1385
1464
  var import_react_slot = require("@radix-ui/react-slot");
1386
- var import_react40 = require("react");
1465
+ var import_react41 = require("react");
1387
1466
  var import_react_textarea_autosize = __toESM(require("react-textarea-autosize"));
1388
1467
  var import_react_use_escape_keydown = require("@radix-ui/react-use-escape-keydown");
1389
1468
  var import_jsx_runtime19 = require("react/jsx-runtime");
1390
- var ComposerPrimitiveInput = (0, import_react40.forwardRef)(
1469
+ var ComposerPrimitiveInput = (0, import_react41.forwardRef)(
1391
1470
  ({ autoFocus = false, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
1392
1471
  const { useThread } = useThreadContext();
1393
1472
  const { useComposer, type } = useComposerContext();
@@ -1396,11 +1475,12 @@ var ComposerPrimitiveInput = (0, import_react40.forwardRef)(
1396
1475
  return c.value;
1397
1476
  });
1398
1477
  const Component = asChild ? import_react_slot.Slot : import_react_textarea_autosize.default;
1399
- const textareaRef = (0, import_react40.useRef)(null);
1478
+ const textareaRef = (0, import_react41.useRef)(null);
1400
1479
  const ref = (0, import_react_compose_refs2.useComposedRefs)(forwardedRef, textareaRef);
1401
1480
  (0, import_react_use_escape_keydown.useEscapeKeydown)((e) => {
1402
1481
  const composer = useComposer.getState();
1403
- if (composer.cancel()) {
1482
+ if (composer.canCancel) {
1483
+ composer.cancel();
1404
1484
  e.preventDefault();
1405
1485
  }
1406
1486
  });
@@ -1415,7 +1495,7 @@ var ComposerPrimitiveInput = (0, import_react40.forwardRef)(
1415
1495
  }
1416
1496
  };
1417
1497
  const autoFocusEnabled = autoFocus && !disabled;
1418
- const focus = (0, import_react40.useCallback)(() => {
1498
+ const focus = (0, import_react41.useCallback)(() => {
1419
1499
  const textarea = textareaRef.current;
1420
1500
  if (!textarea || !autoFocusEnabled) return;
1421
1501
  textarea.focus({ preventScroll: true });
@@ -1424,7 +1504,7 @@ var ComposerPrimitiveInput = (0, import_react40.forwardRef)(
1424
1504
  textareaRef.current.value.length
1425
1505
  );
1426
1506
  }, [autoFocusEnabled]);
1427
- (0, import_react40.useEffect)(() => focus(), [focus]);
1507
+ (0, import_react41.useEffect)(() => focus(), [focus]);
1428
1508
  useOnComposerFocus(() => {
1429
1509
  if (type === "new") {
1430
1510
  focus();
@@ -1451,10 +1531,10 @@ var ComposerPrimitiveInput = (0, import_react40.forwardRef)(
1451
1531
  ComposerPrimitiveInput.displayName = "ComposerPrimitive.Input";
1452
1532
 
1453
1533
  // src/primitives/composer/ComposerSend.tsx
1454
- var import_react41 = require("react");
1534
+ var import_react42 = require("react");
1455
1535
  var import_react_primitive8 = require("@radix-ui/react-primitive");
1456
1536
  var import_jsx_runtime20 = require("react/jsx-runtime");
1457
- var ComposerPrimitiveSend = (0, import_react41.forwardRef)(({ disabled, ...rest }, ref) => {
1537
+ var ComposerPrimitiveSend = (0, import_react42.forwardRef)(({ disabled, ...rest }, ref) => {
1458
1538
  const { useComposer } = useComposerContext();
1459
1539
  const hasValue = useComposer((c) => c.isEditing && c.value.length > 0);
1460
1540
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
@@ -1508,9 +1588,9 @@ __export(thread_exports, {
1508
1588
 
1509
1589
  // src/primitives/thread/ThreadRoot.tsx
1510
1590
  var import_react_primitive9 = require("@radix-ui/react-primitive");
1511
- var import_react42 = require("react");
1591
+ var import_react43 = require("react");
1512
1592
  var import_jsx_runtime21 = require("react/jsx-runtime");
1513
- var ThreadPrimitiveRoot = (0, import_react42.forwardRef)((props, ref) => {
1593
+ var ThreadPrimitiveRoot = (0, import_react43.forwardRef)((props, ref) => {
1514
1594
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_primitive9.Primitive.div, { ...props, ref });
1515
1595
  });
1516
1596
  ThreadPrimitiveRoot.displayName = "ThreadPrimitive.Root";
@@ -1537,18 +1617,18 @@ ThreadPrimitiveIf.displayName = "ThreadPrimitive.If";
1537
1617
  // src/primitives/thread/ThreadViewport.tsx
1538
1618
  var import_react_compose_refs4 = require("@radix-ui/react-compose-refs");
1539
1619
  var import_react_primitive10 = require("@radix-ui/react-primitive");
1540
- var import_react46 = require("react");
1620
+ var import_react47 = require("react");
1541
1621
 
1542
1622
  // src/primitive-hooks/thread/useThreadViewportAutoScroll.tsx
1543
1623
  var import_react_compose_refs3 = require("@radix-ui/react-compose-refs");
1544
- var import_react45 = require("react");
1624
+ var import_react46 = require("react");
1545
1625
 
1546
1626
  // src/utils/hooks/useOnResizeContent.tsx
1547
1627
  var import_react_use_callback_ref2 = require("@radix-ui/react-use-callback-ref");
1548
- var import_react43 = require("react");
1628
+ var import_react44 = require("react");
1549
1629
  var useOnResizeContent = (callback) => {
1550
1630
  const callbackRef = (0, import_react_use_callback_ref2.useCallbackRef)(callback);
1551
- const refCallback = (0, import_react43.useCallback)(
1631
+ const refCallback = (0, import_react44.useCallback)(
1552
1632
  (el) => {
1553
1633
  const resizeObserver = new ResizeObserver(() => {
1554
1634
  callbackRef();
@@ -1585,11 +1665,11 @@ var useOnResizeContent = (callback) => {
1585
1665
 
1586
1666
  // src/utils/hooks/useOnScrollToBottom.tsx
1587
1667
  var import_react_use_callback_ref3 = require("@radix-ui/react-use-callback-ref");
1588
- var import_react44 = require("react");
1668
+ var import_react45 = require("react");
1589
1669
  var useOnScrollToBottom = (callback) => {
1590
1670
  const callbackRef = (0, import_react_use_callback_ref3.useCallbackRef)(callback);
1591
1671
  const { useViewport } = useThreadContext();
1592
- (0, import_react44.useEffect)(() => {
1672
+ (0, import_react45.useEffect)(() => {
1593
1673
  return useViewport.getState().onScrollToBottom(() => {
1594
1674
  callbackRef();
1595
1675
  });
@@ -1600,11 +1680,11 @@ var useOnScrollToBottom = (callback) => {
1600
1680
  var useThreadViewportAutoScroll = ({
1601
1681
  autoScroll = true
1602
1682
  }) => {
1603
- const divRef = (0, import_react45.useRef)(null);
1683
+ const divRef = (0, import_react46.useRef)(null);
1604
1684
  const { useViewport } = useThreadContext();
1605
- const firstRenderRef = (0, import_react45.useRef)(true);
1606
- const lastScrollTop = (0, import_react45.useRef)(0);
1607
- const isScrollingToBottomRef = (0, import_react45.useRef)(false);
1685
+ const firstRenderRef = (0, import_react46.useRef)(true);
1686
+ const lastScrollTop = (0, import_react46.useRef)(0);
1687
+ const isScrollingToBottomRef = (0, import_react46.useRef)(false);
1608
1688
  const scrollToBottom = () => {
1609
1689
  const div = divRef.current;
1610
1690
  if (!div || !autoScroll) return;
@@ -1651,7 +1731,7 @@ var useThreadViewportAutoScroll = ({
1651
1731
 
1652
1732
  // src/primitives/thread/ThreadViewport.tsx
1653
1733
  var import_jsx_runtime22 = require("react/jsx-runtime");
1654
- var ThreadPrimitiveViewport = (0, import_react46.forwardRef)(({ autoScroll, onScroll, children, ...rest }, forwardedRef) => {
1734
+ var ThreadPrimitiveViewport = (0, import_react47.forwardRef)(({ autoScroll, onScroll, children, ...rest }, forwardedRef) => {
1655
1735
  const autoScrollRef = useThreadViewportAutoScroll({
1656
1736
  autoScroll
1657
1737
  });
@@ -1661,10 +1741,10 @@ var ThreadPrimitiveViewport = (0, import_react46.forwardRef)(({ autoScroll, onSc
1661
1741
  ThreadPrimitiveViewport.displayName = "ThreadPrimitive.Viewport";
1662
1742
 
1663
1743
  // src/primitives/thread/ThreadMessages.tsx
1664
- var import_react48 = require("react");
1744
+ var import_react49 = require("react");
1665
1745
 
1666
1746
  // src/context/providers/MessageProvider.tsx
1667
- var import_react47 = require("react");
1747
+ var import_react48 = require("react");
1668
1748
  var import_zustand12 = require("zustand");
1669
1749
 
1670
1750
  // src/context/stores/EditComposer.ts
@@ -1674,20 +1754,19 @@ var makeEditComposerStore = ({
1674
1754
  onSend
1675
1755
  }) => (0, import_zustand10.create)()((set, get, store) => ({
1676
1756
  ...makeBaseComposer(set, get, store),
1757
+ canCancel: false,
1677
1758
  isEditing: false,
1678
1759
  edit: () => {
1679
1760
  const value = onEdit();
1680
- set({ isEditing: true, value });
1761
+ set({ isEditing: true, canCancel: true, value });
1681
1762
  },
1682
1763
  send: () => {
1683
1764
  const value = get().value;
1684
- set({ isEditing: false });
1765
+ set({ isEditing: false, canCancel: false });
1685
1766
  onSend(value);
1686
1767
  },
1687
1768
  cancel: () => {
1688
- if (!get().isEditing) return false;
1689
- set({ isEditing: false });
1690
- return true;
1769
+ set({ isEditing: false, canCancel: false });
1691
1770
  }
1692
1771
  }));
1693
1772
 
@@ -1727,7 +1806,7 @@ var syncMessage = (messages, getBranches, useMessage, messageIndex) => {
1727
1806
  };
1728
1807
  var useMessageContext2 = (messageIndex) => {
1729
1808
  const { useThreadMessages, useThreadActions } = useThreadContext();
1730
- const [context] = (0, import_react47.useState)(() => {
1809
+ const [context] = (0, import_react48.useState)(() => {
1731
1810
  const useMessage = (0, import_zustand12.create)(() => ({}));
1732
1811
  const useMessageUtils = makeMessageUtilsStore();
1733
1812
  const useEditComposer = makeEditComposerStore({
@@ -1764,7 +1843,7 @@ var useMessageContext2 = (messageIndex) => {
1764
1843
  );
1765
1844
  return { useMessage, useMessageUtils, useEditComposer };
1766
1845
  });
1767
- (0, import_react47.useEffect)(() => {
1846
+ (0, import_react48.useEffect)(() => {
1768
1847
  return useThreadMessages.subscribe((thread) => {
1769
1848
  syncMessage(
1770
1849
  thread,
@@ -1806,11 +1885,11 @@ var ThreadMessageImpl = ({
1806
1885
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(MessagePrimitiveIf, { assistant: true, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(AssistantMessage, {}) })
1807
1886
  ] });
1808
1887
  };
1809
- var ThreadMessage = (0, import_react48.memo)(
1888
+ var ThreadMessage = (0, import_react49.memo)(
1810
1889
  ThreadMessageImpl,
1811
- (prev, next) => prev.messageIndex === next.messageIndex && prev.components.UserMessage === next.components.UserMessage && prev.components.EditComposer === next.components.EditComposer && prev.components.AssistantMessage === next.components.AssistantMessage
1890
+ (prev, next) => prev.messageIndex === next.messageIndex && prev.components.Message === next.components.Message && prev.components.UserMessage === next.components.UserMessage && prev.components.EditComposer === next.components.EditComposer && prev.components.AssistantMessage === next.components.AssistantMessage
1812
1891
  );
1813
- var ThreadPrimitiveMessages = ({
1892
+ var ThreadPrimitiveMessagesImpl = ({
1814
1893
  components
1815
1894
  }) => {
1816
1895
  const { useThreadMessages } = useThreadContext();
@@ -1828,7 +1907,11 @@ var ThreadPrimitiveMessages = ({
1828
1907
  );
1829
1908
  });
1830
1909
  };
1831
- ThreadPrimitiveMessages.displayName = "ThreadPrimitive.Messages";
1910
+ ThreadPrimitiveMessagesImpl.displayName = "ThreadPrimitive.Messages";
1911
+ var ThreadPrimitiveMessages = (0, import_react49.memo)(
1912
+ ThreadPrimitiveMessagesImpl,
1913
+ (prev, next) => prev.components?.Message === next.components?.Message && prev.components?.UserMessage === next.components?.UserMessage && prev.components?.EditComposer === next.components?.EditComposer && prev.components?.AssistantMessage === next.components?.AssistantMessage
1914
+ );
1832
1915
 
1833
1916
  // src/primitives/thread/ThreadScrollToBottom.tsx
1834
1917
  var ThreadPrimitiveScrollToBottom = createActionButton(
@@ -1843,7 +1926,7 @@ var ThreadPrimitiveSuggestion = createActionButton(
1843
1926
  );
1844
1927
 
1845
1928
  // src/runtime/local/useLocalRuntime.tsx
1846
- var import_react49 = require("react");
1929
+ var import_react50 = require("react");
1847
1930
 
1848
1931
  // src/runtime/utils/idUtils.tsx
1849
1932
  var import_non_secure = require("nanoid/non-secure");
@@ -2012,6 +2095,9 @@ var BaseAssistantRuntime = class {
2012
2095
  this._thread = _thread;
2013
2096
  this._unsubscribe = this._thread.subscribe(this.subscriptionHandler);
2014
2097
  }
2098
+ get capabilities() {
2099
+ return this._thread.capabilities;
2100
+ }
2015
2101
  _unsubscribe;
2016
2102
  get thread() {
2017
2103
  return this._thread;
@@ -2084,6 +2170,12 @@ var LocalRuntime = class extends BaseAssistantRuntime {
2084
2170
  );
2085
2171
  }
2086
2172
  };
2173
+ var CAPABILITIES = Object.freeze({
2174
+ edit: true,
2175
+ reload: true,
2176
+ cancel: true,
2177
+ copy: true
2178
+ });
2087
2179
  var LocalThreadRuntime = class {
2088
2180
  constructor(_configProviders, adapter) {
2089
2181
  this._configProviders = _configProviders;
@@ -2092,6 +2184,7 @@ var LocalThreadRuntime = class {
2092
2184
  _subscriptions = /* @__PURE__ */ new Set();
2093
2185
  abortController = null;
2094
2186
  repository = new MessageRepository();
2187
+ capabilities = CAPABILITIES;
2095
2188
  get messages() {
2096
2189
  return this.repository.getMessages();
2097
2190
  }
@@ -2175,8 +2268,8 @@ var LocalThreadRuntime = class {
2175
2268
 
2176
2269
  // src/runtime/local/useLocalRuntime.tsx
2177
2270
  var useLocalRuntime = (adapter) => {
2178
- const [runtime] = (0, import_react49.useState)(() => new LocalRuntime(adapter));
2179
- (0, import_react49.useInsertionEffect)(() => {
2271
+ const [runtime] = (0, import_react50.useState)(() => new LocalRuntime(adapter));
2272
+ (0, import_react50.useInsertionEffect)(() => {
2180
2273
  runtime.adapter = adapter;
2181
2274
  });
2182
2275
  return runtime;
@@ -2187,7 +2280,8 @@ var internal_exports = {};
2187
2280
  __export(internal_exports, {
2188
2281
  BaseAssistantRuntime: () => BaseAssistantRuntime,
2189
2282
  MessageRepository: () => MessageRepository,
2190
- ProxyConfigProvider: () => ProxyConfigProvider
2283
+ ProxyConfigProvider: () => ProxyConfigProvider,
2284
+ useSmooth: () => useSmooth
2191
2285
  });
2192
2286
  // Annotate the CommonJS export names for ESM import in node:
2193
2287
  0 && (module.exports = {