@assistant-ui/react 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.mjs CHANGED
@@ -10,137 +10,26 @@ __export(thread_exports, {
10
10
  Empty: () => ThreadEmpty,
11
11
  If: () => ThreadIf,
12
12
  Messages: () => ThreadMessages,
13
- Provider: () => ThreadProvider,
14
13
  Root: () => ThreadRoot,
15
14
  Viewport: () => ThreadViewport
16
15
  });
17
16
 
18
- // src/utils/hooks/useBranches.tsx
19
- import { useCallback, useMemo, useRef } from "react";
20
- var ROOT_ID = "__ROOT_ID__";
21
- var UPCOMING_MESSAGE_ID = "__UPCOMING_MESSAGE_ID__";
22
- var updateBranchData = (data, messages) => {
23
- for (let i = 0; i < messages.length; i++) {
24
- const child = messages[i];
25
- const childId = child.id;
26
- const parentId = messages[i - 1]?.id ?? ROOT_ID;
27
- data.parentMap.set(childId, parentId);
28
- let parentArray = data.branchMap.get(parentId);
29
- if (!parentArray) {
30
- data.branchMap.set(parentId, [childId]);
31
- } else if (!parentArray.includes(childId)) {
32
- parentArray.push(childId);
33
- }
34
- data.snapshots.set(childId, messages);
35
- }
36
- };
37
- var getParentId = (data, messages, message) => {
38
- if (message.id === UPCOMING_MESSAGE_ID) {
39
- const parent = messages.at(-1);
40
- if (!parent)
41
- return ROOT_ID;
42
- return parent.id;
17
+ // src/primitives/thread/ThreadRoot.tsx
18
+ import { forwardRef } from "react";
19
+ import {
20
+ Primitive
21
+ } from "@radix-ui/react-primitive";
22
+ var ThreadRoot = forwardRef(
23
+ (props, ref) => {
24
+ return /* @__PURE__ */ React.createElement(Primitive.div, { ...props, ref });
43
25
  }
44
- const parentId = data.parentMap.get(message.id);
45
- if (!parentId)
46
- throw new Error("Unexpected: Message parent not found");
47
- return parentId;
48
- };
49
- var getBranchStateImpl = (data, messages, message) => {
50
- const parentId = getParentId(data, messages, message);
51
- const branches = data.branchMap.get(parentId) ?? [];
52
- const branchId = message.id === UPCOMING_MESSAGE_ID ? branches.length : branches.indexOf(message.id);
53
- if (branchId === -1)
54
- throw new Error("Unexpected: Message not found in parent children");
55
- const upcomingOffset = message.id === UPCOMING_MESSAGE_ID ? 1 : 0;
56
- return {
57
- branchId,
58
- branchCount: branches.length + upcomingOffset
59
- };
60
- };
61
- var switchToBranchImpl = (data, messages, message, branchId) => {
62
- const parentId = getParentId(data, messages, message);
63
- const branches = data.branchMap.get(parentId);
64
- if (!branches)
65
- throw new Error("Unexpected: Parent children not found");
66
- const newMessageId = branches[branchId];
67
- if (!newMessageId)
68
- throw new Error("Unexpected: Requested branch not found");
69
- if (branchId < 0 || branchId >= branches.length)
70
- throw new Error("Switch to branch called with a branch index out of range");
71
- if (newMessageId === message.id)
72
- return messages;
73
- const snapshot = data.snapshots.get(newMessageId);
74
- if (!snapshot)
75
- throw new Error("Unexpected: Branch snapshot not found");
76
- return snapshot;
77
- };
78
- var sliceMessagesUntil = (messages, message) => {
79
- if (message.id === UPCOMING_MESSAGE_ID)
80
- return messages;
81
- const messageIdx = messages.findIndex((m) => m.id === message.id);
82
- if (messageIdx === -1)
83
- throw new Error("Unexpected: Message not found");
84
- return messages.slice(0, messageIdx);
85
- };
86
- var useChatWithBranches = (chat) => {
87
- const data = useRef({
88
- parentMap: /* @__PURE__ */ new Map(),
89
- branchMap: /* @__PURE__ */ new Map(),
90
- snapshots: /* @__PURE__ */ new Map()
91
- }).current;
92
- updateBranchData(data, chat.messages);
93
- const getBranchState = useCallback(
94
- (message) => {
95
- return getBranchStateImpl(data, chat.messages, message);
96
- },
97
- [chat.messages]
98
- );
99
- const switchToBranch = useCallback(
100
- (message, branchId) => {
101
- const newMessages = switchToBranchImpl(
102
- data,
103
- chat.messages,
104
- message,
105
- branchId
106
- );
107
- chat.setMessages(newMessages);
108
- },
109
- [chat.messages, chat.setMessages]
110
- );
111
- const reloadAt = useCallback(
112
- async (message) => {
113
- const newMessages = sliceMessagesUntil(chat.messages, message);
114
- chat.setMessages(newMessages);
115
- await chat.reload();
116
- },
117
- [chat.messages, chat.setMessages, chat.reload]
118
- );
119
- const editAt = useCallback(
120
- async (message, newMessage) => {
121
- const newMessages = sliceMessagesUntil(chat.messages, message);
122
- chat.setMessages(newMessages);
123
- await chat.append(newMessage);
124
- },
125
- [chat.messages, chat.setMessages, chat.append]
126
- );
127
- return useMemo(
128
- () => ({
129
- ...chat,
130
- getBranchState,
131
- switchToBranch,
132
- editAt,
133
- reloadAt
134
- }),
135
- [chat, getBranchState, switchToBranch, editAt, reloadAt]
136
- );
137
- };
26
+ );
138
27
 
139
28
  // src/utils/context/createStoreContext.tsx
140
29
  import {
141
30
  createContext,
142
31
  useContext,
143
- useMemo as useMemo2,
32
+ useMemo,
144
33
  useState
145
34
  } from "react";
146
35
  import { useSyncExternalStoreWithSelector } from "use-sync-external-store/with-selector";
@@ -179,7 +68,9 @@ var createStoreContext = (providerName) => {
179
68
  return () => listeners.delete(cb);
180
69
  },
181
70
  emit: () => {
182
- listeners.forEach((l) => l());
71
+ for (const listener of listeners) {
72
+ listener();
73
+ }
183
74
  },
184
75
  snapshot: () => {
185
76
  return state;
@@ -190,7 +81,7 @@ var createStoreContext = (providerName) => {
190
81
  }
191
82
  };
192
83
  });
193
- useMemo2(
84
+ useMemo(
194
85
  () => store.setState(unstableContext),
195
86
  Object.values(unstableContext)
196
87
  );
@@ -216,21 +107,6 @@ var createStoreContext = (providerName) => {
216
107
  // src/utils/context/ThreadContext.ts
217
108
  var [ThreadContextProvider, useThreadContext] = createStoreContext("Thread.Provider");
218
109
 
219
- // src/primitives/thread/ThreadProvider.tsx
220
- var ThreadProvider = ({ chat, children }) => {
221
- const branches = useChatWithBranches(chat);
222
- return /* @__PURE__ */ React.createElement(ThreadContextProvider, { chat: branches }, children);
223
- };
224
-
225
- // src/primitives/thread/ThreadRoot.tsx
226
- import { forwardRef } from "react";
227
- import { Primitive } from "@radix-ui/react-primitive";
228
- var ThreadRoot = forwardRef(
229
- (props, ref) => {
230
- return /* @__PURE__ */ React.createElement(Primitive.div, { ...props, ref });
231
- }
232
- );
233
-
234
110
  // src/primitives/thread/ThreadIf.tsx
235
111
  var useThreadIf = (props) => {
236
112
  return useThreadContext("Thread.If", (s) => {
@@ -257,15 +133,17 @@ var ThreadEmpty = ({ children }) => {
257
133
  };
258
134
 
259
135
  // src/primitives/thread/ThreadViewport.tsx
260
- import { forwardRef as forwardRef2, useRef as useRef3, useState as useState2 } from "react";
261
- import { Primitive as Primitive2 } from "@radix-ui/react-primitive";
136
+ import { forwardRef as forwardRef2, useRef as useRef2, useState as useState2 } from "react";
137
+ import {
138
+ Primitive as Primitive2
139
+ } from "@radix-ui/react-primitive";
262
140
  import { useComposedRefs } from "@radix-ui/react-compose-refs";
263
141
  import { composeEventHandlers } from "@radix-ui/primitive";
264
142
 
265
143
  // src/utils/hooks/useOnResizeContent.tsx
266
- import { useLayoutEffect, useRef as useRef2 } from "react";
144
+ import { useLayoutEffect, useRef } from "react";
267
145
  var useOnResizeContent = (ref, callback) => {
268
- const callbackRef = useRef2(callback);
146
+ const callbackRef = useRef(callback);
269
147
  callbackRef.current = callback;
270
148
  useLayoutEffect(() => {
271
149
  const el = ref.current;
@@ -273,33 +151,39 @@ var useOnResizeContent = (ref, callback) => {
273
151
  return;
274
152
  const resizeObserver = new ResizeObserver(() => {
275
153
  callbackRef.current();
154
+ console.log("resize observed");
276
155
  });
277
156
  const mutationObserver = new MutationObserver((mutations) => {
278
- mutations.forEach((mutation) => {
279
- mutation.addedNodes.forEach((node) => {
280
- if (node instanceof HTMLElement) {
157
+ for (const mutation of mutations) {
158
+ for (const node of mutation.addedNodes) {
159
+ if (node instanceof Element) {
281
160
  resizeObserver.observe(node);
282
161
  }
283
- });
284
- mutation.removedNodes.forEach((node) => {
285
- if (node instanceof HTMLElement) {
162
+ }
163
+ for (const node of mutation.removedNodes) {
164
+ if (node instanceof Element) {
286
165
  resizeObserver.unobserve(node);
287
166
  }
288
- });
289
- });
167
+ }
168
+ }
290
169
  callbackRef.current();
291
170
  });
292
171
  mutationObserver.observe(el, { childList: true });
172
+ for (const child of el.children) {
173
+ resizeObserver.observe(child);
174
+ console.log("observing child", child);
175
+ }
293
176
  return () => {
177
+ console.log("disconnecting");
294
178
  resizeObserver.disconnect();
295
179
  mutationObserver.disconnect();
296
180
  };
297
- }, []);
181
+ }, [ref.current]);
298
182
  };
299
183
 
300
184
  // src/primitives/thread/ThreadViewport.tsx
301
185
  var ThreadViewport = forwardRef2(({ onScroll, children, ...rest }, forwardedRef) => {
302
- const divRef = useRef3(null);
186
+ const divRef = useRef2(null);
303
187
  const ref = useComposedRefs(forwardedRef, divRef);
304
188
  const [isAtBottom, setIsAtBottom] = useState2(true);
305
189
  useOnResizeContent(divRef, () => {
@@ -312,8 +196,9 @@ var ThreadViewport = forwardRef2(({ onScroll, children, ...rest }, forwardedRef)
312
196
  const div = divRef.current;
313
197
  if (!div)
314
198
  return;
315
- setIsAtBottom(div.scrollHeight - div.scrollTop <= div.clientHeight);
199
+ setIsAtBottom(div.scrollHeight - div.scrollTop <= div.clientHeight + 50);
316
200
  };
201
+ console.log(isAtBottom);
317
202
  return /* @__PURE__ */ React.createElement(
318
203
  Primitive2.div,
319
204
  {
@@ -325,6 +210,127 @@ var ThreadViewport = forwardRef2(({ onScroll, children, ...rest }, forwardedRef)
325
210
  );
326
211
  });
327
212
 
213
+ // src/utils/hooks/useBranches.tsx
214
+ import { useCallback, useMemo as useMemo2, useRef as useRef3 } from "react";
215
+ var ROOT_ID = "__ROOT_ID__";
216
+ var UPCOMING_MESSAGE_ID = "__UPCOMING_MESSAGE_ID__";
217
+ var updateBranchData = (data, messages) => {
218
+ for (let i = 0; i < messages.length; i++) {
219
+ const child = messages[i];
220
+ const childId = child.id;
221
+ const parentId = messages[i - 1]?.id ?? ROOT_ID;
222
+ data.parentMap.set(childId, parentId);
223
+ const parentArray = data.branchMap.get(parentId);
224
+ if (!parentArray) {
225
+ data.branchMap.set(parentId, [childId]);
226
+ } else if (!parentArray.includes(childId)) {
227
+ parentArray.push(childId);
228
+ }
229
+ data.snapshots.set(childId, messages);
230
+ }
231
+ };
232
+ var getParentId = (data, messages, message) => {
233
+ if (message.id === UPCOMING_MESSAGE_ID) {
234
+ const parent = messages.at(-1);
235
+ if (!parent)
236
+ return ROOT_ID;
237
+ return parent.id;
238
+ }
239
+ const parentId = data.parentMap.get(message.id);
240
+ if (!parentId)
241
+ throw new Error("Unexpected: Message parent not found");
242
+ return parentId;
243
+ };
244
+ var getBranchStateImpl = (data, messages, message) => {
245
+ const parentId = getParentId(data, messages, message);
246
+ const branches = data.branchMap.get(parentId) ?? [];
247
+ const branchId = message.id === UPCOMING_MESSAGE_ID ? branches.length : branches.indexOf(message.id);
248
+ if (branchId === -1)
249
+ throw new Error("Unexpected: Message not found in parent children");
250
+ const upcomingOffset = message.id === UPCOMING_MESSAGE_ID ? 1 : 0;
251
+ return {
252
+ branchId,
253
+ branchCount: branches.length + upcomingOffset
254
+ };
255
+ };
256
+ var switchToBranchImpl = (data, messages, message, branchId) => {
257
+ const parentId = getParentId(data, messages, message);
258
+ const branches = data.branchMap.get(parentId);
259
+ if (!branches)
260
+ throw new Error("Unexpected: Parent children not found");
261
+ const newMessageId = branches[branchId];
262
+ if (!newMessageId)
263
+ throw new Error("Unexpected: Requested branch not found");
264
+ if (branchId < 0 || branchId >= branches.length)
265
+ throw new Error("Switch to branch called with a branch index out of range");
266
+ if (newMessageId === message.id)
267
+ return messages;
268
+ const snapshot = data.snapshots.get(newMessageId);
269
+ if (!snapshot)
270
+ throw new Error("Unexpected: Branch snapshot not found");
271
+ return snapshot;
272
+ };
273
+ var sliceMessagesUntil = (messages, message) => {
274
+ if (message.id === UPCOMING_MESSAGE_ID)
275
+ return messages;
276
+ const messageIdx = messages.findIndex((m) => m.id === message.id);
277
+ if (messageIdx === -1)
278
+ throw new Error("Unexpected: Message not found");
279
+ return messages.slice(0, messageIdx);
280
+ };
281
+ var useChatWithBranches = (chat) => {
282
+ const data = useRef3({
283
+ parentMap: /* @__PURE__ */ new Map(),
284
+ branchMap: /* @__PURE__ */ new Map(),
285
+ snapshots: /* @__PURE__ */ new Map()
286
+ }).current;
287
+ updateBranchData(data, chat.messages);
288
+ const getBranchState = useCallback(
289
+ (message) => {
290
+ return getBranchStateImpl(data, chat.messages, message);
291
+ },
292
+ [data, chat.messages]
293
+ );
294
+ const switchToBranch = useCallback(
295
+ (message, branchId) => {
296
+ const newMessages = switchToBranchImpl(
297
+ data,
298
+ chat.messages,
299
+ message,
300
+ branchId
301
+ );
302
+ chat.setMessages(newMessages);
303
+ },
304
+ [data, chat.messages, chat.setMessages]
305
+ );
306
+ const reloadAt = useCallback(
307
+ async (message) => {
308
+ const newMessages = sliceMessagesUntil(chat.messages, message);
309
+ chat.setMessages(newMessages);
310
+ await chat.reload();
311
+ },
312
+ [chat.messages, chat.setMessages, chat.reload]
313
+ );
314
+ const editAt = useCallback(
315
+ async (message, newMessage) => {
316
+ const newMessages = sliceMessagesUntil(chat.messages, message);
317
+ chat.setMessages(newMessages);
318
+ await chat.append(newMessage);
319
+ },
320
+ [chat.messages, chat.setMessages, chat.append]
321
+ );
322
+ return useMemo2(
323
+ () => ({
324
+ ...chat,
325
+ getBranchState,
326
+ switchToBranch,
327
+ editAt,
328
+ reloadAt
329
+ }),
330
+ [chat, getBranchState, switchToBranch, editAt, reloadAt]
331
+ );
332
+ };
333
+
328
334
  // src/primitives/message/index.ts
329
335
  var message_exports = {};
330
336
  __export(message_exports, {
@@ -377,7 +383,9 @@ var MessageProvider = ({
377
383
 
378
384
  // src/primitives/message/MessageRoot.tsx
379
385
  import { forwardRef as forwardRef3 } from "react";
380
- import { Primitive as Primitive3 } from "@radix-ui/react-primitive";
386
+ import {
387
+ Primitive as Primitive3
388
+ } from "@radix-ui/react-primitive";
381
389
  import { composeEventHandlers as composeEventHandlers2 } from "@radix-ui/primitive";
382
390
  var MessageRoot = forwardRef3(
383
391
  ({ onMouseEnter, onMouseLeave, ...rest }, ref) => {
@@ -445,35 +453,10 @@ var MessageContent = () => {
445
453
  };
446
454
 
447
455
  // src/primitives/message/MessageEditableContent.tsx
448
- import { useComposedRefs as useComposedRefs2 } from "@radix-ui/react-compose-refs";
449
- import { forwardRef as forwardRef4, useRef as useRef4 } from "react";
450
-
451
- // src/utils/hooks/useAutosize.tsx
452
- import { useLayoutEffect as useLayoutEffect2 } from "react";
453
- var useAutosize = (ref) => {
454
- const el = ref.current;
455
- useLayoutEffect2(() => {
456
- const el2 = ref.current;
457
- if (!el2)
458
- return;
459
- const callback = () => {
460
- el2.style.height = "0px";
461
- el2.style.height = el2.scrollHeight + "px";
462
- };
463
- el2.addEventListener("input", callback);
464
- callback();
465
- return () => {
466
- el2.removeEventListener("input", callback);
467
- };
468
- }, [ref, el]);
469
- };
470
-
471
- // src/primitives/message/MessageEditableContent.tsx
456
+ import { forwardRef as forwardRef4 } from "react";
472
457
  import { composeEventHandlers as composeEventHandlers3 } from "@radix-ui/primitive";
458
+ import TextareaAutosize from "react-textarea-autosize";
473
459
  var MessageEditableContent = forwardRef4(({ onChange, value, ...rest }, forwardedRef) => {
474
- const textareaRef = useRef4(null);
475
- const ref = useComposedRefs2(forwardedRef, textareaRef);
476
- useAutosize(textareaRef);
477
460
  const [editState, setEditState] = useMessageContext(
478
461
  "Message.EditableContent",
479
462
  (s) => [s.editState, s.setEditState]
@@ -486,10 +469,10 @@ var MessageEditableContent = forwardRef4(({ onChange, value, ...rest }, forwarde
486
469
  "Message.EditableContent may only be rendered when edit mode is enabled. Consider wrapping the component in <Message.If editing>."
487
470
  );
488
471
  return /* @__PURE__ */ React.createElement(
489
- "textarea",
472
+ TextareaAutosize,
490
473
  {
491
474
  ...rest,
492
- ref,
475
+ ref: forwardedRef,
493
476
  onChange: composeEventHandlers3(onChange, handleChange),
494
477
  value: editState.value || value
495
478
  }
@@ -497,15 +480,23 @@ var MessageEditableContent = forwardRef4(({ onChange, value, ...rest }, forwarde
497
480
  });
498
481
 
499
482
  // src/primitives/thread/ThreadMessages.tsx
500
- var ThreadMessages = ({
501
- components: { Message }
502
- }) => {
483
+ var getComponents = (components) => {
484
+ if ("Message" in components) {
485
+ return {
486
+ UserMessage: components.Message,
487
+ AssistantMessage: components.Message
488
+ };
489
+ }
490
+ return components;
491
+ };
492
+ var ThreadMessages = ({ components }) => {
503
493
  const chat = useThreadContext("Thread.Messages", (s) => s.chat);
504
494
  const messages = chat.messages;
495
+ const { UserMessage, AssistantMessage } = getComponents(components);
505
496
  if (messages.length === 0)
506
497
  return null;
507
- return /* @__PURE__ */ React.createElement(React.Fragment, null, messages.map((message, index) => {
508
- return /* @__PURE__ */ React.createElement(MessageProvider, { key: index, message }, /* @__PURE__ */ React.createElement(Message, null));
498
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, messages.map((message) => {
499
+ return /* @__PURE__ */ React.createElement(MessageProvider, { key: message.id, message }, message.role === "assistant" ? /* @__PURE__ */ React.createElement(AssistantMessage, null) : /* @__PURE__ */ React.createElement(UserMessage, null));
509
500
  }), chat.isLoading && chat.messages[chat.messages.length - 1]?.role !== "assistant" && /* @__PURE__ */ React.createElement(
510
501
  MessageProvider,
511
502
  {
@@ -515,7 +506,7 @@ var ThreadMessages = ({
515
506
  content: "..."
516
507
  }
517
508
  },
518
- /* @__PURE__ */ React.createElement(Message, null)
509
+ /* @__PURE__ */ React.createElement(AssistantMessage, null)
519
510
  ));
520
511
  };
521
512
 
@@ -529,10 +520,12 @@ __export(composer_exports, {
529
520
  });
530
521
 
531
522
  // src/primitives/composer/ComposerRoot.tsx
532
- import { createContext as createContext2, forwardRef as forwardRef5, useContext as useContext2, useMemo as useMemo4, useRef as useRef5 } from "react";
533
- import { Primitive as Primitive4 } from "@radix-ui/react-primitive";
523
+ import { createContext as createContext2, forwardRef as forwardRef5, useContext as useContext2, useMemo as useMemo4, useRef as useRef4 } from "react";
524
+ import {
525
+ Primitive as Primitive4
526
+ } from "@radix-ui/react-primitive";
534
527
  import { composeEventHandlers as composeEventHandlers4 } from "@radix-ui/primitive";
535
- import { useComposedRefs as useComposedRefs3 } from "@radix-ui/react-compose-refs";
528
+ import { useComposedRefs as useComposedRefs2 } from "@radix-ui/react-compose-refs";
536
529
  var ComposerContext = createContext2(null);
537
530
  var useComposerContext = () => {
538
531
  const context = useContext2(ComposerContext);
@@ -549,8 +542,8 @@ var ComposerRoot = forwardRef5(
549
542
  "Composer.Root",
550
543
  (s) => s.chat.handleSubmit
551
544
  );
552
- const formRef = useRef5(null);
553
- const ref = useComposedRefs3(forwardedRef, formRef);
545
+ const formRef = useRef4(null);
546
+ const ref = useComposedRefs2(forwardedRef, formRef);
554
547
  const composerContextValue = useMemo4(
555
548
  () => ({
556
549
  submit: () => formRef.current?.dispatchEvent(
@@ -571,10 +564,10 @@ var ComposerRoot = forwardRef5(
571
564
  );
572
565
 
573
566
  // src/primitives/composer/ComposerInput.tsx
574
- import { forwardRef as forwardRef6, useRef as useRef6 } from "react";
567
+ import { forwardRef as forwardRef6 } from "react";
575
568
  import { Slot } from "@radix-ui/react-slot";
576
569
  import { composeEventHandlers as composeEventHandlers5 } from "@radix-ui/primitive";
577
- import { useComposedRefs as useComposedRefs4 } from "@radix-ui/react-compose-refs";
570
+ import TextareaAutosize2 from "react-textarea-autosize";
578
571
  var ComposerInput = forwardRef6(({ asChild, onChange, onKeyDown, ...rest }, forwardedRef) => {
579
572
  const chat = useThreadContext(
580
573
  "Composer.Input",
@@ -584,15 +577,12 @@ var ComposerInput = forwardRef6(({ asChild, onChange, onKeyDown, ...rest }, forw
584
577
  isLoading
585
578
  })
586
579
  );
587
- const Component = asChild ? Slot : "textarea";
588
- const textareaRef = useRef6(null);
589
- const ref = useComposedRefs4(forwardedRef, textareaRef);
590
- useAutosize(textareaRef);
580
+ const Component = asChild ? Slot : TextareaAutosize2;
591
581
  const composer = useComposerContext();
592
582
  const handleKeyPress = (e) => {
593
583
  if (chat.isLoading || rest.disabled)
594
584
  return;
595
- if (e.key === "Enter" && e.shiftKey == false) {
585
+ if (e.key === "Enter" && e.shiftKey === false) {
596
586
  e.preventDefault();
597
587
  composer.submit();
598
588
  }
@@ -602,7 +592,7 @@ var ComposerInput = forwardRef6(({ asChild, onChange, onKeyDown, ...rest }, forw
602
592
  {
603
593
  value: chat.input,
604
594
  ...rest,
605
- ref,
595
+ ref: forwardedRef,
606
596
  onChange: composeEventHandlers5(onChange, chat.handleInputChange),
607
597
  onKeyDown: composeEventHandlers5(onKeyDown, handleKeyPress)
608
598
  }
@@ -611,7 +601,9 @@ var ComposerInput = forwardRef6(({ asChild, onChange, onKeyDown, ...rest }, forw
611
601
 
612
602
  // src/primitives/composer/ComposerSend.tsx
613
603
  import { forwardRef as forwardRef7 } from "react";
614
- import { Primitive as Primitive5 } from "@radix-ui/react-primitive";
604
+ import {
605
+ Primitive as Primitive5
606
+ } from "@radix-ui/react-primitive";
615
607
  var ComposerSend = forwardRef7(
616
608
  ({ disabled, ...rest }, ref) => {
617
609
  const input = useThreadContext("Composer.Send", (s) => s.chat.input);
@@ -629,7 +621,9 @@ var ComposerSend = forwardRef7(
629
621
 
630
622
  // src/utils/createActionButton.tsx
631
623
  import { forwardRef as forwardRef8 } from "react";
632
- import { Primitive as Primitive6 } from "@radix-ui/react-primitive";
624
+ import {
625
+ Primitive as Primitive6
626
+ } from "@radix-ui/react-primitive";
633
627
  import { composeEventHandlers as composeEventHandlers6 } from "@radix-ui/primitive";
634
628
  var createActionButton = (useActionButton) => {
635
629
  return forwardRef8(
@@ -671,8 +665,8 @@ __export(branchPicker_exports, {
671
665
  Root: () => BranchPickerRoot
672
666
  });
673
667
 
674
- // src/primitives/branchPicker/BranchPickerNext.tsx
675
- var useBranchPickerNext = () => {
668
+ // src/actions/useGoToNextBranch.tsx
669
+ var useGoToNextBranch = () => {
676
670
  const switchToBranch = useThreadContext(
677
671
  "BranchPicker.Next",
678
672
  (s) => s.chat.switchToBranch
@@ -687,10 +681,12 @@ var useBranchPickerNext = () => {
687
681
  switchToBranch(message, branchId + 1);
688
682
  };
689
683
  };
690
- var BranchPickerNext = createActionButton(useBranchPickerNext);
691
684
 
692
- // src/primitives/branchPicker/BranchPickerPrevious.tsx
693
- var useBranchPickerPrevious = () => {
685
+ // src/primitives/branchPicker/BranchPickerNext.tsx
686
+ var BranchPickerNext = createActionButton(useGoToNextBranch);
687
+
688
+ // src/actions/useGoToPreviousBranch.tsx
689
+ var useGoToPreviousBranch = () => {
694
690
  const switchToBranch = useThreadContext(
695
691
  "BranchPicker.Previous",
696
692
  (s) => s.chat.switchToBranch
@@ -705,7 +701,9 @@ var useBranchPickerPrevious = () => {
705
701
  switchToBranch(message, branchId - 1);
706
702
  };
707
703
  };
708
- var BranchPickerPrevious = createActionButton(useBranchPickerPrevious);
704
+
705
+ // src/primitives/branchPicker/BranchPickerPrevious.tsx
706
+ var BranchPickerPrevious = createActionButton(useGoToPreviousBranch);
709
707
 
710
708
  // src/primitives/branchPicker/BranchPickerCount.tsx
711
709
  var BranchPickerCount = () => {
@@ -726,10 +724,12 @@ var BranchPickerNumber = () => {
726
724
  };
727
725
 
728
726
  // src/primitives/branchPicker/BranchPickerRoot.tsx
727
+ import {
728
+ Primitive as Primitive7
729
+ } from "@radix-ui/react-primitive";
729
730
  import { forwardRef as forwardRef9 } from "react";
730
- import { Primitive as Primitive7 } from "@radix-ui/react-primitive";
731
- var BranchPickerRoot = forwardRef9(({ ...rest }, ref) => {
732
- return /* @__PURE__ */ React.createElement(Primitive7.div, { ...rest, ref });
731
+ var BranchPickerRoot = forwardRef9(({ hideWhenSingleBranch, ...rest }, ref) => {
732
+ return /* @__PURE__ */ React.createElement(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0 }, /* @__PURE__ */ React.createElement(Primitive7.div, { ...rest, ref }));
733
733
  });
734
734
 
735
735
  // src/primitives/actionBar/index.ts
@@ -742,16 +742,16 @@ __export(actionBar_exports, {
742
742
  });
743
743
 
744
744
  // src/primitives/actionBar/ActionBarRoot.tsx
745
+ import {
746
+ Primitive as Primitive8
747
+ } from "@radix-ui/react-primitive";
745
748
  import { forwardRef as forwardRef10 } from "react";
746
- import { Primitive as Primitive8 } from "@radix-ui/react-primitive";
747
- var ActionBarRoot = forwardRef10(
748
- ({ ...rest }, ref) => {
749
- return /* @__PURE__ */ React.createElement(Primitive8.div, { ...rest, ref });
750
- }
751
- );
749
+ var ActionBarRoot = forwardRef10(({ hideWhenEditing = false, ...rest }, ref) => {
750
+ return /* @__PURE__ */ React.createElement(MessageIf, { editing: hideWhenEditing ? false : void 0 }, /* @__PURE__ */ React.createElement(Primitive8.div, { ...rest, ref }));
751
+ });
752
752
 
753
- // src/primitives/actionBar/ActionBarCopy.tsx
754
- var useActionBarCopy = ({ copiedDuration = 3e3 }) => {
753
+ // src/actions/useCopyMessage.tsx
754
+ var useCopyMessage = ({ copiedDuration = 3e3 }) => {
755
755
  const [messageContent, setIsCopied] = useMessageContext(
756
756
  "ActionBar.Copy",
757
757
  (s) => [s.message.content, s.setIsCopied]
@@ -762,20 +762,27 @@ var useActionBarCopy = ({ copiedDuration = 3e3 }) => {
762
762
  setTimeout(() => setIsCopied(false), copiedDuration);
763
763
  };
764
764
  };
765
- var ActionBarCopy = createActionButton(useActionBarCopy);
766
765
 
767
- // src/primitives/actionBar/ActionBarReload.tsx
768
- var useActionBarReload = () => {
769
- const chat = useThreadContext("ActionBar.Reload", (s) => s.chat);
766
+ // src/primitives/actionBar/ActionBarCopy.tsx
767
+ var ActionBarCopy = createActionButton(useCopyMessage);
768
+
769
+ // src/actions/useReloadMessage.tsx
770
+ var useReloadMessage = () => {
771
+ const [isLoading, reloadAt] = useThreadContext("ActionBar.Reload", (s) => [
772
+ s.chat.isLoading,
773
+ s.chat.reloadAt
774
+ ]);
770
775
  const message = useMessageContext("ActionBar.Reload", (s) => s.message);
771
- if (message.role !== "assistant" || chat.isLoading)
776
+ if (message.role !== "assistant" || isLoading)
772
777
  return null;
773
- return () => chat.reloadAt(message);
778
+ return () => reloadAt(message);
774
779
  };
775
- var ActionBarReload = createActionButton(useActionBarReload);
776
780
 
777
- // src/primitives/actionBar/ActionBarEdit.tsx
778
- var useActionBarEdit = () => {
781
+ // src/primitives/actionBar/ActionBarReload.tsx
782
+ var ActionBarReload = createActionButton(useReloadMessage);
783
+
784
+ // src/actions/useBeginMessageEdit.tsx
785
+ var useBeginMessageEdit = () => {
779
786
  const [editState, messageContent, setEditState] = useMessageContext(
780
787
  "ActionBar.Edit",
781
788
  (s) => [s.editState, s.message.content, s.setEditState]
@@ -786,7 +793,9 @@ var useActionBarEdit = () => {
786
793
  setEditState({ isEditing: true, value: messageContent });
787
794
  };
788
795
  };
789
- var ActionBarEdit = createActionButton(useActionBarEdit);
796
+
797
+ // src/primitives/actionBar/ActionBarEdit.tsx
798
+ var ActionBarEdit = createActionButton(useBeginMessageEdit);
790
799
 
791
800
  // src/primitives/editBar/index.ts
792
801
  var editBar_exports = {};
@@ -797,16 +806,18 @@ __export(editBar_exports, {
797
806
  });
798
807
 
799
808
  // src/primitives/editBar/EditBarRoot.tsx
809
+ import {
810
+ Primitive as Primitive9
811
+ } from "@radix-ui/react-primitive";
800
812
  import { forwardRef as forwardRef11 } from "react";
801
- import { Primitive as Primitive9 } from "@radix-ui/react-primitive";
802
813
  var EditBarRoot = forwardRef11(
803
- ({ ...rest }, ref) => {
804
- return /* @__PURE__ */ React.createElement(Primitive9.div, { ...rest, ref });
814
+ ({ hideWhenNotEditing, ...rest }, ref) => {
815
+ return /* @__PURE__ */ React.createElement(MessageIf, { editing: hideWhenNotEditing ? true : void 0 }, /* @__PURE__ */ React.createElement(Primitive9.div, { ...rest, ref }));
805
816
  }
806
817
  );
807
818
 
808
- // src/primitives/editBar/EditBarSave.tsx
809
- var useEditBarSave = () => {
819
+ // src/actions/useSaveMessageEdit.tsx
820
+ var useSaveMessageEdit = () => {
810
821
  const chat = useThreadContext("EditBar.Save", (s) => s.chat);
811
822
  const [editState, message, setEditState] = useMessageContext(
812
823
  "EditBar.Save",
@@ -826,10 +837,12 @@ var useEditBarSave = () => {
826
837
  setEditState({ isEditing: false });
827
838
  };
828
839
  };
829
- var EditBarSave = createActionButton(useEditBarSave);
830
840
 
831
- // src/primitives/editBar/EditBarCancel.tsx
832
- var useEditBarCancel = () => {
841
+ // src/primitives/editBar/EditBarSave.tsx
842
+ var EditBarSave = createActionButton(useSaveMessageEdit);
843
+
844
+ // src/actions/useCancelMessageEdit.tsx
845
+ var useCancelMessageEdit = () => {
833
846
  const [isEditing, setEditState] = useMessageContext("EditBar.Cancel", (s) => [
834
847
  s.editState.isEditing,
835
848
  s.setEditState
@@ -840,13 +853,32 @@ var useEditBarCancel = () => {
840
853
  setEditState({ isEditing: false });
841
854
  };
842
855
  };
843
- var EditBarCancel = createActionButton(useEditBarCancel);
856
+
857
+ // src/primitives/editBar/EditBarCancel.tsx
858
+ var EditBarCancel = createActionButton(useCancelMessageEdit);
859
+
860
+ // src/vercel/VercelAIThreadProvider.tsx
861
+ var VercelAIThreadProvider = ({
862
+ chat,
863
+ children
864
+ }) => {
865
+ const branches = useChatWithBranches(chat);
866
+ return /* @__PURE__ */ React.createElement(ThreadContextProvider, { chat: branches }, children);
867
+ };
844
868
  export {
845
- actionBar_exports as ActionBar,
846
- branchPicker_exports as BranchPicker,
847
- composer_exports as Composer,
848
- editBar_exports as EditBar,
849
- message_exports as Message,
850
- thread_exports as Thread,
851
- useMessageContext as unstable_useMessageContext
869
+ actionBar_exports as ActionBarPrimitive,
870
+ branchPicker_exports as BranchPickerPrimitive,
871
+ composer_exports as ComposerPrimitive,
872
+ editBar_exports as EditBarPrimitive,
873
+ message_exports as MessagePrimitive,
874
+ thread_exports as ThreadPrimitive,
875
+ VercelAIThreadProvider,
876
+ useMessageContext as unstable_useMessageContext,
877
+ useBeginMessageEdit,
878
+ useCancelMessageEdit,
879
+ useCopyMessage,
880
+ useGoToNextBranch,
881
+ useGoToPreviousBranch,
882
+ useReloadMessage,
883
+ useSaveMessageEdit
852
884
  };