@assistant-ui/react 0.2.4 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
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
  }