@assistant-ui/react 0.0.10 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -58,11 +58,12 @@ __export(thread_exports, {
58
58
  });
59
59
 
60
60
  // src/primitives/thread/ThreadRoot.tsx
61
- var import_react = require("react");
62
61
  var import_react_primitive = require("@radix-ui/react-primitive");
62
+ var import_react = require("react");
63
+ var import_jsx_runtime = require("react/jsx-runtime");
63
64
  var ThreadRoot = (0, import_react.forwardRef)(
64
65
  (props, ref) => {
65
- return /* @__PURE__ */ React.createElement(import_react_primitive.Primitive.div, { ...props, ref });
66
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_primitive.Primitive.div, { ...props, ref });
66
67
  }
67
68
  );
68
69
 
@@ -99,8 +100,9 @@ var ThreadIf = ({ children, ...query }) => {
99
100
  };
100
101
 
101
102
  // src/primitives/thread/ThreadEmpty.tsx
103
+ var import_jsx_runtime2 = require("react/jsx-runtime");
102
104
  var ThreadEmpty = ({ children }) => {
103
- return /* @__PURE__ */ React.createElement(ThreadIf, { empty: true }, children);
105
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ThreadIf, { empty: true, children });
104
106
  };
105
107
 
106
108
  // src/primitives/thread/ThreadViewport.tsx
@@ -162,6 +164,7 @@ var useOnScrollToBottom = (callback) => {
162
164
  };
163
165
 
164
166
  // src/primitives/thread/ThreadViewport.tsx
167
+ var import_jsx_runtime3 = require("react/jsx-runtime");
165
168
  var ThreadViewport = (0, import_react5.forwardRef)(({ autoScroll = true, onScroll, children, ...rest }, forwardedRef) => {
166
169
  const messagesEndRef = (0, import_react5.useRef)(null);
167
170
  const divRef = (0, import_react5.useRef)(null);
@@ -198,165 +201,28 @@ var ThreadViewport = (0, import_react5.forwardRef)(({ autoScroll = true, onScrol
198
201
  }
199
202
  lastScrollTop.current = div.scrollTop;
200
203
  };
201
- return /* @__PURE__ */ React.createElement(
204
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
202
205
  import_react_primitive2.Primitive.div,
203
206
  {
204
207
  ...rest,
205
208
  onScroll: (0, import_primitive.composeEventHandlers)(onScroll, handleScroll),
206
- ref
207
- },
208
- children,
209
- /* @__PURE__ */ React.createElement("div", { ref: messagesEndRef })
210
- );
211
- });
212
-
213
- // src/adapters/vercel/useVercelAIBranches.tsx
214
- var import_react6 = require("react");
215
-
216
- // src/utils/context/stores/AssistantTypes.ts
217
- var ROOT_PARENT_ID = "__ROOT_ID__";
218
-
219
- // src/adapters/vercel/useVercelAIBranches.tsx
220
- var UPCOMING_MESSAGE_ID = "__UPCOMING_MESSAGE_ID__";
221
- var updateBranchData = (data, messages) => {
222
- for (let i = 0; i < messages.length; i++) {
223
- const child = messages[i];
224
- const childId = child.id;
225
- const parentId = messages[i - 1]?.id ?? ROOT_PARENT_ID;
226
- data.parentMap.set(childId, parentId);
227
- const parentArray = data.branchMap.get(parentId);
228
- if (!parentArray) {
229
- data.branchMap.set(parentId, [childId]);
230
- } else if (!parentArray.includes(childId)) {
231
- parentArray.push(childId);
209
+ ref,
210
+ children: [
211
+ children,
212
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ref: messagesEndRef })
213
+ ]
232
214
  }
233
- data.snapshots.set(childId, messages);
234
- }
235
- };
236
- var getParentId = (data, messages, messageId) => {
237
- if (messageId === UPCOMING_MESSAGE_ID) {
238
- const parent = messages.at(-1);
239
- if (!parent)
240
- return ROOT_PARENT_ID;
241
- return parent.id;
242
- }
243
- const parentId = data.parentMap.get(messageId);
244
- if (!parentId)
245
- throw new Error("Unexpected: Message parent not found");
246
- return parentId;
247
- };
248
- var getBranchStateImpl = (data, messages, messageId) => {
249
- const parentId = getParentId(data, messages, messageId);
250
- const branches = data.branchMap.get(parentId) ?? [];
251
- const branchId = messageId === UPCOMING_MESSAGE_ID ? branches.length : branches.indexOf(messageId);
252
- if (branchId === -1)
253
- throw new Error("Unexpected: Message not found in parent children");
254
- const upcomingOffset = messageId === UPCOMING_MESSAGE_ID ? 1 : 0;
255
- return {
256
- branchId,
257
- branchCount: branches.length + upcomingOffset
258
- };
259
- };
260
- var switchToBranchImpl = (data, messages, messageId, branchId) => {
261
- const parentId = getParentId(data, messages, messageId);
262
- const branches = data.branchMap.get(parentId);
263
- if (!branches)
264
- throw new Error("Unexpected: Parent children not found");
265
- const newMessageId = branches[branchId];
266
- if (!newMessageId)
267
- throw new Error("Unexpected: Requested branch not found");
268
- if (branchId < 0 || branchId >= branches.length)
269
- throw new Error("Switch to branch called with a branch index out of range");
270
- if (newMessageId === messageId)
271
- return messages;
272
- const snapshot = data.snapshots.get(newMessageId);
273
- if (!snapshot)
274
- throw new Error("Unexpected: Branch snapshot not found");
275
- return snapshot;
276
- };
277
- var sliceMessagesUntil = (messages, messageId) => {
278
- if (messageId === ROOT_PARENT_ID)
279
- return [];
280
- if (messageId === UPCOMING_MESSAGE_ID)
281
- return messages;
282
- const messageIdx = messages.findIndex((m) => m.id === messageId);
283
- if (messageIdx === -1)
284
- throw new Error("Unexpected: Message not found");
285
- return messages.slice(0, messageIdx + 1);
286
- };
287
- var useVercelAIBranches = (chat, context) => {
288
- const data = (0, import_react6.useRef)({
289
- parentMap: /* @__PURE__ */ new Map(),
290
- branchMap: /* @__PURE__ */ new Map(),
291
- snapshots: /* @__PURE__ */ new Map()
292
- }).current;
293
- updateBranchData(data, chat.messages);
294
- const getBranchState = (0, import_react6.useCallback)(
295
- (messageId) => {
296
- return getBranchStateImpl(data, chat.messages, messageId);
297
- },
298
- [data, chat.messages]
299
215
  );
300
- const switchToBranch = (0, import_react6.useCallback)(
301
- (messageId, branchId) => {
302
- const newMessages = switchToBranchImpl(
303
- data,
304
- chat.messages,
305
- messageId,
306
- branchId
307
- );
308
- chat.setMessages(newMessages);
309
- },
310
- [data, chat.messages, chat.setMessages]
311
- );
312
- const reloadMaybe = "reload" in chat ? chat.reload : void 0;
313
- const startRun = (0, import_react6.useCallback)(
314
- async (parentId) => {
315
- if (!reloadMaybe)
316
- throw new Error("Reload not supported by Vercel AI SDK's useAssistant");
317
- const newMessages = sliceMessagesUntil(chat.messages, parentId);
318
- chat.setMessages(newMessages);
319
- context.useViewport.getState().scrollToBottom();
320
- await reloadMaybe();
321
- },
322
- [context, chat.messages, chat.setMessages, reloadMaybe]
323
- );
324
- const append = (0, import_react6.useCallback)(
325
- async (message) => {
326
- const newMessages = sliceMessagesUntil(chat.messages, message.parentId);
327
- chat.setMessages(newMessages);
328
- if (message.content.length !== 1 || message.content[0]?.type !== "text")
329
- throw new Error("Only text content is currently supported");
330
- context.useViewport.getState().scrollToBottom();
331
- await chat.append({
332
- role: "user",
333
- content: message.content[0].text
334
- });
335
- },
336
- [context, chat.messages, chat.setMessages, chat.append]
337
- );
338
- return (0, import_react6.useMemo)(
339
- () => ({
340
- getBranchState,
341
- switchToBranch,
342
- append,
343
- startRun
344
- }),
345
- [getBranchState, switchToBranch, append, startRun]
346
- );
347
- };
348
- var hasUpcomingMessage = (thread) => {
349
- return thread.isRunning && thread.messages[thread.messages.length - 1]?.role !== "assistant";
350
- };
216
+ });
351
217
 
