@assistant-ui/react 0.2.4 → 0.3.1

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.mjs CHANGED
@@ -148,11 +148,14 @@ var makeBaseComposer = (set) => ({
148
148
  });
149
149
 
150
150
  // src/context/stores/Composer.ts
151
- var makeComposerStore = (useThread, useThreadMessages, useThreadActions) => {
151
+ var makeComposerStore = (useThreadMessages, useThreadActions) => {
152
152
  const focusListeners = /* @__PURE__ */ new Set();
153
153
  return create3()((set, get, store) => {
154
154
  return {
155
155
  ...makeBaseComposer(set, get, store),
156
+ get canCancel() {
157
+ return useThreadActions.getState().capabilities.cancel;
158
+ },
156
159
  isEditing: true,
157
160
  send: () => {
158
161
  const { setValue, value } = get();
@@ -164,10 +167,7 @@ var makeComposerStore = (useThread, useThreadMessages, useThreadActions) => {
164
167
  });
165
168
  },
166
169
  cancel: () => {
167
- const thread = useThread.getState();
168
- if (!thread.isRunning) return false;
169
170
  useThreadActions.getState().cancelRun();
170
- return true;
171
171
  },
172
172
  focus: () => {
173
173
  for (const listener of focusListeners) {
@@ -217,6 +217,9 @@ import { create as create6 } from "zustand";
217
217
  var makeThreadActionStore = (runtimeRef) => {
218
218
  return create6(
219
219
  () => Object.freeze({
220
+ get capabilities() {
221
+ return runtimeRef.current.capabilities;
222
+ },
220
223
  getBranches: (messageId) => runtimeRef.current.getBranches(messageId),
221
224
  switchToBranch: (branchId) => runtimeRef.current.switchToBranch(branchId),
222
225
  startRun: (parentId) => runtimeRef.current.startRun(parentId),
@@ -248,11 +251,7 @@ var ThreadProvider = ({
248
251
  const useThreadMessages = makeThreadMessagesStore(runtimeRef);
249
252
  const useThreadActions = makeThreadActionStore(runtimeRef);
250
253
  const useViewport = makeThreadViewportStore();
251
- const useComposer = makeComposerStore(
252
- useThread,
253
- useThreadMessages,
254
- useThreadActions
255
- );
254
+ const useComposer = makeComposerStore(useThreadMessages, useThreadActions);
256
255
  return {
257
256
  useThread,
258
257
  useThreadMessages,
@@ -522,7 +521,7 @@ var useActionBarCopy = ({
522
521
  const hasCopyableContent = useCombinedStore(
523
522
  [useMessage, useEditComposer],
524
523
  (m, c) => {
525
- return !c.isEditing && m.message.content.some((c2) => c2.type === "text");
524
+ return !c.isEditing && m.message.content.some((c2) => c2.type === "text" && c2.text.length > 0);
526
525
  }
527
526
  );
528
527
  const callback = useCallback4(() => {
@@ -625,7 +624,7 @@ var useBranchPickerPrevious = () => {
625
624
  import { useCallback as useCallback9 } from "react";
626
625
  var useComposerCancel = () => {
627
626
  const { useComposer } = useComposerContext();
628
- const disabled = useComposer((c) => !c.isEditing);
627
+ const disabled = useComposer((c) => !c.canCancel);
629
628
  const callback = useCallback9(() => {
630
629
  const { cancel } = useComposer.getState();
631
630
  cancel();
@@ -695,7 +694,7 @@ var useContentPartText = () => {
695
694
  throw new Error(
696
695
  "ContentPartText can only be used inside text content parts."
697
696
  );
698
- return c.part.text;
697
+ return c;
699
698
  });
700
699
  return text;
701
700
  };
@@ -757,15 +756,18 @@ var useThreadSuggestion = ({
757
756
  autoSend
758
757
  }) => {
759
758
  const { useThread, useComposer } = useThreadContext();
759
+ const append = useAppendMessage();
760
760
  const disabled = useThread((t) => t.isRunning);
761
761
  const callback = useCallback12(() => {
762
762
  const thread = useThread.getState();
763
763
  const composer = useComposer.getState();
764
- composer.setValue(prompt);
765
764
  if (autoSend && !thread.isRunning) {
766
- composer.send();
765
+ append(prompt);
766
+ composer.setValue("");
767
+ } else {
768
+ composer.setValue(prompt);
767
769
  }
768
- }, [useThread, useComposer, prompt, autoSend]);
770
+ }, [useThread, useComposer, autoSend, append, prompt]);
769
771
  if (disabled) return null;
770
772
  return callback;
771
773
  };
@@ -1045,28 +1047,60 @@ __export(message_exports, {
1045
1047
  });
1046
1048
 
1047
1049
  // src/primitives/message/MessageRoot.tsx
1048
- import { composeEventHandlers as composeEventHandlers4 } from "@radix-ui/primitive";
1049
1050
  import { Primitive as Primitive3 } from "@radix-ui/react-primitive";
1050
- import { forwardRef as forwardRef6 } from "react";
1051
+ import {
1052
+ forwardRef as forwardRef6,
1053
+ useCallback as useCallback14
1054
+ } from "react";
1055
+
1056
+ // src/utils/hooks/useManagedRef.ts
1057
+ import { useCallback as useCallback13, useRef as useRef3 } from "react";
1058
+ var useManagedRef = (callback) => {
1059
+ const cleanupRef = useRef3();
1060
+ const ref = useCallback13(
1061
+ (el) => {
1062
+ if (cleanupRef.current) {
1063
+ cleanupRef.current();
1064
+ }
1065
+ if (el) {
1066
+ cleanupRef.current = callback(el);
1067
+ }
1068
+ },
1069
+ [callback]
1070
+ );
1071
+ return ref;
1072
+ };
1073
+
1074
+ // src/primitives/message/MessageRoot.tsx
1075
+ import { useComposedRefs } from "@radix-ui/react-compose-refs";
1051
1076
  import { jsx as jsx12 } from "react/jsx-runtime";
1052
- var MessagePrimitiveRoot = forwardRef6(({ onMouseEnter, onMouseLeave, ...rest }, ref) => {
1077
+ var useIsHoveringRef = () => {
1053
1078
  const { useMessageUtils } = useMessageContext();
1054
- const setIsHovering = useMessageUtils((s) => s.setIsHovering);
1055
- const handleMouseEnter = () => {
1056
- setIsHovering(true);
1057
- };
1058
- const handleMouseLeave = () => {
1059
- setIsHovering(false);
1060
- };
1061
- return /* @__PURE__ */ jsx12(
1062
- Primitive3.div,
1063
- {
1064
- ...rest,
1065
- ref,
1066
- onMouseEnter: composeEventHandlers4(onMouseEnter, handleMouseEnter),
1067
- onMouseLeave: composeEventHandlers4(onMouseLeave, handleMouseLeave)
1068
- }
1079
+ const callbackRef = useCallback14(
1080
+ (el) => {
1081
+ const setIsHovering = useMessageUtils.getState().setIsHovering;
1082
+ const handleMouseEnter = () => {
1083
+ setIsHovering(true);
1084
+ };
1085
+ const handleMouseLeave = () => {
1086
+ setIsHovering(false);
1087
+ };
1088
+ el.addEventListener("mouseenter", handleMouseEnter);
1089
+ el.addEventListener("mouseleave", handleMouseLeave);
1090
+ return () => {
1091
+ el.removeEventListener("mouseenter", handleMouseEnter);
1092
+ el.removeEventListener("mouseleave", handleMouseLeave);
1093
+ setIsHovering(false);
1094
+ };
1095
+ },
1096
+ [useMessageUtils]
1069
1097
  );
1098
+ return useManagedRef(callbackRef);
1099
+ };
1100
+ var MessagePrimitiveRoot = forwardRef6(({ onMouseEnter, onMouseLeave, ...rest }, forwardRef15) => {
1101
+ const isHoveringRef = useIsHoveringRef();
1102
+ const ref = useComposedRefs(forwardRef15, isHoveringRef);
1103
+ return /* @__PURE__ */ jsx12(Primitive3.div, { ...rest, ref });
1070
1104
  });
1071
1105
  MessagePrimitiveRoot.displayName = "MessagePrimitive.Root";
1072
1106
 
@@ -1126,6 +1160,29 @@ var ContentPartProvider = ({
1126
1160
  return /* @__PURE__ */ jsx13(ContentPartContext.Provider, { value: context, children });
1127
1161
  };
1128
1162
 
1163
+ // src/primitives/contentPart/ContentPartText.tsx
1164
+ import { Primitive as Primitive4 } from "@radix-ui/react-primitive";
1165
+ import { forwardRef as forwardRef7 } from "react";
1166
+ import { jsx as jsx14 } from "react/jsx-runtime";
1167
+ var ContentPartPrimitiveText = forwardRef7((props, forwardedRef) => {
1168
+ const {
1169
+ part: { text },
1170
+ status
1171
+ } = useContentPartText();
1172
+ return /* @__PURE__ */ jsx14(Primitive4.span, { "data-status": status, ...props, ref: forwardedRef, children: text });
1173
+ });
1174
+ ContentPartPrimitiveText.displayName = "ContentPartPrimitive.Text";
1175
+
1176
+ // src/primitives/contentPart/ContentPartImage.tsx
1177
+ import { Primitive as Primitive5 } from "@radix-ui/react-primitive";
1178
+ import { forwardRef as forwardRef8 } from "react";
1179
+ import { jsx as jsx15 } from "react/jsx-runtime";
1180
+ var ContentPartPrimitiveImage = forwardRef8((props, forwardedRef) => {
1181
+ const image = useContentPartImage();
1182
+ return /* @__PURE__ */ jsx15(Primitive5.img, { src: image, ...props, ref: forwardedRef });
1183
+ });
1184
+ ContentPartPrimitiveImage.displayName = "ContentPartPrimitive.Image";
1185
+
1129
1186
  // src/primitives/contentPart/ContentPartDisplay.tsx
1130
1187
  var ContentPartPrimitiveDisplay = () => {
1131
1188
  const display = useContentPartDisplay();
@@ -1133,61 +1190,31 @@ var ContentPartPrimitiveDisplay = () => {
1133
1190
  };
1134
1191
  ContentPartPrimitiveDisplay.displayName = "ContentPartPrimitive.Display";
1135
1192
 
1136
- // src/utils/OutPortal.tsx
1137
- import { useLayoutEffect, useRef as useRef3 } from "react";
1138
- import { jsx as jsx14 } from "react/jsx-runtime";
1139
- var OutPortal = ({ node }) => {
1140
- const parentRef = useRef3(null);
1141
- useLayoutEffect(() => {
1142
- const parent = parentRef.current;
1143
- if (!parent || !node) return;
1144
- parent.appendChild(node);
1145
- return () => {
1146
- parent.removeChild(node);
1147
- };
1148
- }, [node]);
1149
- if (!node) return null;
1150
- return /* @__PURE__ */ jsx14("span", { ref: parentRef });
1151
- };
1152
-
1153
- // src/primitives/contentPart/ContentPartInProgressIndicator.tsx
1154
- import { jsx as jsx15 } from "react/jsx-runtime";
1155
- var ContentPartPrimitiveInProgressIndicator = () => {
1156
- const { useMessageUtils } = useMessageContext();
1193
+ // src/primitives/contentPart/ContentPartInProgress.tsx
1194
+ var ContentPartPrimitiveInProgress = ({
1195
+ children
1196
+ }) => {
1157
1197
  const { useContentPart } = useContentPartContext();
1158
- const indicator = useCombinedStore(
1159
- [useMessageUtils, useContentPart],
1160
- (m, c) => c.status === "in_progress" ? m.inProgressIndicator : null
1161
- );
1162
- return /* @__PURE__ */ jsx15(OutPortal, { node: indicator });
1198
+ const isInProgress = useContentPart((c) => c.status === "in_progress");
1199
+ return isInProgress ? children : null;
1163
1200
  };
1164
- ContentPartPrimitiveInProgressIndicator.displayName = "ContentPartPrimitive.InProgressIndicator";
1165
-
1166
- // src/primitives/contentPart/ContentPartText.tsx
1167
- import { Primitive as Primitive4 } from "@radix-ui/react-primitive";
1168
- import { forwardRef as forwardRef7 } from "react";
1169
- import { jsx as jsx16 } from "react/jsx-runtime";
1170
- var ContentPartPrimitiveText = forwardRef7((props, forwardedRef) => {
1171
- const text = useContentPartText();
1172
- return /* @__PURE__ */ jsx16(Primitive4.span, { ...props, ref: forwardedRef, children: text });
1173
- });
1174
- ContentPartPrimitiveText.displayName = "ContentPartPrimitive.Text";
1201
+ ContentPartPrimitiveInProgress.displayName = "ContentPartPrimitive.InProgress";
1175
1202
 
1176
1203
  // src/primitives/message/MessageContent.tsx
1177
- import { jsx as jsx17, jsxs as jsxs2 } from "react/jsx-runtime";
1204
+ import { jsx as jsx16, jsxs as jsxs2 } from "react/jsx-runtime";
1178
1205
  var defaultComponents = {
1179
1206
  Text: () => /* @__PURE__ */ jsxs2("p", { style: { whiteSpace: "pre-line" }, children: [
1180
- /* @__PURE__ */ jsx17(ContentPartPrimitiveText, {}),
1181
- /* @__PURE__ */ jsx17(ContentPartPrimitiveInProgressIndicator, {})
1207
+ /* @__PURE__ */ jsx16(ContentPartPrimitiveText, {}),
1208
+ /* @__PURE__ */ jsx16(ContentPartPrimitiveInProgress, { children: /* @__PURE__ */ jsx16("span", { style: { fontFamily: "revert" }, children: " \u25CF" }) })
1182
1209
  ] }),
1183
- Image: () => null,
1184
- UI: () => /* @__PURE__ */ jsx17(ContentPartPrimitiveDisplay, {}),
1210
+ Image: () => /* @__PURE__ */ jsx16(ContentPartPrimitiveImage, {}),
1211
+ UI: () => /* @__PURE__ */ jsx16(ContentPartPrimitiveDisplay, {}),
1185
1212
  tools: {
1186
1213
  Fallback: (props) => {
1187
1214
  const { useToolUIs } = useAssistantContext();
1188
1215
  const Render = useToolUIs((s) => s.getToolUI(props.part.toolName));
1189
1216
  if (!Render) return null;
1190
- return /* @__PURE__ */ jsx17(Render, { ...props });
1217
+ return /* @__PURE__ */ jsx16(Render, { ...props });
1191
1218
  }
1192
1219
  }
1193
1220
  };
@@ -1206,15 +1233,15 @@ var MessageContentPartComponent = ({
1206
1233
  const type = part.type;
1207
1234
  switch (type) {
1208
1235
  case "text":
1209
- return /* @__PURE__ */ jsx17(Text, { part, status });
1236
+ return /* @__PURE__ */ jsx16(Text, { part, status });
1210
1237
  case "image":
1211
- return /* @__PURE__ */ jsx17(Image, { part, status });
1238
+ return /* @__PURE__ */ jsx16(Image, { part, status });
1212
1239
  case "ui":
1213
- return /* @__PURE__ */ jsx17(UI, { part, status });
1240
+ return /* @__PURE__ */ jsx16(UI, { part, status });
1214
1241
  case "tool-call": {
1215
1242
  const Tool = by_name[part.toolName] || Fallback;
1216
1243
  const addResult = (result) => addToolResult(part.toolCallId, result);
1217
- return /* @__PURE__ */ jsx17(Tool, { part, status, addResult });
1244
+ return /* @__PURE__ */ jsx16(Tool, { part, status, addResult });
1218
1245
  }
1219
1246
  default:
1220
1247
  throw new Error(`Unknown content part type: ${type}`);
@@ -1224,7 +1251,7 @@ var MessageContentPartImpl = ({
1224
1251
  partIndex,
1225
1252
  components
1226
1253
  }) => {
1227
- return /* @__PURE__ */ jsx17(ContentPartProvider, { partIndex, children: /* @__PURE__ */ jsx17(MessageContentPartComponent, { components }) });
1254
+ return /* @__PURE__ */ jsx16(ContentPartProvider, { partIndex, children: /* @__PURE__ */ jsx16(MessageContentPartComponent, { components }) });
1228
1255
  };
1229
1256
  var MessageContentPart = memo2(
1230
1257
  MessageContentPartImpl,
@@ -1237,7 +1264,7 @@ var MessagePrimitiveContent = ({
1237
1264
  const contentLength = useMessage((s) => s.message.content.length);
1238
1265
  return new Array(contentLength).fill(null).map((_, idx) => {
1239
1266
  const partIndex = idx;
1240
- return /* @__PURE__ */ jsx17(
1267
+ return /* @__PURE__ */ jsx16(
1241
1268
  MessageContentPart,
1242
1269
  {
1243
1270
  partIndex,
@@ -1250,21 +1277,15 @@ var MessagePrimitiveContent = ({
1250
1277
  MessagePrimitiveContent.displayName = "MessagePrimitive.Content";
1251
1278
 
1252
1279
  // src/primitives/message/MessageInProgress.tsx
1253
- import { createPortal } from "react-dom";
1254
- import { Primitive as Primitive5 } from "@radix-ui/react-primitive";
1255
- import { forwardRef as forwardRef8 } from "react";
1256
- import { jsx as jsx18 } from "react/jsx-runtime";
1257
- var MessagePrimitiveInProgress = forwardRef8((props, ref) => {
1258
- const { useMessageUtils } = useMessageContext();
1259
- const portalNode = useMessageUtils((s) => s.inProgressIndicator);
1260
- return createPortal(/* @__PURE__ */ jsx18(Primitive5.span, { ...props, ref }), portalNode);
1261
- });
1280
+ var MessagePrimitiveInProgress = () => {
1281
+ return null;
1282
+ };
1262
1283
  MessagePrimitiveInProgress.displayName = "MessagePrimitive.InProgress";
1263
1284
 
1264
1285
  // src/primitives/branchPicker/BranchPickerRoot.tsx
1265
- import { jsx as jsx19 } from "react/jsx-runtime";
1286
+ import { jsx as jsx17 } from "react/jsx-runtime";
1266
1287
  var BranchPickerPrimitiveRoot = forwardRef9(({ hideWhenSingleBranch, ...rest }, ref) => {
1267
- return /* @__PURE__ */ jsx19(MessagePrimitiveIf, { hasBranches: hideWhenSingleBranch ? true : void 0, children: /* @__PURE__ */ jsx19(Primitive6.div, { ...rest, ref }) });
1288
+ return /* @__PURE__ */ jsx17(MessagePrimitiveIf, { hasBranches: hideWhenSingleBranch ? true : void 0, children: /* @__PURE__ */ jsx17(Primitive6.div, { ...rest, ref }) });
1268
1289
  });
1269
1290
  BranchPickerPrimitiveRoot.displayName = "BranchPickerPrimitive.Root";
1270
1291
 
@@ -1279,12 +1300,12 @@ __export(composer_exports, {
1279
1300
  });
1280
1301
 
1281
1302
  // src/primitives/composer/ComposerRoot.tsx
1282
- import { composeEventHandlers as composeEventHandlers5 } from "@radix-ui/primitive";
1303
+ import { composeEventHandlers as composeEventHandlers4 } from "@radix-ui/primitive";
1283
1304
  import { Primitive as Primitive7 } from "@radix-ui/react-primitive";
1284
1305
  import {
1285
1306
  forwardRef as forwardRef10
1286
1307
  } from "react";
1287
- import { jsx as jsx20 } from "react/jsx-runtime";
1308
+ import { jsx as jsx18 } from "react/jsx-runtime";
1288
1309
  var ComposerPrimitiveRoot = forwardRef10(({ onSubmit, ...rest }, forwardedRef) => {
1289
1310
  const send = useComposerSend();
1290
1311
  const handleSubmit = (e) => {
@@ -1292,30 +1313,30 @@ var ComposerPrimitiveRoot = forwardRef10(({ onSubmit, ...rest }, forwardedRef) =
1292
1313
  if (!send) return;
1293
1314
  send();
1294
1315
  };
1295
- return /* @__PURE__ */ jsx20(
1316
+ return /* @__PURE__ */ jsx18(
1296
1317
  Primitive7.form,
1297
1318
  {
1298
1319
  ...rest,
1299
1320
  ref: forwardedRef,
1300
- onSubmit: composeEventHandlers5(onSubmit, handleSubmit)
1321
+ onSubmit: composeEventHandlers4(onSubmit, handleSubmit)
1301
1322
  }
1302
1323
  );
1303
1324
  });
1304
1325
  ComposerPrimitiveRoot.displayName = "ComposerPrimitive.Root";
1305
1326
 
1306
1327
  // src/primitives/composer/ComposerInput.tsx
1307
- import { composeEventHandlers as composeEventHandlers6 } from "@radix-ui/primitive";
1308
- import { useComposedRefs } from "@radix-ui/react-compose-refs";
1328
+ import { composeEventHandlers as composeEventHandlers5 } from "@radix-ui/primitive";
1329
+ import { useComposedRefs as useComposedRefs2 } from "@radix-ui/react-compose-refs";
1309
1330
  import { Slot } from "@radix-ui/react-slot";
1310
1331
  import {
1311
1332
  forwardRef as forwardRef11,
1312
- useCallback as useCallback13,
1333
+ useCallback as useCallback15,
1313
1334
  useEffect as useEffect8,
1314
1335
  useRef as useRef4
1315
1336
  } from "react";
1316
1337
  import TextareaAutosize from "react-textarea-autosize";
1317
1338
  import { useEscapeKeydown } from "@radix-ui/react-use-escape-keydown";
1318
- import { jsx as jsx21 } from "react/jsx-runtime";
1339
+ import { jsx as jsx19 } from "react/jsx-runtime";
1319
1340
  var ComposerPrimitiveInput = forwardRef11(
1320
1341
  ({ autoFocus = false, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
1321
1342
  const { useThread } = useThreadContext();
@@ -1326,10 +1347,11 @@ var ComposerPrimitiveInput = forwardRef11(
1326
1347
  });
1327
1348
  const Component = asChild ? Slot : TextareaAutosize;
1328
1349
  const textareaRef = useRef4(null);
1329
- const ref = useComposedRefs(forwardedRef, textareaRef);
1350
+ const ref = useComposedRefs2(forwardedRef, textareaRef);
1330
1351
  useEscapeKeydown((e) => {
1331
1352
  const composer = useComposer.getState();
1332
- if (composer.cancel()) {
1353
+ if (composer.canCancel) {
1354
+ composer.cancel();
1333
1355
  e.preventDefault();
1334
1356
  }
1335
1357
  });
@@ -1344,7 +1366,7 @@ var ComposerPrimitiveInput = forwardRef11(
1344
1366
  }
1345
1367
  };
1346
1368
  const autoFocusEnabled = autoFocus && !disabled;
1347
- const focus = useCallback13(() => {
1369
+ const focus = useCallback15(() => {
1348
1370
  const textarea = textareaRef.current;
1349
1371
  if (!textarea || !autoFocusEnabled) return;
1350
1372
  textarea.focus({ preventScroll: true });
@@ -1359,19 +1381,20 @@ var ComposerPrimitiveInput = forwardRef11(
1359
1381
  focus();
1360
1382
  }
1361
1383
  });
1362
- return /* @__PURE__ */ jsx21(
1384
+ return /* @__PURE__ */ jsx19(
1363
1385
  Component,
1364
1386
  {
1387
+ name: "input",
1365
1388
  value,
1366
1389
  ...rest,
1367
1390
  ref,
1368
1391
  disabled,
1369
- onChange: composeEventHandlers6(onChange, (e) => {
1392
+ onChange: composeEventHandlers5(onChange, (e) => {
1370
1393
  const composerState = useComposer.getState();
1371
1394
  if (!composerState.isEditing) return;
1372
1395
  return composerState.setValue(e.target.value);
1373
1396
  }),
1374
- onKeyDown: composeEventHandlers6(onKeyDown, handleKeyPress)
1397
+ onKeyDown: composeEventHandlers5(onKeyDown, handleKeyPress)
1375
1398
  }
1376
1399
  );
1377
1400
  }
@@ -1381,11 +1404,11 @@ ComposerPrimitiveInput.displayName = "ComposerPrimitive.Input";
1381
1404
  // src/primitives/composer/ComposerSend.tsx
1382
1405
  import { forwardRef as forwardRef12 } from "react";
1383
1406
  import { Primitive as Primitive8 } from "@radix-ui/react-primitive";
1384
- import { jsx as jsx22 } from "react/jsx-runtime";
1407
+ import { jsx as jsx20 } from "react/jsx-runtime";
1385
1408
  var ComposerPrimitiveSend = forwardRef12(({ disabled, ...rest }, ref) => {
1386
1409
  const { useComposer } = useComposerContext();
1387
1410
  const hasValue = useComposer((c) => c.isEditing && c.value.length > 0);
1388
- return /* @__PURE__ */ jsx22(
1411
+ return /* @__PURE__ */ jsx20(
1389
1412
  Primitive8.button,
1390
1413
  {
1391
1414
  type: "submit",
@@ -1418,20 +1441,10 @@ var contentPart_exports = {};
1418
1441
  __export(contentPart_exports, {
1419
1442
  Display: () => ContentPartPrimitiveDisplay,
1420
1443
  Image: () => ContentPartPrimitiveImage,
1421
- InProgressIndicator: () => ContentPartPrimitiveInProgressIndicator,
1444
+ InProgress: () => ContentPartPrimitiveInProgress,
1422
1445
  Text: () => ContentPartPrimitiveText
1423
1446
  });
1424
1447
 
1425
- // src/primitives/contentPart/ContentPartImage.tsx
1426
- import { Primitive as Primitive9 } from "@radix-ui/react-primitive";
1427
- import { forwardRef as forwardRef13 } from "react";
1428
- import { jsx as jsx23 } from "react/jsx-runtime";
1429
- var ContentPartPrimitiveImage = forwardRef13((props, forwardedRef) => {
1430
- const image = useContentPartImage();
1431
- return /* @__PURE__ */ jsx23(Primitive9.img, { src: image, ...props, ref: forwardedRef });
1432
- });
1433
- ContentPartPrimitiveImage.displayName = "ContentPartPrimitive.Image";
1434
-
1435
1448
  // src/primitives/thread/index.ts
1436
1449
  var thread_exports = {};
1437
1450
  __export(thread_exports, {
@@ -1445,11 +1458,11 @@ __export(thread_exports, {
1445
1458
  });
1446
1459
 
1447
1460
  // src/primitives/thread/ThreadRoot.tsx
1448
- import { Primitive as Primitive10 } from "@radix-ui/react-primitive";
1449
- import { forwardRef as forwardRef14 } from "react";
1450
- import { jsx as jsx24 } from "react/jsx-runtime";
1451
- var ThreadPrimitiveRoot = forwardRef14((props, ref) => {
1452
- return /* @__PURE__ */ jsx24(Primitive10.div, { ...props, ref });
1461
+ import { Primitive as Primitive9 } from "@radix-ui/react-primitive";
1462
+ import { forwardRef as forwardRef13 } from "react";
1463
+ import { jsx as jsx21 } from "react/jsx-runtime";
1464
+ var ThreadPrimitiveRoot = forwardRef13((props, ref) => {
1465
+ return /* @__PURE__ */ jsx21(Primitive9.div, { ...props, ref });
1453
1466
  });
1454
1467
  ThreadPrimitiveRoot.displayName = "ThreadPrimitive.Root";
1455
1468
 
@@ -1473,40 +1486,20 @@ var ThreadPrimitiveIf = ({
1473
1486
  ThreadPrimitiveIf.displayName = "ThreadPrimitive.If";
1474
1487
 
1475
1488
  // src/primitives/thread/ThreadViewport.tsx
1476
- import { useComposedRefs as useComposedRefs3 } from "@radix-ui/react-compose-refs";
1477
- import { Primitive as Primitive11 } from "@radix-ui/react-primitive";
1478
- import { forwardRef as forwardRef15 } from "react";
1489
+ import { useComposedRefs as useComposedRefs4 } from "@radix-ui/react-compose-refs";
1490
+ import { Primitive as Primitive10 } from "@radix-ui/react-primitive";
1491
+ import { forwardRef as forwardRef14 } from "react";
1479
1492
 
1480
1493
  // src/primitive-hooks/thread/useThreadViewportAutoScroll.tsx
1481
- import { useComposedRefs as useComposedRefs2 } from "@radix-ui/react-compose-refs";
1482
- import { useRef as useRef6 } from "react";
1494
+ import { useComposedRefs as useComposedRefs3 } from "@radix-ui/react-compose-refs";
1495
+ import { useRef as useRef5 } from "react";
1483
1496
 
1484
1497
  // src/utils/hooks/useOnResizeContent.tsx
1485
1498
  import { useCallbackRef as useCallbackRef2 } from "@radix-ui/react-use-callback-ref";
1486
- import { useCallback as useCallback15 } from "react";
1487
-
1488
- // src/utils/hooks/useManagedRef.ts
1489
- import { useCallback as useCallback14, useRef as useRef5 } from "react";
1490
- var useManagedRef = (callback) => {
1491
- const cleanupRef = useRef5();
1492
- const ref = useCallback14(
1493
- (el) => {
1494
- if (cleanupRef.current) {
1495
- cleanupRef.current();
1496
- }
1497
- if (el) {
1498
- cleanupRef.current = callback(el);
1499
- }
1500
- },
1501
- [callback]
1502
- );
1503
- return ref;
1504
- };
1505
-
1506
- // src/utils/hooks/useOnResizeContent.tsx
1499
+ import { useCallback as useCallback16 } from "react";
1507
1500
  var useOnResizeContent = (callback) => {
1508
1501
  const callbackRef = useCallbackRef2(callback);
1509
- const refCallback = useCallback15(
1502
+ const refCallback = useCallback16(
1510
1503
  (el) => {
1511
1504
  const resizeObserver = new ResizeObserver(() => {
1512
1505
  callbackRef();
@@ -1558,11 +1551,11 @@ var useOnScrollToBottom = (callback) => {
1558
1551
  var useThreadViewportAutoScroll = ({
1559
1552
  autoScroll = true
1560
1553
  }) => {
1561
- const divRef = useRef6(null);
1554
+ const divRef = useRef5(null);
1562
1555
  const { useViewport } = useThreadContext();
1563
- const firstRenderRef = useRef6(true);
1564
- const lastScrollTop = useRef6(0);
1565
- const isScrollingToBottomRef = useRef6(false);
1556
+ const firstRenderRef = useRef5(true);
1557
+ const lastScrollTop = useRef5(0);
1558
+ const isScrollingToBottomRef = useRef5(false);
1566
1559
  const scrollToBottom = () => {
1567
1560
  const div = divRef.current;
1568
1561
  if (!div || !autoScroll) return;
@@ -1600,7 +1593,7 @@ var useThreadViewportAutoScroll = ({
1600
1593
  el.removeEventListener("scroll", handleScroll);
1601
1594
  };
1602
1595
  });
1603
- const autoScrollRef = useComposedRefs2(resizeRef, scrollRef, divRef);
1596
+ const autoScrollRef = useComposedRefs3(resizeRef, scrollRef, divRef);
1604
1597
  useOnScrollToBottom(() => {
1605
1598
  scrollToBottom();
1606
1599
  });
@@ -1608,13 +1601,13 @@ var useThreadViewportAutoScroll = ({
1608
1601
  };
1609
1602
 
1610
1603
  // src/primitives/thread/ThreadViewport.tsx
1611
- import { jsx as jsx25 } from "react/jsx-runtime";
1612
- var ThreadPrimitiveViewport = forwardRef15(({ autoScroll, onScroll, children, ...rest }, forwardedRef) => {
1604
+ import { jsx as jsx22 } from "react/jsx-runtime";
1605
+ var ThreadPrimitiveViewport = forwardRef14(({ autoScroll, onScroll, children, ...rest }, forwardedRef) => {
1613
1606
  const autoScrollRef = useThreadViewportAutoScroll({
1614
1607
  autoScroll
1615
1608
  });
1616
- const ref = useComposedRefs3(forwardedRef, autoScrollRef);
1617
- return /* @__PURE__ */ jsx25(Primitive11.div, { ...rest, ref, children });
1609
+ const ref = useComposedRefs4(forwardedRef, autoScrollRef);
1610
+ return /* @__PURE__ */ jsx22(Primitive10.div, { ...rest, ref, children });
1618
1611
  });
1619
1612
  ThreadPrimitiveViewport.displayName = "ThreadPrimitive.Viewport";
1620
1613
 
@@ -1632,27 +1625,25 @@ var makeEditComposerStore = ({
1632
1625
  onSend
1633
1626
  }) => create10()((set, get, store) => ({
1634
1627
  ...makeBaseComposer(set, get, store),
1628
+ canCancel: false,
1635
1629
  isEditing: false,
1636
1630
  edit: () => {
1637
1631
  const value = onEdit();
1638
- set({ isEditing: true, value });
1632
+ set({ isEditing: true, canCancel: true, value });
1639
1633
  },
1640
1634
  send: () => {
1641
1635
  const value = get().value;
1642
- set({ isEditing: false });
1636
+ set({ isEditing: false, canCancel: false });
1643
1637
  onSend(value);
1644
1638
  },
1645
1639
  cancel: () => {
1646
- if (!get().isEditing) return false;
1647
- set({ isEditing: false });
1648
- return true;
1640
+ set({ isEditing: false, canCancel: false });
1649
1641
  }
1650
1642
  }));
1651
1643
 
1652
1644
  // src/context/stores/MessageUtils.ts
1653
1645
  import { create as create11 } from "zustand";
1654
1646
  var makeMessageUtilsStore = () => create11((set) => ({
1655
- inProgressIndicator: document.createElement("span"),
1656
1647
  isCopied: false,
1657
1648
  setIsCopied: (value) => {
1658
1649
  set({ isCopied: value });
@@ -1664,7 +1655,7 @@ var makeMessageUtilsStore = () => create11((set) => ({
1664
1655
  }));
1665
1656
 
1666
1657
  // src/context/providers/MessageProvider.tsx
1667
- import { jsx as jsx26 } from "react/jsx-runtime";
1658
+ import { jsx as jsx23 } from "react/jsx-runtime";
1668
1659
  var getIsLast = (messages, message) => {
1669
1660
  return messages[messages.length - 1]?.id === message.id;
1670
1661
  };
@@ -1740,11 +1731,11 @@ var MessageProvider = ({
1740
1731
  children
1741
1732
  }) => {
1742
1733
  const context = useMessageContext2(messageIndex);
1743
- return /* @__PURE__ */ jsx26(MessageContext.Provider, { value: context, children });
1734
+ return /* @__PURE__ */ jsx23(MessageContext.Provider, { value: context, children });
1744
1735
  };
1745
1736
 
1746
1737
  // src/primitives/thread/ThreadMessages.tsx
1747
- import { jsx as jsx27, jsxs as jsxs3 } from "react/jsx-runtime";
1738
+ import { jsx as jsx24, jsxs as jsxs3 } from "react/jsx-runtime";
1748
1739
  var getComponents = (components) => {
1749
1740
  return {
1750
1741
  EditComposer: components.EditComposer ?? components.UserMessage ?? components.Message,
@@ -1759,17 +1750,17 @@ var ThreadMessageImpl = ({
1759
1750
  const { UserMessage, EditComposer, AssistantMessage } = getComponents(components);
1760
1751
  return /* @__PURE__ */ jsxs3(MessageProvider, { messageIndex, children: [
1761
1752
  /* @__PURE__ */ jsxs3(MessagePrimitiveIf, { user: true, children: [
1762
- /* @__PURE__ */ jsx27(ComposerPrimitiveIf, { editing: false, children: /* @__PURE__ */ jsx27(UserMessage, {}) }),
1763
- /* @__PURE__ */ jsx27(ComposerPrimitiveIf, { editing: true, children: /* @__PURE__ */ jsx27(EditComposer, {}) })
1753
+ /* @__PURE__ */ jsx24(ComposerPrimitiveIf, { editing: false, children: /* @__PURE__ */ jsx24(UserMessage, {}) }),
1754
+ /* @__PURE__ */ jsx24(ComposerPrimitiveIf, { editing: true, children: /* @__PURE__ */ jsx24(EditComposer, {}) })
1764
1755
  ] }),
1765
- /* @__PURE__ */ jsx27(MessagePrimitiveIf, { assistant: true, children: /* @__PURE__ */ jsx27(AssistantMessage, {}) })
1756
+ /* @__PURE__ */ jsx24(MessagePrimitiveIf, { assistant: true, children: /* @__PURE__ */ jsx24(AssistantMessage, {}) })
1766
1757
  ] });
1767
1758
  };
1768
1759
  var ThreadMessage = memo3(
1769
1760
  ThreadMessageImpl,
1770
- (prev, next) => prev.messageIndex === next.messageIndex && prev.components.UserMessage === next.components.UserMessage && prev.components.EditComposer === next.components.EditComposer && prev.components.AssistantMessage === next.components.AssistantMessage
1761
+ (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
1771
1762
  );
1772
- var ThreadPrimitiveMessages = ({
1763
+ var ThreadPrimitiveMessagesImpl = ({
1773
1764
  components
1774
1765
  }) => {
1775
1766
  const { useThreadMessages } = useThreadContext();
@@ -1777,7 +1768,7 @@ var ThreadPrimitiveMessages = ({
1777
1768
  if (messagesLength === 0) return null;
1778
1769
  return new Array(messagesLength).fill(null).map((_, idx) => {
1779
1770
  const messageIndex = idx;
1780
- return /* @__PURE__ */ jsx27(
1771
+ return /* @__PURE__ */ jsx24(
1781
1772
  ThreadMessage,
1782
1773
  {
1783
1774
  messageIndex,
@@ -1787,7 +1778,11 @@ var ThreadPrimitiveMessages = ({
1787
1778
  );
1788
1779
  });
1789
1780
  };
1790
- ThreadPrimitiveMessages.displayName = "ThreadPrimitive.Messages";
1781
+ ThreadPrimitiveMessagesImpl.displayName = "ThreadPrimitive.Messages";
1782
+ var ThreadPrimitiveMessages = memo3(
1783
+ ThreadPrimitiveMessagesImpl,
1784
+ (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
1785
+ );
1791
1786
 
1792
1787
  // src/primitives/thread/ThreadScrollToBottom.tsx
1793
1788
  var ThreadPrimitiveScrollToBottom = createActionButton(
@@ -1971,6 +1966,9 @@ var BaseAssistantRuntime = class {
1971
1966
  this._thread = _thread;
1972
1967
  this._unsubscribe = this._thread.subscribe(this.subscriptionHandler);
1973
1968
  }
1969
+ get capabilities() {
1970
+ return this._thread.capabilities;
1971
+ }
1974
1972
  _unsubscribe;
1975
1973
  get thread() {
1976
1974
  return this._thread;
@@ -2043,6 +2041,12 @@ var LocalRuntime = class extends BaseAssistantRuntime {
2043
2041
  );
2044
2042
  }
2045
2043
  };
2044
+ var CAPABILITIES = Object.freeze({
2045
+ edit: true,
2046
+ reload: true,
2047
+ cancel: true,
2048
+ copy: true
2049
+ });
2046
2050
  var LocalThreadRuntime = class {
2047
2051
  constructor(_configProviders, adapter) {
2048
2052
  this._configProviders = _configProviders;
@@ -2051,6 +2055,7 @@ var LocalThreadRuntime = class {
2051
2055
  _subscriptions = /* @__PURE__ */ new Set();
2052
2056
  abortController = null;
2053
2057
  repository = new MessageRepository();
2058
+ capabilities = CAPABILITIES;
2054
2059
  get messages() {
2055
2060
  return this.repository.getMessages();
2056
2061
  }