@assistant-ui/react 0.0.13 → 0.0.14

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.js CHANGED
@@ -75,7 +75,7 @@ var useAssistantContext = () => {
75
75
  const context = (0, import_react2.useContext)(AssistantContext);
76
76
  if (!context)
77
77
  throw new Error(
78
- "useAssistantContext must be used within a AssistantProvider"
78
+ "This component must be used within a AssistantProvider"
79
79
  );
80
80
  return context;
81
81
  };
@@ -225,7 +225,7 @@ var MessageContext = (0, import_react6.createContext)(null);
225
225
  var useMessageContext = () => {
226
226
  const context = (0, import_react6.useContext)(MessageContext);
227
227
  if (!context)
228
- throw new Error("useMessageContext must be used within a MessageProvider");
228
+ throw new Error("This component must be used within a MessageProvider");
229
229
  return context;
230
230
  };
231
231
 
@@ -330,6 +330,7 @@ var useMessageContext2 = () => {
330
330
  const [context] = (0, import_react8.useState)(() => {
331
331
  const useMessage = (0, import_zustand2.create)(() => ({
332
332
  message: null,
333
+ parentId: null,
333
334
  branches: [],
334
335
  isLast: false,
335
336
  isCopied: false,
@@ -344,15 +345,19 @@ var useMessageContext2 = () => {
344
345
  const message = useMessage.getState().message;
345
346
  if (message.role !== "user")
346
347
  throw new Error("Editing is only supported for user messages");
347
- if (message.content[0]?.type !== "text")
348
- throw new Error("Editing is only supported for text-only messages");
349
- return message.content[0].text;
348
+ const text = message.content.filter((part) => part.type === "text").map((part) => part.text).join("\n");
349
+ return text;
350
350
  },
351
351
  onSend: (text) => {
352
- const message = useMessage.getState().message;
352
+ const { message, parentId } = useMessage.getState();
353
+ if (message.role !== "user")
354
+ throw new Error("Editing is only supported for user messages");
355
+ const nonTextParts = message.content.filter(
356
+ (part) => part.type !== "text" && part.type !== "ui"
357
+ );
353
358
  useThread.getState().append({
354
- parentId: message.parentId,
355
- content: [{ type: "text", text }]
359
+ parentId,
360
+ content: [{ type: "text", text }, ...nonTextParts]
356
361
  });
357
362
  }
358
363
  });
@@ -362,6 +367,7 @@ var useMessageContext2 = () => {
362
367
  };
363
368
  var MessageProvider = ({
364
369
  message,
370
+ parentId,
365
371
  children
366
372
  }) => {
367
373
  const { useThread } = useAssistantContext();
@@ -374,6 +380,7 @@ var MessageProvider = ({
374
380
  context.useMessage.setState(
375
381
  {
376
382
  message,
383
+ parentId,
377
384
  branches,
378
385
  isLast,
379
386
  isCopied,
@@ -383,7 +390,7 @@ var MessageProvider = ({
383
390
  },
384
391
  true
385
392
  );
386
- }, [context, message, branches, isLast, isCopied, isHovering]);
393
+ }, [context, message, parentId, branches, isLast, isCopied, isHovering]);
387
394
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MessageContext.Provider, { value: context, children });
388
395
  };
389
396
 
@@ -494,15 +501,21 @@ var ThreadMessages = ({ components }) => {
494
501
  if (messages.length === 0)
495
502
  return null;
496
503
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, { children: messages.map((message, idx) => {
497
- return (
498
- // biome-ignore lint/suspicious/noArrayIndexKey: fixes a11y issues with branch navigation
499
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(MessageProvider, { message, children: [
500
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(MessageIf, { user: true, children: [
501
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ComposerIf, { editing: false, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(UserMessage, {}) }),
502
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ComposerIf, { editing: true, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(EditComposer, {}) })
503
- ] }),
504
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MessageIf, { assistant: true, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AssistantMessage, {}) })
505
- ] }, idx)
504
+ const parentId = messages[idx - 1]?.id ?? null;
505
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
506
+ MessageProvider,
507
+ {
508
+ message,
509
+ parentId,
510
+ children: [
511
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(MessageIf, { user: true, children: [
512
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ComposerIf, { editing: false, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(UserMessage, {}) }),
513
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ComposerIf, { editing: true, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(EditComposer, {}) })
514
+ ] }),
515
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MessageIf, { assistant: true, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AssistantMessage, {}) })
516
+ ]
517
+ },
518
+ parentId ?? "__ROOT__"
506
519
  );