352
218
  // src/utils/context/useComposerContext.ts
353
- var import_react8 = require("react");
219
+ var import_react7 = require("react");
354
220
 
355
221
  // src/utils/context/useMessageContext.ts
356
- var import_react7 = require("react");
357
- var MessageContext = (0, import_react7.createContext)(null);
222
+ var import_react6 = require("react");
223
+ var MessageContext = (0, import_react6.createContext)(null);
358
224
  var useMessageContext = () => {
359
- const context = (0, import_react7.useContext)(MessageContext);
225
+ const context = (0, import_react6.useContext)(MessageContext);
360
226
  if (!context)
361
227
  throw new Error("useMessageContext must be used within a MessageProvider");
362
228
  return context;
@@ -365,7 +231,7 @@ var useMessageContext = () => {
365
231
  // src/utils/context/useComposerContext.ts
366
232
  var useComposerContext = () => {
367
233
  const { useComposer: useAssisstantComposer } = useAssistantContext();
368
- const { useComposer: useMessageComposer } = (0, import_react8.useContext)(MessageContext) ?? {};
234
+ const { useComposer: useMessageComposer } = (0, import_react7.useContext)(MessageContext) ?? {};
369
235
  return {
370
236
  useComposer: useMessageComposer ?? useAssisstantComposer,
371
237
  type: useMessageComposer ? "message" : "assistant"
@@ -398,7 +264,7 @@ __export(message_exports, {
398
264
  });
399
265
 
400
266
  // src/primitives/message/MessageProvider.tsx
401
- var import_react9 = require("react");
267
+ var import_react8 = require("react");
402
268
  var import_zustand2 = require("zustand");
403
269
 
404
270
  // src/utils/context/stores/ComposerStore.ts
@@ -414,7 +280,6 @@ var makeMessageComposerStore = ({
414
280
  onSend
415
281
  }) => (0, import_zustand.create)()((set, get, store) => ({
416
282
  ...makeBaseComposer(set, get, store),
417
- canCancel: true,
418
283
  isEditing: false,
419
284
  edit: () => {
420
285
  const value = onEdit();
@@ -423,39 +288,48 @@ var makeMessageComposerStore = ({
423
288
  send: () => {
424
289
  const value = get().value;
425
290
  set({ isEditing: false });
426
- return onSend(value);
291
+ onSend(value);
427
292
  },
428
293
  cancel: () => {
294
+ if (!get().isEditing)
295
+ return false;
429
296
  set({ isEditing: false });
297
+ return true;
430
298
  }
431
299
  }));
432
- var makeThreadComposerStore = ({
433
- onSend,
434
- onCancel
435
- }) => (0, import_zustand.create)()((set, get, store) => ({
436
- ...makeBaseComposer(set, get, store),
437
- isEditing: true,
438
- canCancel: false,
439
- send: () => {
440
- const value = get().value;
441
- set({ value: "", canCancel: true });
442
- onSend(value).then(() => {
443
- set({ canCancel: false });
444
- });
445
- },
446
- cancel: onCancel
447
- }));
300
+ var makeThreadComposerStore = (useThread) => (0, import_zustand.create)()((set, get, store) => {
301
+ return {
302
+ ...makeBaseComposer(set, get, store),
303
+ isEditing: true,
304
+ send: () => {
305
+ const { value } = get();
306
+ set({ value: "" });
307
+ useThread.getState().append({
308
+ parentId: useThread.getState().messages.at(-1)?.id ?? null,
309
+ content: [{ type: "text", text: value }]
310
+ });
311
+ },
312
+ cancel: () => {
313
+ const thread = useThread.getState();
314
+ if (!thread.isRunning)
315
+ return false;
316
+ useThread.getState().cancelRun();
317
+ return true;
318
+ }
319
+ };
320
+ });
448
321
 
449
322
  // src/primitives/message/MessageProvider.tsx
323
+ var import_jsx_runtime4 = require("react/jsx-runtime");
450
324
  var getIsLast = (thread, message) => {
451
- const hasUpcoming = hasUpcomingMessage(thread);
452
- return hasUpcoming ? message.id === UPCOMING_MESSAGE_ID : thread.messages[thread.messages.length - 1]?.id === message.id;
325
+ return thread.messages[thread.messages.length - 1]?.id === message.id;
453
326
  };
454
327
  var useMessageContext2 = () => {
455
- const [context] = (0, import_react9.useState)(() => {
456
- const { useThread } = useAssistantContext();
328
+ const { useThread } = useAssistantContext();
329
+ const [context] = (0, import_react8.useState)(() => {
457
330
  const useMessage = (0, import_zustand2.create)(() => ({
458
331
  message: null,
332
+ branches: [],
459
333
  isLast: false,
460
334
  isCopied: false,
461
335
  isHovering: false,
@@ -475,7 +349,7 @@ var useMessageContext2 = () => {
475
349
  },
476
350
  onSend: (text) => {
477
351
  const message = useMessage.getState().message;
478
- return useThread.getState().append({
352
+ useThread.getState().append({
479
353
  parentId: message.parentId,
480
354
  content: [{ type: "text", text }]
481
355
  });
@@ -492,12 +366,14 @@ var MessageProvider = ({
492
366
  const { useThread } = useAssistantContext();
493
367
  const context = useMessageContext2();
494
368
  const isLast = useThread((thread) => getIsLast(thread, message));
495
- const [isCopied, setIsCopied] = (0, import_react9.useState)(false);
496
- const [isHovering, setIsHovering] = (0, import_react9.useState)(false);
497
- (0, import_react9.useMemo)(() => {
369
+ const branches = useThread((thread) => thread.getBranches(message.id));
370
+ const [isCopied, setIsCopied] = (0, import_react8.useState)(false);
371
+ const [isHovering, setIsHovering] = (0, import_react8.useState)(false);
372
+ (0, import_react8.useMemo)(() => {
498
373
  context.useMessage.setState(
499
374
  {
500
375
  message,
376
+ branches,
501
377
  isLast,
502
378
  isCopied,
503
379
  isHovering,
@@ -506,15 +382,16 @@ var MessageProvider = ({
506
382
  },
507
383
  true
508
384
  );
509
- }, [context, message, isLast, isCopied, isHovering]);
510
- return /* @__PURE__ */ React.createElement(MessageContext.Provider, { value: context }, children);
385
+ }, [context, message, branches, isLast, isCopied, isHovering]);
386
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MessageContext.Provider, { value: context, children });
511
387
  };
512
388
 
513
389
  // src/primitives/message/MessageRoot.tsx
514
390
  var import_primitive2 = require("@radix-ui/primitive");
515
391
  var import_react_primitive3 = require("@radix-ui/react-primitive");
516
- var import_react10 = require("react");
517
- var MessageRoot = (0, import_react10.forwardRef)(
392
+ var import_react9 = require("react");
393
+ var import_jsx_runtime5 = require("react/jsx-runtime");
394
+ var MessageRoot = (0, import_react9.forwardRef)(
518
395
  ({ onMouseEnter, onMouseLeave, ...rest }, ref) => {
519
396
  const { useMessage } = useMessageContext();
520
397
  const setIsHovering = useMessage((s) => s.setIsHovering);
@@ -524,7 +401,7 @@ var MessageRoot = (0, import_react10.forwardRef)(
524
401
  const handleMouseLeave = () => {
525
402
  setIsHovering(false);
526
403
  };
527
- return /* @__PURE__ */ React.createElement(
404
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
528
405
  import_react_primitive3.Primitive.div,
529
406
  {
530
407
  ...rest,
@@ -539,8 +416,8 @@ var MessageRoot = (0, import_react10.forwardRef)(
539
416
  // src/primitives/message/MessageIf.tsx
540
417
  var useMessageIf = (props) => {
541
418
  const { useMessage } = useMessageContext();
542
- return useMessage(({ message, isLast, isCopied, isHovering }) => {
543
- if (props.hasBranches === true && message.branchCount < 2)
419
+ return useMessage(({ message, branches, isLast, isCopied, isHovering }) => {
420
+ if (props.hasBranches === true && branches.length < 2)
544
421
  return false;
545
422
  if (props.user && message.role !== "user")
546
423
  return false;
@@ -561,8 +438,9 @@ var MessageIf = ({ children, ...query }) => {
561
438
  };
562
439
 
563
440
  // src/primitives/message/MessageContent.tsx
441
+ var import_jsx_runtime6 = require("react/jsx-runtime");
564
442
  var defaultComponents = {
565
- Text: ({ part }) => /* @__PURE__ */ React.createElement(React.Fragment, null, part.text),
443
+ Text: ({ part }) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, { children: part.text }),
566
444
  Image: () => null,
567
445
  UI: ({ part }) => part.display,
568
446
  tools: {
@@ -579,26 +457,27 @@ var MessageContent = ({
579
457
  }) => {
580
458
  const { useMessage } = useMessageContext();
581
459
  const content = useMessage((s) => s.message.content);
582
- return /* @__PURE__ */ React.createElement(React.Fragment, null, content.map((part, i) => {
460
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, { children: content.map((part, i) => {
583
461
  const key = i;
584
462
  switch (part.type) {
585
463
  case "text":
586
- return /* @__PURE__ */ React.createElement(Text, { key, part });
464
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { part }, key);
587
465
  case "image":
588
- return /* @__PURE__ */ React.createElement(Image, { key, part });
466
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Image, { part }, key);
589
467
  case "ui":
590
- return /* @__PURE__ */ React.createElement(UI, { key, part });
468
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(UI, { part }, key);
591
469
  case "tool-call": {
592
470
  const Tool = by_name[part.name] || Fallback;
593
- return /* @__PURE__ */ React.createElement(Tool, { key, part });
471
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Tool, { part }, key);
594
472
  }
595
473
  default:
596
474
  return null;
597
475
  }
598
- }));
476
+ }) });
599
477
  };
600
478
 
601
479
  // src/primitives/thread/ThreadMessages.tsx
480
+ var import_jsx_runtime7 = require("react/jsx-runtime");
602
481
  var getComponents = (components) => {
603
482
  return {
604
483
  EditComposer: components.EditComposer ?? components.UserMessage ?? components.Message,
@@ -613,40 +492,32 @@ var ThreadMessages = ({ components }) => {
613
492
  const { UserMessage, EditComposer, AssistantMessage } = getComponents(components);
614
493
  if (messages.length === 0)
615
494
  return null;
616
- return /* @__PURE__ */ React.createElement(React.Fragment, null, messages.map((message, idx) => {
495
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, { children: messages.map((message, idx) => {
617
496
  return (
618
497
  // biome-ignore lint/suspicious/noArrayIndexKey: fixes a11y issues with branch navigation
619
- /* @__PURE__ */ React.createElement(MessageProvider, { key: idx, message }, /* @__PURE__ */ React.createElement(MessageIf, { user: true }, /* @__PURE__ */ React.createElement(ComposerIf, { editing: false }, /* @__PURE__ */ React.createElement(UserMessage, null)), /* @__PURE__ */ React.createElement(ComposerIf, { editing: true }, /* @__PURE__ */ React.createElement(EditComposer, null))), /* @__PURE__ */ React.createElement(MessageIf, { assistant: true }, /* @__PURE__ */ React.createElement(AssistantMessage, null)))
498
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(MessageProvider, { message, children: [
499
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(MessageIf, { user: true, children: [
500
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ComposerIf, { editing: false, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(UserMessage, {}) }),
501
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ComposerIf, { editing: true, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(EditComposer, {}) })
502
+ ] }),
503
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MessageIf, { assistant: true, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AssistantMessage, {}) })
504
+ ] }, idx)
620
505
  );
621
- }), hasUpcomingMessage(thread) && /* @__PURE__ */ React.createElement(
622
- MessageProvider,
623
- {
624
- message: {
625
- id: UPCOMING_MESSAGE_ID,
626
- role: "assistant",
627
- content: [{ type: "text", text: "..." }],
628
- parentId: messages.at(-1)?.id ?? ROOT_PARENT_ID,
629
- // TODO fix these (move upcoming message to AssistantContext)
630
- branchId: 0,
631
- branchCount: 1,
632
- createdAt: /* @__PURE__ */ new Date()
633
- }
634
- },
635
- /* @__PURE__ */ React.createElement(AssistantMessage, null)
636
- ));
506
+ }) });
637
507
  };
638
508
 
639
509
  // src/primitives/thread/ThreadScrollToBottom.tsx
640
510
  var import_primitive3 = require("@radix-ui/primitive");
641
511
  var import_react_primitive4 = require("@radix-ui/react-primitive");
642
- var import_react11 = require("react");
643
- var ThreadScrollToBottom = (0, import_react11.forwardRef)(({ onClick, ...rest }, ref) => {
512
+ var import_react10 = require("react");
513
+ var import_jsx_runtime8 = require("react/jsx-runtime");
514
+ var ThreadScrollToBottom = (0, import_react10.forwardRef)(({ onClick, ...rest }, ref) => {
644
515
  const { useViewport } = useAssistantContext();
645
516
  const isAtBottom = useViewport((s) => s.isAtBottom);
646
517
  const handleScrollToBottom = () => {
647
518
  useViewport.getState().scrollToBottom();
648
519
  };
649
- return /* @__PURE__ */ React.createElement(
520
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
650
521
  import_react_primitive4.Primitive.button,
651
522
  {
652
523
  ...rest,
@@ -671,11 +542,13 @@ __export(composer_exports, {
671
542
  var import_primitive4 = require("@radix-ui/primitive");
672
543
  var import_react_compose_refs2 = require("@radix-ui/react-compose-refs");
673
544
  var import_react_primitive5 = require("@radix-ui/react-primitive");
674
- var import_react12 = require("react");
675
- var ComposerRoot = (0, import_react12.forwardRef)(
545
+ var import_react11 = require("react");
546
+ var import_jsx_runtime9 = require("react/jsx-runtime");
547
+ var ComposerRoot = (0, import_react11.forwardRef)(
676
548
  ({ onSubmit, ...rest }, forwardedRef) => {
549
+ const { useViewport } = useAssistantContext();
677
550
  const { useComposer } = useComposerContext();
678
- const formRef = (0, import_react12.useRef)(null);
551
+ const formRef = (0, import_react11.useRef)(null);
679
552
  const ref = (0, import_react_compose_refs2.useComposedRefs)(forwardedRef, formRef);
680
553
  const handleSubmit = (e) => {
681
554
  const composerState = useComposer.getState();
@@ -683,8 +556,9 @@ var ComposerRoot = (0, import_react12.forwardRef)(
683
556
  return;
684
557
  e.preventDefault();
685
558
  composerState.send();
559
+ useViewport.getState().scrollToBottom();
686
560
  };
687
- return /* @__PURE__ */ React.createElement(
561
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
688
562
  import_react_primitive5.Primitive.form,
689
563
  {
690
564
  ...rest,
@@ -699,11 +573,12 @@ var ComposerRoot = (0, import_react12.forwardRef)(
699
573
  var import_primitive5 = require("@radix-ui/primitive");
700
574
  var import_react_compose_refs3 = require("@radix-ui/react-compose-refs");
701
575
  var import_react_slot = require("@radix-ui/react-slot");
702
- var import_react13 = require("react");
576
+ var import_react12 = require("react");
703
577
  var import_react_textarea_autosize = __toESM(require("react-textarea-autosize"));
704
- var ComposerInput = (0, import_react13.forwardRef)(
578
+ var import_jsx_runtime10 = require("react/jsx-runtime");
579
+ var ComposerInput = (0, import_react12.forwardRef)(
705
580
  ({ autoFocus, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
706
- const { useThread } = useAssistantContext();
581
+ const { useThread, useViewport } = useAssistantContext();
707
582
  const { useComposer, type } = useComposerContext();
708
583
  const value = useComposer((c) => {
709
584
  if (!c.isEditing)
@@ -715,22 +590,23 @@ var ComposerInput = (0, import_react13.forwardRef)(
715
590
  if (disabled)
716
591
  return;
717
592
  const composer = useComposer.getState();
718
- if (e.key === "Escape" && composer.canCancel) {
719
- e.preventDefault();
720
- useComposer.getState().cancel();
721
- }
722
- if (e.key === "Enter" && e.shiftKey === false) {
593
+ if (e.key === "Escape") {
594
+ if (useComposer.getState().cancel()) {
595
+ e.preventDefault();
596
+ }
597
+ } else if (e.key === "Enter" && e.shiftKey === false) {
723
598
  const isRunning = useThread.getState().isRunning;
724
599
  if (!isRunning) {
725
600
  e.preventDefault();
726
601
  composer.send();
602
+ useViewport.getState().scrollToBottom();
727
603
  }
728
604
  }
729
605
  };
730
- const textareaRef = (0, import_react13.useRef)(null);
606
+ const textareaRef = (0, import_react12.useRef)(null);
731
607
  const ref = (0, import_react_compose_refs3.useComposedRefs)(forwardedRef, textareaRef);
732
608
  const autoFocusEnabled = autoFocus !== false && !disabled;
733
- const focus = (0, import_react13.useCallback)(() => {
609
+ const focus = (0, import_react12.useCallback)(() => {
734
610
  const textarea = textareaRef.current;
735
611
  if (!textarea || !autoFocusEnabled)
736
612
  return;
@@ -740,13 +616,13 @@ var ComposerInput = (0, import_react13.forwardRef)(
740
616
  textareaRef.current.value.length
741
617
  );
742
618
  }, [autoFocusEnabled]);
743
- (0, import_react13.useEffect)(() => focus(), [focus]);
619
+ (0, import_react12.useEffect)(() => focus(), [focus]);
744
620
  useOnScrollToBottom(() => {
745
621
  if (type === "assistant") {
746
622
  focus();
747
623
  }
748
624
  });
749
- return /* @__PURE__ */ React.createElement(
625
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
750
626
  Component,
751
627
  {
752
628
  value,
@@ -767,12 +643,13 @@ var ComposerInput = (0, import_react13.forwardRef)(
767
643
 
768
644
  // src/primitives/composer/ComposerSend.tsx
769
645
  var import_react_primitive6 = require("@radix-ui/react-primitive");
770
- var import_react14 = require("react");
771
- var ComposerSend = (0, import_react14.forwardRef)(
646
+ var import_react13 = require("react");
647
+ var import_jsx_runtime11 = require("react/jsx-runtime");
648
+ var ComposerSend = (0, import_react13.forwardRef)(
772
649
  ({ disabled, ...rest }, ref) => {
773
650
  const { useComposer } = useComposerContext();
774
651
  const hasValue = useComposer((c) => c.isEditing && c.value.length > 0);
775
- return /* @__PURE__ */ React.createElement(
652
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
776
653
  import_react_primitive6.Primitive.button,
777
654
  {
778
655
  type: "submit",
@@ -787,21 +664,20 @@ var ComposerSend = (0, import_react14.forwardRef)(
787
664
  // src/primitives/composer/ComposerCancel.tsx
788
665
  var import_primitive6 = require("@radix-ui/primitive");
789
666
  var import_react_primitive7 = require("@radix-ui/react-primitive");
790
- var import_react15 = require("react");
791
- var ComposerCancel = (0, import_react15.forwardRef)(({ disabled, onClick, ...rest }, ref) => {
667
+ var import_react14 = require("react");
668
+ var import_jsx_runtime12 = require("react/jsx-runtime");
669
+ var ComposerCancel = (0, import_react14.forwardRef)(({ onClick, ...rest }, ref) => {
792
670
  const { useComposer } = useComposerContext();
793
- const hasValue = useComposer((c) => c.canCancel);
794
- const handleClose = () => {
671
+ const handleCancel = () => {
795
672
  useComposer.getState().cancel();
796
673
  };
797
- return /* @__PURE__ */ React.createElement(
674
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
798
675
  import_react_primitive7.Primitive.button,
799
676
  {
800
677
  type: "button",
801
678
  ...rest,
802
679
  ref,
803
- onClick: (0, import_primitive6.composeEventHandlers)(onClick, handleClose),
804
- disabled: disabled || !hasValue
680
+ onClick: (0, import_primitive6.composeEventHandlers)(onClick, handleCancel)
805
681
  }
806
682
  );
807
683
  });
@@ -817,10 +693,10 @@ __export(branchPicker_exports, {
817
693
  });
818
694
 
819
695
  // src/utils/context/combined/useCombinedStore.ts
820
- var import_react17 = require("react");
696
+ var import_react16 = require("react");
821
697
 
822
698
  // src/utils/context/combined/createCombinedStore.ts
823
- var import_react16 = require("react");
699
+ var import_react15 = require("react");
824
700
  var createCombinedStore = (stores) => {
825
701
  const subscribe = (callback) => {
826
702
  const unsubscribes = stores.map((store) => store.subscribe(callback));
@@ -832,41 +708,42 @@ var createCombinedStore = (stores) => {
832
708
  };
833
709
  return (selector) => {
834
710
  const getSnapshot = () => selector(...stores.map((store) => store.getState()));
835
- return (0, import_react16.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
711
+ return (0, import_react15.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
836
712
  };
837
713
  };
838
714
 
839
715
  // src/utils/context/combined/useCombinedStore.ts
840
716
  var useCombinedStore = (stores, selector) => {
841
- const useCombined = (0, import_react17.useMemo)(() => createCombinedStore(stores), stores);
717
+ const useCombined = (0, import_react16.useMemo)(() => createCombinedStore(stores), stores);
842
718
  return useCombined(selector);
843
719
  };
844
720
 
845
721
  // src/actions/useGoToNextBranch.tsx
846
722
  var useGoToNextBranch = () => {
847
723
  const { useThread } = useAssistantContext();
848
- const { useComposer, useMessage } = useMessageContext();
724
+ const { useMessage, useComposer } = useMessageContext();
849
725
  const disabled = useCombinedStore(
850
- [useThread, useComposer, useMessage],
851
- (t, c, m) => t.isRunning || c.isEditing || m.message.branchId + 1 >= m.message.branchCount
726
+ [useMessage, useComposer],
727
+ (m, c) => c.isEditing || m.branches.indexOf(m.message.id) + 1 >= m.branches.length
852
728
  );
853
729
  if (disabled)
854
730
  return null;
855
731
  return () => {
856
- const { message } = useMessage.getState();
857
- useThread.getState().switchToBranch(message.id, message.branchId + 1);
732
+ const { message, branches } = useMessage.getState();
733
+ useThread.getState().switchToBranch(branches[branches.indexOf(message.id) + 1]);
858
734
  };
859
735
  };
860
736
 
861
737
  // src/utils/createActionButton.tsx
862
- var import_react18 = require("react");
863
- var import_react_primitive8 = require("@radix-ui/react-primitive");
864
738
  var import_primitive7 = require("@radix-ui/primitive");
739
+ var import_react_primitive8 = require("@radix-ui/react-primitive");
740
+ var import_react17 = require("react");
741
+ var import_jsx_runtime13 = require("react/jsx-runtime");
865
742
  var createActionButton = (useActionButton) => {
866
- return (0, import_react18.forwardRef)(
743
+ return (0, import_react17.forwardRef)(
867
744
  (props, forwardedRef) => {
868
745
  const onClick = useActionButton(props);
869
- return /* @__PURE__ */ React.createElement(
746
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
870
747
  import_react_primitive8.Primitive.button,
871
748
  {
872
749
  type: "button",
@@ -886,16 +763,19 @@ var BranchPickerNext = createActionButton(useGoToNextBranch);
886
763
  // src/actions/useGoToPreviousBranch.tsx
887
764
  var useGoToPreviousBranch = () => {
888
765
  const { useThread } = useAssistantContext();
889
- const { useComposer, useMessage } = useMessageContext();
766
+ const { useMessage, useComposer } = useMessageContext();
890
767
  const disabled = useCombinedStore(
891
- [useThread, useComposer, useMessage],
892
- (t, c, m) => t.isRunning || c.isEditing || m.message.branchId <= 0
768
+ [useMessage, useComposer],
769
+ (m, c) => c.isEditing || m.branches.indexOf(m.message.id) <= 0
893
770
  );
894
771
  if (disabled)
895
772
  return null;
896
773
  return () => {
897
- const { message } = useMessage.getState();
898
- useThread.getState().switchToBranch(message.id, message.branchId - 1);
774
+ const { message, branches } = useMessage.getState();
775
+ useThread.getState().switchToBranch(
776
+ branches[branches.indexOf(message.id) - 1]
777
+ // TODO probably there's a more elegant way to do this
778
+ );
899
779
  };
900
780
  };
901
781
 
@@ -903,24 +783,27 @@ var useGoToPreviousBranch = () => {
903
783
  var BranchPickerPrevious = createActionButton(useGoToPreviousBranch);
904
784
 
905
785
  // src/primitives/branchPicker/BranchPickerCount.tsx
786
+ var import_jsx_runtime14 = require("react/jsx-runtime");
906
787
  var BranchPickerCount = () => {
907
788
  const { useMessage } = useMessageContext();
908
- const branchCount = useMessage((s) => s.message.branchCount);
909
- return /* @__PURE__ */ React.createElement(React.Fragment, null, branchCount);
789
+ const branchCount = useMessage((s) => s.branches.length);
790
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_jsx_runtime14.Fragment, { children: branchCount });
910
791
  };
911
792
 
912
793
  // src/primitives/branchPicker/BranchPickerNumber.tsx
794
+ var import_jsx_runtime15 = require("react/jsx-runtime");
913
795
  var BranchPickerNumber = () => {
914
796
  const { useMessage } = useMessageContext();
915
- const branchId = useMessage((s) => s.message.branchId);
916
- return /* @__PURE__ */ React.createElement(React.Fragment, null, branchId + 1);
797
+ const branchIdx = useMessage((s) => s.branches.indexOf(s.message.id));
798
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, { children: branchIdx + 1 });
917
799
  };
918
800
 
919
801
  // src/primitives/branchPicker/BranchPickerRoot.tsx
920
802
  var import_react_primitive9 = require("@radix-ui/react-primitive");
921
- var import_react19 = require("react");
922
- var BranchPickerRoot = (0, import_react19.forwardRef)(({ hideWhenSingleBranch, ...rest }, ref) => {
923
- return /* @__PURE__ */ React.createElement(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0 }, /* @__PURE__ */ React.createElement(import_react_primitive9.Primitive.div, { ...rest, ref }));
803
+ var import_react18 = require("react");
804
+ var import_jsx_runtime16 = require("react/jsx-runtime");
805
+ var BranchPickerRoot = (0, import_react18.forwardRef)(({ hideWhenSingleBranch, ...rest }, ref) => {
806
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_primitive9.Primitive.div, { ...rest, ref }) });
924
807
  });
925
808
 
926
809
  // src/primitives/actionBar/index.ts
@@ -934,8 +817,9 @@ __export(actionBar_exports, {
934
817
 
935
818
  // src/primitives/actionBar/ActionBarRoot.tsx
936
819
  var import_react_primitive10 = require("@radix-ui/react-primitive");
937
- var import_react20 = require("react");
938
- var ActionBarRoot = (0, import_react20.forwardRef)(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
820
+ var import_react19 = require("react");
821
+ var import_jsx_runtime17 = require("react/jsx-runtime");
822
+ var ActionBarRoot = (0, import_react19.forwardRef)(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
939
823
  const { useThread } = useAssistantContext();
940
824
  const { useMessage } = useMessageContext();
941
825
  const hideAndfloatStatus = useCombinedStore(
@@ -948,14 +832,14 @@ var ActionBarRoot = (0, import_react20.forwardRef)(({ hideWhenRunning, autohide,
948
832
  return "normal" /* Normal */;
949
833
  if (!m.isHovering)
950
834
  return "hidden" /* Hidden */;
951
- if (autohideFloat === "always" || autohideFloat === "single-branch" && m.message.branchCount <= 1)
835
+ if (autohideFloat === "always" || autohideFloat === "single-branch" && m.branches.length <= 1)
952
836
  return "floating" /* Floating */;
953
837
  return "normal" /* Normal */;
954
838
  }
955
839
  );
956
840
  if (hideAndfloatStatus === "hidden" /* Hidden */)
957
841
  return null;
958
- return /* @__PURE__ */ React.createElement(
842
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
959
843
  import_react_primitive10.Primitive.div,
960
844
  {
961
845
  "data-floating": hideAndfloatStatus === "floating" /* Floating */,
@@ -986,7 +870,7 @@ var ActionBarCopy = createActionButton(useCopyMessage);
986
870
 
987
871
  // src/actions/useReloadMessage.tsx
988
872
  var useReloadMessage = () => {
989
- const { useThread } = useAssistantContext();
873
+ const { useThread, useViewport } = useAssistantContext();
990
874
  const { useMessage } = useMessageContext();
991
875
  const disabled = useCombinedStore(
992
876
  [useThread, useMessage],
@@ -999,6 +883,7 @@ var useReloadMessage = () => {
999
883
  if (message.role !== "assistant")
1000
884
  throw new Error("Reloading is only supported on assistant messages");
1001
885
  useThread.getState().startRun(message.parentId);
886
+ useViewport.getState().scrollToBottom();
1002
887
  };
1003
888
  };
1004
889
 
@@ -1027,7 +912,7 @@ var ActionBarEdit = createActionButton(useBeginMessageEdit);
1027
912
  var import_react22 = require("react");
1028
913
 
1029
914
  // src/adapters/vercel/useDummyAIAssistantContext.tsx
1030
- var import_react21 = require("react");
915
+ var import_react20 = require("react");
1031
916
  var import_zustand4 = require("zustand");
1032
917
 
1033
918
  // src/utils/context/stores/ViewportStore.tsx
@@ -1051,45 +936,285 @@ var makeViewportStore = () => {
1051
936
  };
1052
937
 
1053
938
  // src/adapters/vercel/useDummyAIAssistantContext.tsx
939
+ var makeDummyThreadStore = () => {
940
+ return (0, import_zustand4.create)(() => ({
941
+ messages: [],
942
+ isRunning: false,
943
+ getBranches: () => {
944
+ return [];
945
+ },
946
+ switchToBranch: () => {
947
+ throw new Error("Not implemented");
948
+ },
949
+ append: async () => {
950
+ throw new Error("Not implemented");
951
+ },
952
+ cancelRun: () => {
953
+ throw new Error("Not implemented");
954
+ },
955
+ startRun: async () => {
956
+ throw new Error("Not implemented");
957
+ }
958
+ }));
959
+ };
1054
960
  var useDummyAIAssistantContext = () => {
1055
- const [context] = (0, import_react21.useState)(() => {
1056
- const useThread = (0, import_zustand4.create)()(() => ({
1057
- id: "",
1058
- messages: [],
1059
- isRunning: false,
1060
- append: async () => {
1061
- throw new Error("Not implemented");
1062
- },
1063
- cancelRun: () => {
1064
- throw new Error("Not implemented");
1065
- },
1066
- switchToBranch: () => {
1067
- throw new Error("Not implemented");
1068
- },
1069
- startRun: async () => {
1070
- throw new Error("Not implemented");
1071
- }
1072
- }));
961
+ const [context] = (0, import_react20.useState)(() => {
962
+ const useThread = makeDummyThreadStore();
1073
963
  const useViewport = makeViewportStore();
1074
- const useComposer = makeThreadComposerStore({
1075
- onSend: async (text) => {
1076
- await useThread.getState().append({
1077
- parentId: useThread.getState().messages.at(-1)?.id ?? ROOT_PARENT_ID,
1078
- content: [{ type: "text", text }]
1079
- });
1080
- },
1081
- onCancel: () => {
1082
- useThread.getState().cancelRun();
1083
- }
1084
- });
964
+ const useComposer = makeThreadComposerStore(useThread);
1085
965
  return { useThread, useViewport, useComposer };
1086
966
  });
1087
967
  return context;
1088
968
  };
1089
969
 
970
+ // src/adapters/vercel/useVercelAIBranches.tsx
971
+ var import_react21 = require("react");
972
+
973
+ // ../../node_modules/nanoid/non-secure/index.js
974
+ var customAlphabet = (alphabet, defaultSize = 21) => {
975
+ return (size = defaultSize) => {
976
+ let id = "";
977
+ let i = size;
978
+ while (i--) {
979
+ id += alphabet[Math.random() * alphabet.length | 0];
980
+ }
981
+ return id;
982
+ };
983
+ };
984
+
985
+ // src/adapters/MessageRepository.tsx
986
+ var generateId = customAlphabet(
987
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
988
+ 7
989
+ );
990
+ var optimisticPrefix = "__optimistic__";
991
+ var generateOptimisticId = () => `${optimisticPrefix}${generateId()}`;
992
+ var isOptimisticId = (id) => id.startsWith(optimisticPrefix);
993
+ var findHead = (message) => {
994
+ if (message.next)
995
+ return findHead(message.next);
996
+ return message;
997
+ };
998
+ var MessageRepository = class {
999
+ messages = /* @__PURE__ */ new Map();
1000
+ // message_id -> item
1001
+ head = null;
1002
+ rootChildren = [];
1003
+ getMessages() {
1004
+ const messages = new Array(this.head?.level ?? 0);
1005
+ for (let current = this.head; current; current = current.prev) {
1006
+ messages[current.level] = current.current;
1007
+ }
1008
+ return messages;
1009
+ }
1010
+ addOrUpdateMessage(message) {
1011
+ const item = this.messages.get(message.id);
1012
+ if (item) {
1013
+ if (item.current.parentId !== message.parentId) {
1014
+ this.deleteMessage(message.id);
1015
+ } else {
1016
+ item.current = message;
1017
+ return;
1018
+ }
1019
+ }
1020
+ const prev = message.parentId ? this.messages.get(message.parentId) : null;
1021
+ if (prev === void 0)
1022
+ throw new Error("Unexpected: Parent message not found");
1023
+ const newItem = {
1024
+ prev,
1025
+ current: message,
1026
+ next: null,
1027
+ children: [],
1028
+ level: prev ? prev.level + 1 : 0
1029
+ };
1030
+ this.messages.set(message.id, newItem);
1031
+ if (prev) {
1032
+ prev.children = [...prev.children, message.id];
1033
+ prev.next = newItem;
1034
+ } else {
1035
+ this.rootChildren = [...this.rootChildren, message.id];
1036
+ }
1037
+ if (this.head === prev) {
1038
+ this.head = newItem;
1039
+ }
1040
+ }
1041
+ deleteMessage(messageId) {
1042
+ const message = this.messages.get(messageId);
1043
+ if (!message)
1044
+ throw new Error("Unexpected: Message not found");
1045
+ if (message.children.length > 0) {
1046
+ for (const child of message.children) {
1047
+ this.deleteMessage(child);
1048
+ }
1049
+ }
1050
+ this.messages.delete(messageId);
1051
+ if (message.prev) {
1052
+ message.prev.children = message.prev.children.filter(
1053
+ (m) => m !== messageId
1054
+ );
1055
+ if (message.prev.next === message) {
1056
+ const childId = message.prev.children.at(-1);
1057
+ const child = childId ? this.messages.get(childId) : null;
1058
+ if (child === void 0)
1059
+ throw new Error("Unexpected: Child message not found");
1060
+ message.prev.next = child;
1061
+ }
1062
+ } else {
1063
+ this.rootChildren = this.rootChildren.filter((m) => m !== messageId);
1064
+ }
1065
+ if (this.head === message) {
1066
+ this.head = message.prev ? findHead(message.prev) : null;
1067
+ }
1068
+ }
1069
+ getOptimisticId = () => {
1070
+ let optimisticId;
1071
+ do {
1072
+ optimisticId = generateOptimisticId();
1073
+ } while (this.messages.has(optimisticId));
1074
+ return optimisticId;
1075
+ };
1076
+ commitOptimisticRun(parentId) {
1077
+ const optimisticId = this.getOptimisticId();
1078
+ this.addOrUpdateMessage({
1079
+ id: optimisticId,
1080
+ role: "assistant",
1081
+ content: [
1082
+ {
1083
+ type: "text",
1084
+ text: ""
1085
+ }
1086
+ ],
1087
+ parentId,
1088
+ createdAt: /* @__PURE__ */ new Date()
1089
+ });
1090
+ return optimisticId;
1091
+ }
1092
+ getBranches(messageId) {
1093
+ const message = this.messages.get(messageId);
1094
+ if (!message)
1095
+ throw new Error("Unexpected: Message not found");
1096
+ if (message.prev) {
1097
+ return message.prev.children;
1098
+ }
1099
+ return this.rootChildren;
1100
+ }
1101
+ switchToBranch(messageId) {
1102
+ const message = this.messages.get(messageId);
1103
+ if (!message)
1104
+ throw new Error("Unexpected: Branch not found");
1105
+ if (message.prev) {
1106
+ message.prev.next = message;
1107
+ }
1108
+ this.head = findHead(message);
1109
+ }
1110
+ resetHead(messageId) {
1111
+ if (messageId) {
1112
+ const message = this.messages.get(messageId);
1113
+ if (!message)
1114
+ throw new Error("Unexpected: Branch not found");
1115
+ this.head = message;
1116
+ for (let current = message; current; current = current.prev) {
1117
+ if (current.prev) {
1118
+ current.prev.next = current;
1119
+ }
1120
+ }
1121
+ } else {
1122
+ this.head = null;
1123
+ }
1124
+ }
1125
+ };
1126
+
1127
+ // src/adapters/vercel/useVercelAIBranches.tsx
1128
+ var sliceMessagesUntil = (messages, messageId) => {
1129
+ if (messageId == null)
1130
+ return [];
1131
+ if (isOptimisticId(messageId))
1132
+ return messages;
1133
+ const messageIdx = messages.findIndex((m) => m.id === messageId);
1134
+ if (messageIdx === -1)
1135
+ throw new Error("Unexpected: Message not found");
1136
+ return messages.slice(0, messageIdx + 1);
1137
+ };
1138
+ var hasUpcomingMessage = (isRunning, messages) => {
1139
+ return isRunning && messages[messages.length - 1]?.role !== "assistant";
1140
+ };
1141
+ var useVercelAIBranches = (chat, messages) => {
1142
+ const [data] = (0, import_react21.useState)(() => new MessageRepository());
1143
+ const isRunning = "isLoading" in chat ? chat.isLoading : chat.status === "in_progress";
1144
+ const assistantOptimisticIdRef = (0, import_react21.useRef)(null);
1145
+ const messagesEx = (0, import_react21.useMemo)(() => {
1146
+ for (const message of messages) {
1147
+ data.addOrUpdateMessage(message);
1148
+ }
1149
+ if (assistantOptimisticIdRef.current) {
1150
+ data.deleteMessage(assistantOptimisticIdRef.current);
1151
+ assistantOptimisticIdRef.current = null;
1152
+ }
1153
+ if (hasUpcomingMessage(isRunning, messages)) {
1154
+ assistantOptimisticIdRef.current = data.commitOptimisticRun(
1155
+ messages.at(-1)?.id ?? null
1156
+ );
1157
+ }
1158
+ data.resetHead(
1159
+ assistantOptimisticIdRef.current ?? messages.at(-1)?.id ?? null
1160
+ );
1161
+ return data.getMessages();
1162
+ }, [data, isRunning, messages]);
1163
+ const getBranches = (0, import_react21.useCallback)(
1164
+ (messageId) => {
1165
+ return data.getBranches(messageId);
1166
+ },
1167
+ [data]
1168
+ );
1169
+ const switchToBranch = (0, import_react21.useCallback)(
1170
+ (messageId) => {
1171
+ data.switchToBranch(messageId);
1172
+ chat.setMessages(
1173
+ data.getMessages().filter((m) => !isOptimisticId(m.id)).map((m) => m.innerMessage)
1174
+ );
1175
+ },
1176
+ [data, chat.setMessages]
1177
+ );
1178
+ const reloadMaybe = "reload" in chat ? chat.reload : void 0;
1179
+ const startRun = (0, import_react21.useCallback)(
1180
+ async (parentId) => {
1181
+ if (!reloadMaybe)
1182
+ throw new Error("Reload not supported by Vercel AI SDK's useAssistant");
1183
+ const newMessages = sliceMessagesUntil(chat.messages, parentId);
1184
+ chat.setMessages(newMessages);
1185
+ await reloadMaybe();
1186
+ },
1187
+ [chat.messages, chat.setMessages, reloadMaybe]
1188
+ );
1189
+ const append = (0, import_react21.useCallback)(
1190
+ async (message) => {
1191
+ if (message.content.length !== 1 || message.content[0]?.type !== "text")
1192
+ throw new Error("Only text content is supported by Vercel AI SDK");
1193
+ const newMessages = sliceMessagesUntil(chat.messages, message.parentId);
1194
+ chat.setMessages(newMessages);
1195
+ await chat.append({
1196
+ role: "user",
1197
+ content: message.content[0].text
1198
+ });
1199
+ },
1200
+ [chat.messages, chat.setMessages, chat.append]
1201
+ );
1202
+ return (0, import_react21.useMemo)(
1203
+ () => ({
1204
+ messages: messagesEx,
1205
+ getBranches,
1206
+ switchToBranch,
1207
+ append,
1208
+ startRun
1209
+ }),
1210
+ [messagesEx, getBranches, switchToBranch, append, startRun]
1211
+ );
1212
+ };
1213
+
1090
1214
  // src/adapters/vercel/VercelAIAssistantProvider.tsx
1215
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1091
1216
  var ThreadMessageCache = /* @__PURE__ */ new WeakMap();
1092
- var vercelToThreadMessage = (message, parentId, branchId, branchCount) => {
1217
+ var vercelToThreadMessage = (message, parentId) => {
1093
1218
  if (message.role !== "user" && message.role !== "assistant")
1094
1219
  throw new Error("Unsupported role");
1095
1220
  return {
@@ -1097,24 +1222,17 @@ var vercelToThreadMessage = (message, parentId, branchId, branchCount) => {
1097
1222
  id: message.id,
1098
1223
  role: message.role,
1099
1224
  content: [{ type: "text", text: message.content }],
1100
- branchId,
1101
- branchCount,
1102
- createdAt: message.createdAt ?? /* @__PURE__ */ new Date()
1225
+ createdAt: message.createdAt ?? /* @__PURE__ */ new Date(),
1226
+ innerMessage: message
1103
1227
  };
1104
1228
  };
1105
- var vercelToCachedThreadMessages = (messages, getBranchState) => {
1229
+ var vercelToCachedThreadMessages = (messages) => {
1106
1230
  return messages.map((m, idx) => {
1107
1231
  const cached = ThreadMessageCache.get(m);
1108
- const parentId = messages[idx - 1]?.id ?? ROOT_PARENT_ID;
1109
- const { branchId, branchCount } = getBranchState(m.id);
1110
- if (cached && cached.parentId === parentId && cached.branchId === branchId && cached.branchCount === branchCount)
1232
+ const parentId = messages[idx - 1]?.id ?? null;
1233
+ if (cached && cached.parentId === parentId)
1111
1234
  return cached;
1112
- const newMessage = vercelToThreadMessage(
1113
- m,
1114
- parentId,
1115
- branchId,
1116
- branchCount
1117
- );
1235
+ const newMessage = vercelToThreadMessage(m, parentId);
1118
1236
  ThreadMessageCache.set(m, newMessage);
1119
1237
  return newMessage;
1120
1238
  });
@@ -1125,13 +1243,10 @@ var VercelAIAssistantProvider = ({
1125
1243
  }) => {
1126
1244
  const context = useDummyAIAssistantContext();
1127
1245
  const vercel = "chat" in rest ? rest.chat : rest.assistant;
1128
- const branches = useVercelAIBranches(vercel, context);
1129
1246
  const messages = (0, import_react22.useMemo)(() => {
1130
- return vercelToCachedThreadMessages(
1131
- vercel.messages,
1132
- branches.getBranchState
1133
- );
1134
- }, [vercel.messages, branches.getBranchState]);
1247
+ return vercelToCachedThreadMessages(vercel.messages);
1248
+ }, [vercel.messages]);
1249
+ const branches = useVercelAIBranches(vercel, messages);
1135
1250
  const cancelRun = (0, import_react22.useCallback)(() => {
1136
1251
  const lastMessage = vercel.messages.at(-1);
1137
1252
  vercel.stop();
@@ -1141,27 +1256,31 @@ var VercelAIAssistantProvider = ({
1141
1256
  }, [vercel.messages, vercel.stop, vercel.setInput]);
1142
1257
  const isRunning = "isLoading" in vercel ? vercel.isLoading : vercel.status === "in_progress";
1143
1258
  (0, import_react22.useMemo)(() => {
1144
- context.useThread.setState({
1145
- messages,
1146
- isRunning,
1147
- cancelRun,
1148
- switchToBranch: branches.switchToBranch,
1149
- append: branches.append,
1150
- startRun: branches.startRun
1151
- });
1152
- }, [context, messages, isRunning, cancelRun, branches]);
1259
+ context.useThread.setState(
1260
+ {
1261
+ messages: branches.messages,
1262
+ isRunning,
1263
+ getBranches: branches.getBranches,
1264
+ switchToBranch: branches.switchToBranch,
1265
+ append: branches.append,
1266
+ startRun: branches.startRun,
1267
+ cancelRun
1268
+ },
1269
+ true
1270
+ );
1271
+ }, [context, isRunning, cancelRun, branches]);
1153
1272
  (0, import_react22.useMemo)(() => {
1154
1273
  context.useComposer.setState({
1155
- canCancel: isRunning,
1156
1274
  value: vercel.input,
1157
1275
  setValue: vercel.setInput
1158
1276
  });
1159
- }, [context, isRunning, vercel.input, vercel.setInput]);
1160
- return /* @__PURE__ */ React.createElement(AssistantContext.Provider, { value: context }, children);
1277
+ }, [context, vercel.input, vercel.setInput]);
1278
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AssistantContext.Provider, { value: context, children });
1161
1279
  };
1162
1280
 
1163
1281
  // src/adapters/vercel/VercelRSCAssistantProvider.tsx
1164
1282
  var import_react23 = require("react");
1283
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1165
1284
  var ThreadMessageCache2 = /* @__PURE__ */ new WeakMap();
1166
1285
  var vercelToThreadMessage2 = (parentId, message) => {
1167
1286
  if (message.role !== "user" && message.role !== "assistant")
@@ -1171,15 +1290,13 @@ var vercelToThreadMessage2 = (parentId, message) => {
1171
1290
  id: message.id,
1172
1291
  role: message.role,
1173
1292
  content: [{ type: "ui", display: message.display }],
1174
- createdAt: message.createdAt ?? /* @__PURE__ */ new Date(),
1175
- branchId: 0,
1176
- branchCount: 1
1293
+ createdAt: message.createdAt ?? /* @__PURE__ */ new Date()
1177
1294
  };
1178
1295
  };
1179
1296
  var vercelToCachedThreadMessages2 = (messages) => {
1180
1297
  return messages.map((m, idx) => {
1181
1298
  const cached = ThreadMessageCache2.get(m);
1182
- const parentId = messages[idx - 1]?.id ?? ROOT_PARENT_ID;
1299
+ const parentId = messages[idx - 1]?.id ?? null;
1183
1300
  if (cached && cached.parentId === parentId)
1184
1301
  return cached;
1185
1302
  const newMessage = vercelToThreadMessage2(parentId, m);
@@ -1198,12 +1315,11 @@ var VercelRSCAssistantProvider = ({
1198
1315
  }, [vercelMessages]);
1199
1316
  const append = (0, import_react23.useCallback)(
1200
1317
  async (message) => {
1201
- if (message.parentId !== (context.useThread.getState().messages.at(-1)?.id ?? ROOT_PARENT_ID))
1318
+ if (message.parentId !== (context.useThread.getState().messages.at(-1)?.id ?? null))
1202
1319
  throw new Error("Unexpected: Message editing is not supported");
1203
1320
  if (message.content[0]?.type !== "text") {
1204
1321
  throw new Error("Only text content is currently supported");
1205
1322
  }
1206
- context.useViewport.getState().scrollToBottom();
1207
1323
  await vercelAppend(message);
1208
1324
  },
1209
1325
  [context, vercelAppend]
@@ -1214,7 +1330,7 @@ var VercelRSCAssistantProvider = ({
1214
1330
  append
1215
1331
  });
1216
1332
  }, [context, messages, append]);
1217
- return /* @__PURE__ */ React.createElement(AssistantContext.Provider, { value: context }, children);
1333
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(AssistantContext.Provider, { value: context, children });
1218
1334
  };
1219
1335
  // Annotate the CommonJS export names for ESM import in node:
1220
1336
  0 && (module.exports = {