507
520
  }) });
508
521
  };
@@ -605,7 +618,7 @@ var import_react13 = require("react");
605
618
  var import_react_textarea_autosize = __toESM(require("react-textarea-autosize"));
606
619
  var import_jsx_runtime11 = require("react/jsx-runtime");
607
620
  var ComposerInput = (0, import_react13.forwardRef)(
608
- ({ autoFocus, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
621
+ ({ autoFocus = false, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
609
622
  const { useThread, useViewport } = useAssistantContext();
610
623
  const { useComposer, type } = useComposerContext();
611
624
  const value = useComposer((c) => {
@@ -633,7 +646,7 @@ var ComposerInput = (0, import_react13.forwardRef)(
633
646
  };
634
647
  const textareaRef = (0, import_react13.useRef)(null);
635
648
  const ref = (0, import_react_compose_refs3.useComposedRefs)(forwardedRef, textareaRef);
636
- const autoFocusEnabled = autoFocus !== false && !disabled;
649
+ const autoFocusEnabled = autoFocus && !disabled;
637
650
  const focus = (0, import_react13.useCallback)(() => {
638
651
  const textarea = textareaRef.current;
639
652
  if (!textarea || !autoFocusEnabled)
@@ -907,10 +920,10 @@ var useReloadMessage = () => {
907
920
  if (disabled)
908
921
  return null;
909
922
  return () => {
910
- const message = useMessage.getState().message;
923
+ const { message, parentId } = useMessage.getState();
911
924
  if (message.role !== "assistant")
912
925
  throw new Error("Reloading is only supported on assistant messages");
913
- useThread.getState().startRun(message.parentId);
926
+ useThread.getState().startRun(parentId);
914
927
  useViewport.getState().scrollToBottom();
915
928
  };
916
929
  };
@@ -995,7 +1008,7 @@ var useDummyAIAssistantContext = () => {
995
1008
  return context;
996
1009
  };
997
1010
 
998
- // src/adapters/vercel/useVercelAIBranches.tsx
1011
+ // src/adapters/vercel/useVercelAIThreadState.tsx
999
1012
  var import_react22 = require("react");
1000
1013
 
1001
1014
  // src/adapters/MessageRepository.tsx
@@ -1024,17 +1037,26 @@ var MessageRepository = class {
1024
1037
  }
1025
1038
  return messages;
1026
1039
  }
1027
- addOrUpdateMessage(message) {
1040
+ // TODO previousId is confusing
1041
+ // TODO previousId does not fix children
1042
+ // TODO cut / link operations
1043
+ addOrUpdateMessage(parentId, message, previousId = message.id) {
1028
1044
  const item = this.messages.get(message.id);
1029
1045
  if (item) {
1030
- if (item.current.parentId !== message.parentId) {
1031
- this.deleteMessage(message.id);
1032
- } else {
1033
- item.current = message;
1034
- return;
1046
+ if (item.prev?.current.id !== parentId) {
1047
+ if ((item.prev?.current.id ?? null) !== parentId) {
1048
+ this.deleteMessage(message.id);
1049
+ } else {
1050
+ item.current = message;
1051
+ if (previousId !== message.id) {
1052
+ this.messages.delete(previousId);
1053
+ this.messages.set(message.id, item);
1054
+ }
1055
+ return;
1056
+ }
1035
1057
  }
1036
1058
  }
1037
- const prev = message.parentId ? this.messages.get(message.parentId) : null;
1059
+ const prev = parentId ? this.messages.get(parentId) : null;
1038
1060
  if (prev === void 0)
1039
1061
  throw new Error("Unexpected: Parent message not found");
1040
1062
  const newItem = {
@@ -1083,16 +1105,27 @@ var MessageRepository = class {
1083
1105
  this.head = message.prev ? findHead(message.prev) : null;
1084
1106
  }
1085
1107
  }
1086
- getOptimisticId = () => {
1108
+ getOptimisticId() {
1087
1109
  let optimisticId;
1088
1110
  do {
1089
1111
  optimisticId = generateOptimisticId();
1090
1112
  } while (this.messages.has(optimisticId));
1091
1113
  return optimisticId;
1092
- };
1114
+ }
1115
+ commitOptimisticAppend(message) {
1116
+ const optimisticIdUser = this.getOptimisticId();
1117
+ this.addOrUpdateMessage(message.parentId, {
1118
+ id: optimisticIdUser,
1119
+ role: "user",
1120
+ content: message.content,
1121
+ createdAt: /* @__PURE__ */ new Date()
1122
+ });
1123
+ const optimisticIdAssistant = this.commitOptimisticRun(optimisticIdUser);
1124
+ return [optimisticIdUser, optimisticIdAssistant];
1125
+ }
1093
1126
  commitOptimisticRun(parentId) {
1094
1127
  const optimisticId = this.getOptimisticId();
1095
- this.addOrUpdateMessage({
1128
+ this.addOrUpdateMessage(parentId, {
1096
1129
  id: optimisticId,
1097
1130
  role: "assistant",
1098
1131
  content: [
@@ -1101,7 +1134,6 @@ var MessageRepository = class {
1101
1134
  text: ""
1102
1135
  }
1103
1136
  ],
1104
- parentId,
1105
1137
  createdAt: /* @__PURE__ */ new Date()
1106
1138
  });
1107
1139
  return optimisticId;
@@ -1141,7 +1173,37 @@ var MessageRepository = class {
1141
1173
  }
1142
1174
  };
1143
1175
 
1144
- // src/adapters/vercel/useVercelAIBranches.tsx
1176
+ // src/adapters/ThreadMessageConverter.tsx
1177
+ var ThreadMessageConverter = class {
1178
+ constructor(converter2) {
1179
+ this.converter = converter2;
1180
+ }
1181
+ cache = /* @__PURE__ */ new WeakMap();
1182
+ convertMessages(messages) {
1183
+ return messages.map((m) => {
1184
+ const cached = this.cache.get(m);
1185
+ if (cached)
1186
+ return cached;
1187
+ const newMessage = this.converter(m);
1188
+ this.cache.set(m, newMessage);
1189
+ return newMessage;
1190
+ });
1191
+ }
1192
+ };
1193
+
1194
+ // src/adapters/vercel/useVercelAIThreadState.tsx
1195
+ var vercelToThreadMessage = (message) => {
1196
+ if (message.role !== "user" && message.role !== "assistant")
1197
+ throw new Error("Unsupported role");
1198
+ return {
1199
+ id: message.id,
1200
+ role: message.role,
1201
+ content: [{ type: "text", text: message.content }],
1202
+ createdAt: message.createdAt ?? /* @__PURE__ */ new Date(),
1203
+ innerMessage: message
1204
+ };
1205
+ };
1206
+ var converter = new ThreadMessageConverter(vercelToThreadMessage);
1145
1207
  var sliceMessagesUntil = (messages, messageId) => {
1146
1208
  if (messageId == null)
1147
1209
  return [];
@@ -1155,28 +1217,36 @@ var sliceMessagesUntil = (messages, messageId) => {
1155
1217
  var hasUpcomingMessage = (isRunning, messages) => {
1156
1218
  return isRunning && messages[messages.length - 1]?.role !== "assistant";
1157
1219
  };
1158
- var useVercelAIBranches = (chat, messages) => {
1220
+ var getIsRunning = (vercel) => {
1221
+ if ("isLoading" in vercel)
1222
+ return vercel.isLoading;
1223
+ return vercel.status === "in_progress";
1224
+ };
1225
+ var useVercelAIThreadState = (vercel) => {
1159
1226
  const [data] = (0, import_react22.useState)(() => new MessageRepository());
1160
- const isRunning = "isLoading" in chat ? chat.isLoading : chat.status === "in_progress";
1227
+ const vercelRef = (0, import_react22.useRef)(vercel);
1228
+ vercelRef.current = vercel;
1229
+ const isRunning = getIsRunning(vercelRef.current);
1161
1230
  const assistantOptimisticIdRef = (0, import_react22.useRef)(null);
1162
- const messagesEx = (0, import_react22.useMemo)(() => {
1163
- for (const message of messages) {
1164
- data.addOrUpdateMessage(message);
1231
+ const messages = (0, import_react22.useMemo)(() => {
1232
+ const vm = converter.convertMessages(vercel.messages);
1233
+ for (let i = 0; i < vm.length; i++) {
1234
+ const message = vm[i];
1235
+ const parent = vm[i - 1];
1236
+ data.addOrUpdateMessage(parent?.id ?? null, message);
1165
1237
  }
1166
1238
  if (assistantOptimisticIdRef.current) {
1167
1239
  data.deleteMessage(assistantOptimisticIdRef.current);
1168
1240
  assistantOptimisticIdRef.current = null;
1169
1241
  }
1170
- if (hasUpcomingMessage(isRunning, messages)) {
1242
+ if (hasUpcomingMessage(isRunning, vm)) {
1171
1243
  assistantOptimisticIdRef.current = data.commitOptimisticRun(
1172
- messages.at(-1)?.id ?? null
1244
+ vm.at(-1)?.id ?? null
1173
1245
  );
1174
1246
  }
1175
- data.resetHead(
1176
- assistantOptimisticIdRef.current ?? messages.at(-1)?.id ?? null
1177
- );
1247
+ data.resetHead(assistantOptimisticIdRef.current ?? vm.at(-1)?.id ?? null);
1178
1248
  return data.getMessages();
1179
- }, [data, isRunning, messages]);
1249
+ }, [data, isRunning, vercel.messages]);
1180
1250
  const getBranches = (0, import_react22.useCallback)(
1181
1251
  (messageId) => {
1182
1252
  return data.getBranches(messageId);
@@ -1186,106 +1256,77 @@ var useVercelAIBranches = (chat, messages) => {
1186
1256
  const switchToBranch = (0, import_react22.useCallback)(
1187
1257
  (messageId) => {
1188
1258
  data.switchToBranch(messageId);
1189
- chat.setMessages(
1259
+ vercelRef.current.setMessages(
1190
1260
  data.getMessages().filter((m) => !isOptimisticId(m.id)).map((m) => m.innerMessage)
1191
1261
  );
1192
1262
  },
1193
- [data, chat.setMessages]
1194
- );
1195
- const reloadMaybe = "reload" in chat ? chat.reload : void 0;
1196
- const startRun = (0, import_react22.useCallback)(
1197
- async (parentId) => {
1198
- if (!reloadMaybe)
1199
- throw new Error("Reload not supported by Vercel AI SDK's useAssistant");
1200
- const newMessages = sliceMessagesUntil(chat.messages, parentId);
1201
- chat.setMessages(newMessages);
1202
- await reloadMaybe();
1203
- },
1204
- [chat.messages, chat.setMessages, reloadMaybe]
1205
- );
1206
- const append = (0, import_react22.useCallback)(
1207
- async (message) => {
1208
- if (message.content.length !== 1 || message.content[0]?.type !== "text")
1209
- throw new Error("Only text content is supported by Vercel AI SDK");
1210
- const newMessages = sliceMessagesUntil(chat.messages, message.parentId);
1211
- chat.setMessages(newMessages);
1212
- await chat.append({
1213
- role: "user",
1214
- content: message.content[0].text
1215
- });
1216
- },
1217
- [chat.messages, chat.setMessages, chat.append]
1263
+ [data]
1218
1264
  );
1265
+ const startRun = (0, import_react22.useCallback)(async (parentId) => {
1266
+ const reloadMaybe = "reload" in vercelRef.current ? vercelRef.current.reload : void 0;
1267
+ if (!reloadMaybe)
1268
+ throw new Error("Reload not supported by Vercel AI SDK's useAssistant");
1269
+ const newMessages = sliceMessagesUntil(
1270
+ vercelRef.current.messages,
1271
+ parentId
1272
+ );
1273
+ vercelRef.current.setMessages(newMessages);
1274
+ await reloadMaybe();
1275
+ }, []);
1276
+ const append = (0, import_react22.useCallback)(async (message) => {
1277
+ if (message.content.length !== 1 || message.content[0]?.type !== "text")
1278
+ throw new Error("Only text content is supported by Vercel AI SDK");
1279
+ const newMessages = sliceMessagesUntil(
1280
+ vercelRef.current.messages,
1281
+ message.parentId
1282
+ );
1283
+ vercelRef.current.setMessages(newMessages);
1284
+ await vercelRef.current.append({
1285
+ role: "user",
1286
+ content: message.content[0].text
1287
+ });
1288
+ }, []);
1289
+ const cancelRun = (0, import_react22.useCallback)(() => {
1290
+ const lastMessage = vercelRef.current.messages.at(-1);
1291
+ vercelRef.current.stop();
1292
+ if (lastMessage?.role === "user") {
1293
+ vercelRef.current.setInput(lastMessage.content);
1294
+ }
1295
+ }, []);
1219
1296
  return (0, import_react22.useMemo)(
1220
1297
  () => ({
1221
- messages: messagesEx,
1298
+ isRunning,
1299
+ messages,
1222
1300
  getBranches,
1223
1301
  switchToBranch,
1224
1302
  append,
1225
- startRun
1303
+ startRun,
1304
+ cancelRun
1226
1305
  }),
1227
- [messagesEx, getBranches, switchToBranch, append, startRun]
1306
+ [
1307
+ isRunning,
1308
+ messages,
1309
+ getBranches,
1310
+ switchToBranch,
1311
+ append,
1312
+ startRun,
1313
+ cancelRun
1314
+ ]
1228
1315
  );
1229
1316
  };
1230
1317
 
1231
1318
  // src/adapters/vercel/VercelAIAssistantProvider.tsx
1232
1319
  var import_jsx_runtime19 = require("react/jsx-runtime");
1233
- var ThreadMessageCache = /* @__PURE__ */ new WeakMap();
1234
- var vercelToThreadMessage = (message, parentId) => {
1235
- if (message.role !== "user" && message.role !== "assistant")
1236
- throw new Error("Unsupported role");
1237
- return {
1238
- parentId,
1239
- id: message.id,
1240
- role: message.role,
1241
- content: [{ type: "text", text: message.content }],
1242
- createdAt: message.createdAt ?? /* @__PURE__ */ new Date(),
1243
- innerMessage: message
1244
- };
1245
- };
1246
- var vercelToCachedThreadMessages = (messages) => {
1247
- return messages.map((m, idx) => {
1248
- const cached = ThreadMessageCache.get(m);
1249
- const parentId = messages[idx - 1]?.id ?? null;
1250
- if (cached && cached.parentId === parentId)
1251
- return cached;
1252
- const newMessage = vercelToThreadMessage(m, parentId);
1253
- ThreadMessageCache.set(m, newMessage);
1254
- return newMessage;
1255
- });
1256
- };
1257
1320
  var VercelAIAssistantProvider = ({
1258
1321
  children,
1259
1322
  ...rest
1260
1323
  }) => {
1261
1324
  const context = useDummyAIAssistantContext();
1262
1325
  const vercel = "chat" in rest ? rest.chat : rest.assistant;
1263
- const messages = (0, import_react23.useMemo)(() => {
1264
- return vercelToCachedThreadMessages(vercel.messages);
1265
- }, [vercel.messages]);
1266
- const branches = useVercelAIBranches(vercel, messages);
1267
- const cancelRun = (0, import_react23.useCallback)(() => {
1268
- const lastMessage = vercel.messages.at(-1);
1269
- vercel.stop();
1270
- if (lastMessage?.role === "user") {
1271
- vercel.setInput(lastMessage.content);
1272
- }
1273
- }, [vercel.messages, vercel.stop, vercel.setInput]);
1274
- const isRunning = "isLoading" in vercel ? vercel.isLoading : vercel.status === "in_progress";
1326
+ const threadState = useVercelAIThreadState(vercel);
1275
1327
  (0, import_react23.useMemo)(() => {
1276
- context.useThread.setState(
1277
- {
1278
- messages: branches.messages,
1279
- isRunning,
1280
- getBranches: branches.getBranches,
1281
- switchToBranch: branches.switchToBranch,
1282
- append: branches.append,
1283
- startRun: branches.startRun,
1284
- cancelRun
1285
- },
1286
- true
1287
- );
1288
- }, [context, isRunning, cancelRun, branches]);
1328
+ context.useThread.setState(threadState, true);
1329
+ }, [context, threadState]);
1289
1330
  (0, import_react23.useMemo)(() => {
1290
1331
  context.useComposer.setState({
1291
1332
  value: vercel.input,
@@ -1298,51 +1339,65 @@ var VercelAIAssistantProvider = ({
1298
1339
  // src/adapters/vercel/VercelRSCAssistantProvider.tsx
1299
1340
  var import_react24 = require("react");
1300
1341
  var import_jsx_runtime20 = require("react/jsx-runtime");
1301
- var ThreadMessageCache2 = /* @__PURE__ */ new WeakMap();
1302
- var vercelToThreadMessage2 = (parentId, message) => {
1342
+ var vercelToThreadMessage2 = (message) => {
1303
1343
  if (message.role !== "user" && message.role !== "assistant")
1304
1344
  throw new Error("Unsupported role");
1305
1345
  return {
1306
- parentId,
1307
1346
  id: message.id,
1308
1347
  role: message.role,
1309
1348
  content: [{ type: "ui", display: message.display }],
1310
1349
  createdAt: message.createdAt ?? /* @__PURE__ */ new Date()
1311
1350
  };
1312
1351
  };
1313
- var vercelToCachedThreadMessages2 = (messages) => {
1314
- return messages.map((m, idx) => {
1315
- const cached = ThreadMessageCache2.get(m);
1316
- const parentId = messages[idx - 1]?.id ?? null;
1317
- if (cached && cached.parentId === parentId)
1318
- return cached;
1319
- const newMessage = vercelToThreadMessage2(parentId, m);
1320
- ThreadMessageCache2.set(m, newMessage);
1321
- return newMessage;
1322
- });
1323
- };
1324
- var VercelRSCAssistantProvider = ({ children, messages: vercelMessages, append: vercelAppend }) => {
1352
+ var VercelRSCAssistantProvider = ({
1353
+ children,
1354
+ convertMessage,
1355
+ messages: vercelMessages,
1356
+ append: appendCallback,
1357
+ edit,
1358
+ reload
1359
+ }) => {
1325
1360
  const context = useDummyAIAssistantContext();
1361
+ const converter2 = (0, import_react24.useMemo)(() => {
1362
+ const rscConverter = convertMessage ?? ((m) => m);
1363
+ return new ThreadMessageConverter((m) => {
1364
+ return vercelToThreadMessage2(rscConverter(m));
1365
+ });
1366
+ }, [convertMessage]);
1326
1367
  const messages = (0, import_react24.useMemo)(() => {
1327
- return vercelToCachedThreadMessages2(vercelMessages);
1328
- }, [vercelMessages]);
1368
+ return converter2.convertMessages(vercelMessages);
1369
+ }, [converter2, vercelMessages]);
1329
1370
  const append = (0, import_react24.useCallback)(
1330
1371
  async (message) => {
1331
- if (message.parentId !== (context.useThread.getState().messages.at(-1)?.id ?? null))
1332
- throw new Error("Unexpected: Message editing is not supported");
1333
- if (message.content[0]?.type !== "text") {
1334
- throw new Error("Only text content is currently supported");
1372
+ if (message.parentId !== (context.useThread.getState().messages.at(-1)?.id ?? null)) {
1373
+ if (!edit)
1374
+ throw new Error(
1375
+ "Unexpected: Message editing is not supported, no edit callback was provided to VercelRSCAssistantProvider."
1376
+ );
1377
+ await edit(message);
1378
+ } else {
1379
+ await appendCallback(message);
1335
1380
  }
1336
- await vercelAppend(message);
1337
1381
  },
1338
- [context, vercelAppend]
1382
+ [context, appendCallback, edit]
1383
+ );
1384
+ const startRun = (0, import_react24.useCallback)(
1385
+ async (parentId) => {
1386
+ if (!reload)
1387
+ throw new Error(
1388
+ "Unexpected: Message reloading is not supported, no reload callback was provided to VercelRSCAssistantProvider."
1389
+ );
1390
+ await reload(parentId);
1391
+ },
1392
+ [reload]
1339
1393
  );
1340
1394
  (0, import_react24.useMemo)(() => {
1341
1395
  context.useThread.setState({
1342
1396
  messages,
1343
- append
1397
+ append,
1398
+ startRun
1344
1399
  });
1345
- }, [context, messages, append]);
1400
+ }, [context, messages, append, startRun]);
1346
1401
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(AssistantContext.Provider, { value: context, children });
1347
1402
  };
1348
1403
  // Annotate the CommonJS export names for ESM import in node: