@assistant-ui/react 0.0.1 → 0.0.3

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
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,18 +17,34 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
21
31
  var src_exports = {};
22
32
  __export(src_exports, {
23
- ActionBar: () => actionBar_exports,
24
- BranchPicker: () => branchPicker_exports,
25
- Composer: () => composer_exports,
26
- EditBar: () => editBar_exports,
27
- Message: () => message_exports,
28
- Thread: () => thread_exports,
29
- unstable_useMessageContext: () => useMessageContext
33
+ ActionBarPrimitive: () => actionBar_exports,
34
+ BranchPickerPrimitive: () => branchPicker_exports,
35
+ ComposerPrimitive: () => composer_exports,
36
+ EditBarPrimitive: () => editBar_exports,
37
+ MessagePrimitive: () => message_exports,
38
+ ThreadPrimitive: () => thread_exports,
39
+ VercelAIThreadProvider: () => VercelAIThreadProvider,
40
+ unstable_useMessageContext: () => useMessageContext,
41
+ useBeginMessageEdit: () => useBeginMessageEdit,
42
+ useCancelMessageEdit: () => useCancelMessageEdit,
43
+ useCopyMessage: () => useCopyMessage,
44
+ useGoToNextBranch: () => useGoToNextBranch,
45
+ useGoToPreviousBranch: () => useGoToPreviousBranch,
46
+ useReloadMessage: () => useReloadMessage,
47
+ useSaveMessageEdit: () => useSaveMessageEdit
30
48
  });
31
49
  module.exports = __toCommonJS(src_exports);
32
50
 
@@ -36,131 +54,18 @@ __export(thread_exports, {
36
54
  Empty: () => ThreadEmpty,
37
55
  If: () => ThreadIf,
38
56
  Messages: () => ThreadMessages,
39
- Provider: () => ThreadProvider,
40
57
  Root: () => ThreadRoot,
41
58
  Viewport: () => ThreadViewport
42
59
  });
43
60
 
44
- // src/utils/hooks/useBranches.tsx
61
+ // src/primitives/thread/ThreadRoot.tsx
45
62
  var import_react = require("react");
46
- var ROOT_ID = "__ROOT_ID__";
47
- var UPCOMING_MESSAGE_ID = "__UPCOMING_MESSAGE_ID__";
48
- var updateBranchData = (data, messages) => {
49
- for (let i = 0; i < messages.length; i++) {
50
- const child = messages[i];
51
- const childId = child.id;
52
- const parentId = messages[i - 1]?.id ?? ROOT_ID;
53
- data.parentMap.set(childId, parentId);
54
- let parentArray = data.branchMap.get(parentId);
55
- if (!parentArray) {
56
- data.branchMap.set(parentId, [childId]);
57
- } else if (!parentArray.includes(childId)) {
58
- parentArray.push(childId);
59
- }
60
- data.snapshots.set(childId, messages);
61
- }
62
- };
63
- var getParentId = (data, messages, message) => {
64
- if (message.id === UPCOMING_MESSAGE_ID) {
65
- const parent = messages.at(-1);
66
- if (!parent)
67
- return ROOT_ID;
68
- return parent.id;
63
+ var import_react_primitive = require("@radix-ui/react-primitive");
64
+ var ThreadRoot = (0, import_react.forwardRef)(
65
+ (props, ref) => {
66
+ return /* @__PURE__ */ React.createElement(import_react_primitive.Primitive.div, { ...props, ref });
69
67
  }
70
- const parentId = data.parentMap.get(message.id);
71
- if (!parentId)
72
- throw new Error("Unexpected: Message parent not found");
73
- return parentId;
74
- };
75
- var getBranchStateImpl = (data, messages, message) => {
76
- const parentId = getParentId(data, messages, message);
77
- const branches = data.branchMap.get(parentId) ?? [];
78
- const branchId = message.id === UPCOMING_MESSAGE_ID ? branches.length : branches.indexOf(message.id);
79
- if (branchId === -1)
80
- throw new Error("Unexpected: Message not found in parent children");
81
- const upcomingOffset = message.id === UPCOMING_MESSAGE_ID ? 1 : 0;
82
- return {
83
- branchId,
84
- branchCount: branches.length + upcomingOffset
85
- };
86
- };
87
- var switchToBranchImpl = (data, messages, message, branchId) => {
88
- const parentId = getParentId(data, messages, message);
89
- const branches = data.branchMap.get(parentId);
90
- if (!branches)
91
- throw new Error("Unexpected: Parent children not found");
92
- const newMessageId = branches[branchId];
93
- if (!newMessageId)
94
- throw new Error("Unexpected: Requested branch not found");
95
- if (branchId < 0 || branchId >= branches.length)
96
- throw new Error("Switch to branch called with a branch index out of range");
97
- if (newMessageId === message.id)
98
- return messages;
99
- const snapshot = data.snapshots.get(newMessageId);
100
- if (!snapshot)
101
- throw new Error("Unexpected: Branch snapshot not found");
102
- return snapshot;
103
- };
104
- var sliceMessagesUntil = (messages, message) => {
105
- if (message.id === UPCOMING_MESSAGE_ID)
106
- return messages;
107
- const messageIdx = messages.findIndex((m) => m.id === message.id);
108
- if (messageIdx === -1)
109
- throw new Error("Unexpected: Message not found");
110
- return messages.slice(0, messageIdx);
111
- };
112
- var useChatWithBranches = (chat) => {
113
- const data = (0, import_react.useRef)({
114
- parentMap: /* @__PURE__ */ new Map(),
115
- branchMap: /* @__PURE__ */ new Map(),
116
- snapshots: /* @__PURE__ */ new Map()
117
- }).current;
118
- updateBranchData(data, chat.messages);
119
- const getBranchState = (0, import_react.useCallback)(
120
- (message) => {
121
- return getBranchStateImpl(data, chat.messages, message);
122
- },
123
- [chat.messages]
124
- );
125
- const switchToBranch = (0, import_react.useCallback)(
126
- (message, branchId) => {
127
- const newMessages = switchToBranchImpl(
128
- data,
129
- chat.messages,
130
- message,
131
- branchId
132
- );
133
- chat.setMessages(newMessages);
134
- },
135
- [chat.messages, chat.setMessages]
136
- );
137
- const reloadAt = (0, import_react.useCallback)(
138
- async (message) => {
139
- const newMessages = sliceMessagesUntil(chat.messages, message);
140
- chat.setMessages(newMessages);
141
- await chat.reload();
142
- },
143
- [chat.messages, chat.setMessages, chat.reload]
144
- );
145
- const editAt = (0, import_react.useCallback)(
146
- async (message, newMessage) => {
147
- const newMessages = sliceMessagesUntil(chat.messages, message);
148
- chat.setMessages(newMessages);
149
- await chat.append(newMessage);
150
- },
151
- [chat.messages, chat.setMessages, chat.append]
152
- );
153
- return (0, import_react.useMemo)(
154
- () => ({
155
- ...chat,
156
- getBranchState,
157
- switchToBranch,
158
- editAt,
159
- reloadAt
160
- }),
161
- [chat, getBranchState, switchToBranch, editAt, reloadAt]
162
- );
163
- };
68
+ );
164
69
 
165
70
  // src/utils/context/createStoreContext.tsx
166
71
  var import_react2 = require("react");
@@ -200,7 +105,9 @@ var createStoreContext = (providerName) => {
200
105
  return () => listeners.delete(cb);
201
106
  },
202
107
  emit: () => {
203
- listeners.forEach((l) => l());
108
+ for (const listener of listeners) {
109
+ listener();
110
+ }
204
111
  },
205
112
  snapshot: () => {
206
113
  return state;
@@ -237,21 +144,6 @@ var createStoreContext = (providerName) => {
237
144
  // src/utils/context/ThreadContext.ts
238
145
  var [ThreadContextProvider, useThreadContext] = createStoreContext("Thread.Provider");
239
146
 
240
- // src/primitives/thread/ThreadProvider.tsx
241
- var ThreadProvider = ({ chat, children }) => {
242
- const branches = useChatWithBranches(chat);
243
- return /* @__PURE__ */ React.createElement(ThreadContextProvider, { chat: branches }, children);
244
- };
245
-
246
- // src/primitives/thread/ThreadRoot.tsx
247
- var import_react3 = require("react");
248
- var import_react_primitive = require("@radix-ui/react-primitive");
249
- var ThreadRoot = (0, import_react3.forwardRef)(
250
- (props, ref) => {
251
- return /* @__PURE__ */ React.createElement(import_react_primitive.Primitive.div, { ...props, ref });
252
- }
253
- );
254
-
255
147
  // src/primitives/thread/ThreadIf.tsx
256
148
  var useThreadIf = (props) => {
257
149
  return useThreadContext("Thread.If", (s) => {
@@ -278,17 +170,17 @@ var ThreadEmpty = ({ children }) => {
278
170
  };
279
171
 
280
172
  // src/primitives/thread/ThreadViewport.tsx
281
- var import_react5 = require("react");
173
+ var import_react4 = require("react");
282
174
  var import_react_primitive2 = require("@radix-ui/react-primitive");
283
175
  var import_react_compose_refs = require("@radix-ui/react-compose-refs");
284
176
  var import_primitive = require("@radix-ui/primitive");
285
177
 
286
178
  // src/utils/hooks/useOnResizeContent.tsx
287
- var import_react4 = require("react");
179
+ var import_react3 = require("react");
288
180
  var useOnResizeContent = (ref, callback) => {
289
- const callbackRef = (0, import_react4.useRef)(callback);
181
+ const callbackRef = (0, import_react3.useRef)(callback);
290
182
  callbackRef.current = callback;
291
- (0, import_react4.useLayoutEffect)(() => {
183
+ (0, import_react3.useLayoutEffect)(() => {
292
184
  const el = ref.current;
293
185
  if (!el)
294
186
  return;
@@ -296,33 +188,39 @@ var useOnResizeContent = (ref, callback) => {
296
188
  callbackRef.current();
297
189
  });
298
190
  const mutationObserver = new MutationObserver((mutations) => {
299
- mutations.forEach((mutation) => {
300
- mutation.addedNodes.forEach((node) => {
301
- if (node instanceof HTMLElement) {
191
+ for (const mutation of mutations) {
192
+ for (const node of mutation.addedNodes) {
193
+ if (node instanceof Element) {
302
194
  resizeObserver.observe(node);
303
195
  }
304
- });
305
- mutation.removedNodes.forEach((node) => {
306
- if (node instanceof HTMLElement) {
196
+ }
197
+ for (const node of mutation.removedNodes) {
198
+ if (node instanceof Element) {
307
199
  resizeObserver.unobserve(node);
308
200
  }
309
- });
310
- });
201
+ }
202
+ }
311
203
  callbackRef.current();
312
204
  });
205
+ resizeObserver.observe(el);
313
206
  mutationObserver.observe(el, { childList: true });
207
+ for (const child of el.children) {
208
+ resizeObserver.observe(child);
209
+ console.log("observing child", child);
210
+ }
314
211
  return () => {
212
+ console.log("disconnecting");
315
213
  resizeObserver.disconnect();
316
214
  mutationObserver.disconnect();
317
215
  };
318
- }, []);
216
+ }, [ref.current]);
319
217
  };
320
218
 
321
219
  // src/primitives/thread/ThreadViewport.tsx
322
- var ThreadViewport = (0, import_react5.forwardRef)(({ onScroll, children, ...rest }, forwardedRef) => {
323
- const divRef = (0, import_react5.useRef)(null);
220
+ var ThreadViewport = (0, import_react4.forwardRef)(({ onScroll, children, ...rest }, forwardedRef) => {
221
+ const divRef = (0, import_react4.useRef)(null);
324
222
  const ref = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, divRef);
325
- const [isAtBottom, setIsAtBottom] = (0, import_react5.useState)(true);
223
+ const [isAtBottom, setIsAtBottom] = (0, import_react4.useState)(true);
326
224
  useOnResizeContent(divRef, () => {
327
225
  const div = divRef.current;
328
226
  if (!div || !isAtBottom)
@@ -333,8 +231,9 @@ var ThreadViewport = (0, import_react5.forwardRef)(({ onScroll, children, ...res
333
231
  const div = divRef.current;
334
232
  if (!div)
335
233
  return;
336
- setIsAtBottom(div.scrollHeight - div.scrollTop <= div.clientHeight);
234
+ setIsAtBottom(div.scrollHeight - div.scrollTop <= div.clientHeight + 50);
337
235
  };
236
+ console.log(isAtBottom);
338
237
  return /* @__PURE__ */ React.createElement(
339
238
  import_react_primitive2.Primitive.div,
340
239
  {
@@ -346,6 +245,127 @@ var ThreadViewport = (0, import_react5.forwardRef)(({ onScroll, children, ...res
346
245
  );
347
246
  });
348
247
 
248
+ // src/utils/hooks/useBranches.tsx
249
+ var import_react5 = require("react");
250
+ var ROOT_ID = "__ROOT_ID__";
251
+ var UPCOMING_MESSAGE_ID = "__UPCOMING_MESSAGE_ID__";
252
+ var updateBranchData = (data, messages) => {
253
+ for (let i = 0; i < messages.length; i++) {
254
+ const child = messages[i];
255
+ const childId = child.id;
256
+ const parentId = messages[i - 1]?.id ?? ROOT_ID;
257
+ data.parentMap.set(childId, parentId);
258
+ const parentArray = data.branchMap.get(parentId);
259
+ if (!parentArray) {
260
+ data.branchMap.set(parentId, [childId]);
261
+ } else if (!parentArray.includes(childId)) {
262
+ parentArray.push(childId);
263
+ }
264
+ data.snapshots.set(childId, messages);
265
+ }
266
+ };
267
+ var getParentId = (data, messages, message) => {
268
+ if (message.id === UPCOMING_MESSAGE_ID) {
269
+ const parent = messages.at(-1);
270
+ if (!parent)
271
+ return ROOT_ID;
272
+ return parent.id;
273
+ }
274
+ const parentId = data.parentMap.get(message.id);
275
+ if (!parentId)
276
+ throw new Error("Unexpected: Message parent not found");
277
+ return parentId;
278
+ };
279
+ var getBranchStateImpl = (data, messages, message) => {
280
+ const parentId = getParentId(data, messages, message);
281
+ const branches = data.branchMap.get(parentId) ?? [];
282
+ const branchId = message.id === UPCOMING_MESSAGE_ID ? branches.length : branches.indexOf(message.id);
283
+ if (branchId === -1)
284
+ throw new Error("Unexpected: Message not found in parent children");
285
+ const upcomingOffset = message.id === UPCOMING_MESSAGE_ID ? 1 : 0;
286
+ return {
287
+ branchId,
288
+ branchCount: branches.length + upcomingOffset
289
+ };
290
+ };
291
+ var switchToBranchImpl = (data, messages, message, branchId) => {
292
+ const parentId = getParentId(data, messages, message);
293
+ const branches = data.branchMap.get(parentId);
294
+ if (!branches)
295
+ throw new Error("Unexpected: Parent children not found");
296
+ const newMessageId = branches[branchId];
297
+ if (!newMessageId)
298
+ throw new Error("Unexpected: Requested branch not found");
299
+ if (branchId < 0 || branchId >= branches.length)
300
+ throw new Error("Switch to branch called with a branch index out of range");
301
+ if (newMessageId === message.id)
302
+ return messages;
303
+ const snapshot = data.snapshots.get(newMessageId);
304
+ if (!snapshot)
305
+ throw new Error("Unexpected: Branch snapshot not found");
306
+ return snapshot;
307
+ };
308
+ var sliceMessagesUntil = (messages, message) => {
309
+ if (message.id === UPCOMING_MESSAGE_ID)
310
+ return messages;
311
+ const messageIdx = messages.findIndex((m) => m.id === message.id);
312
+ if (messageIdx === -1)
313
+ throw new Error("Unexpected: Message not found");
314
+ return messages.slice(0, messageIdx);
315
+ };
316
+ var useChatWithBranches = (chat) => {
317
+ const data = (0, import_react5.useRef)({
318
+ parentMap: /* @__PURE__ */ new Map(),
319
+ branchMap: /* @__PURE__ */ new Map(),
320
+ snapshots: /* @__PURE__ */ new Map()
321
+ }).current;
322
+ updateBranchData(data, chat.messages);
323
+ const getBranchState = (0, import_react5.useCallback)(
324
+ (message) => {
325
+ return getBranchStateImpl(data, chat.messages, message);
326
+ },
327
+ [data, chat.messages]
328
+ );
329
+ const switchToBranch = (0, import_react5.useCallback)(
330
+ (message, branchId) => {
331
+ const newMessages = switchToBranchImpl(
332
+ data,
333
+ chat.messages,
334
+ message,
335
+ branchId
336
+ );
337
+ chat.setMessages(newMessages);
338
+ },
339
+ [data, chat.messages, chat.setMessages]
340
+ );
341
+ const reloadAt = (0, import_react5.useCallback)(
342
+ async (message) => {
343
+ const newMessages = sliceMessagesUntil(chat.messages, message);
344
+ chat.setMessages(newMessages);
345
+ await chat.reload();
346
+ },
347
+ [chat.messages, chat.setMessages, chat.reload]
348
+ );
349
+ const editAt = (0, import_react5.useCallback)(
350
+ async (message, newMessage) => {
351
+ const newMessages = sliceMessagesUntil(chat.messages, message);
352
+ chat.setMessages(newMessages);
353
+ await chat.append(newMessage);
354
+ },
355
+ [chat.messages, chat.setMessages, chat.append]
356
+ );
357
+ return (0, import_react5.useMemo)(
358
+ () => ({
359
+ ...chat,
360
+ getBranchState,
361
+ switchToBranch,
362
+ editAt,
363
+ reloadAt
364
+ }),
365
+ [chat, getBranchState, switchToBranch, editAt, reloadAt]
366
+ );
367
+ };
368
+
349
369
  // src/primitives/message/index.ts
350
370
  var message_exports = {};
351
371
  __export(message_exports, {
@@ -466,35 +486,10 @@ var MessageContent = () => {
466
486
  };
467
487
 
468
488
  // src/primitives/message/MessageEditableContent.tsx
469
- var import_react_compose_refs2 = require("@radix-ui/react-compose-refs");
470
- var import_react9 = require("react");
471
-
472
- // src/utils/hooks/useAutosize.tsx
473
489
  var import_react8 = require("react");
474
- var useAutosize = (ref) => {
475
- const el = ref.current;
476
- (0, import_react8.useLayoutEffect)(() => {
477
- const el2 = ref.current;
478
- if (!el2)
479
- return;
480
- const callback = () => {
481
- el2.style.height = "0px";
482
- el2.style.height = el2.scrollHeight + "px";
483
- };
484
- el2.addEventListener("input", callback);
485
- callback();
486
- return () => {
487
- el2.removeEventListener("input", callback);
488
- };
489
- }, [ref, el]);
490
- };
491
-
492
- // src/primitives/message/MessageEditableContent.tsx
493
490
  var import_primitive3 = require("@radix-ui/primitive");
494
- var MessageEditableContent = (0, import_react9.forwardRef)(({ onChange, value, ...rest }, forwardedRef) => {
495
- const textareaRef = (0, import_react9.useRef)(null);
496
- const ref = (0, import_react_compose_refs2.useComposedRefs)(forwardedRef, textareaRef);
497
- useAutosize(textareaRef);
491
+ var import_react_textarea_autosize = __toESM(require("react-textarea-autosize"));
492
+ var MessageEditableContent = (0, import_react8.forwardRef)(({ onChange, value, ...rest }, forwardedRef) => {
498
493
  const [editState, setEditState] = useMessageContext(
499
494
  "Message.EditableContent",
500
495
  (s) => [s.editState, s.setEditState]
@@ -507,10 +502,10 @@ var MessageEditableContent = (0, import_react9.forwardRef)(({ onChange, value, .
507
502
  "Message.EditableContent may only be rendered when edit mode is enabled. Consider wrapping the component in <Message.If editing>."
508
503
  );
509
504
  return /* @__PURE__ */ React.createElement(
510
- "textarea",
505
+ import_react_textarea_autosize.default,
511
506
  {
512
507
  ...rest,
513
- ref,
508
+ ref: forwardedRef,
514
509
  onChange: (0, import_primitive3.composeEventHandlers)(onChange, handleChange),
515
510
  value: editState.value || value
516
511
  }
@@ -518,15 +513,24 @@ var MessageEditableContent = (0, import_react9.forwardRef)(({ onChange, value, .
518
513
  });
519
514
 
520
515
  // src/primitives/thread/ThreadMessages.tsx
521
- var ThreadMessages = ({
522
- components: { Message }
523
- }) => {
516
+ var getComponents = (components) => {
517
+ return {
518
+ EditingUserMessage: components.EditingUserMessage ?? components.UserMessage ?? components.Message,
519
+ UserMessage: components.UserMessage ?? components.Message,
520
+ AssistantMessage: components.AssistantMessage ?? components.Message
521
+ };
522
+ };
523
+ var ThreadMessages = ({ components }) => {
524
524
  const chat = useThreadContext("Thread.Messages", (s) => s.chat);
525
525
  const messages = chat.messages;
526
+ const { UserMessage, EditingUserMessage, AssistantMessage } = getComponents(components);
526
527
  if (messages.length === 0)
527
528
  return null;
528
- return /* @__PURE__ */ React.createElement(React.Fragment, null, messages.map((message, index) => {
529
- return /* @__PURE__ */ React.createElement(MessageProvider, { key: index, message }, /* @__PURE__ */ React.createElement(Message, null));
529
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, messages.map((message, idx) => {
530
+ return (
531
+ // biome-ignore lint/suspicious/noArrayIndexKey: fixes a11y issues with branch navigation
532
+ /* @__PURE__ */ React.createElement(MessageProvider, { key: idx, message }, /* @__PURE__ */ React.createElement(MessageIf, { user: true, editing: false }, /* @__PURE__ */ React.createElement(UserMessage, null)), /* @__PURE__ */ React.createElement(MessageIf, { user: true, editing: true }, /* @__PURE__ */ React.createElement(EditingUserMessage, null)), /* @__PURE__ */ React.createElement(MessageIf, { assistant: true }, /* @__PURE__ */ React.createElement(AssistantMessage, null)))
533
+ );
530
534
  }), chat.isLoading && chat.messages[chat.messages.length - 1]?.role !== "assistant" && /* @__PURE__ */ React.createElement(
531
535
  MessageProvider,
532
536
  {
@@ -536,7 +540,7 @@ var ThreadMessages = ({
536
540
  content: "..."
537
541
  }
538
542
  },
539
- /* @__PURE__ */ React.createElement(Message, null)
543
+ /* @__PURE__ */ React.createElement(AssistantMessage, null)
540
544
  ));
541
545
  };
542
546
 
@@ -550,13 +554,13 @@ __export(composer_exports, {
550
554
  });
551
555
 
552
556
  // src/primitives/composer/ComposerRoot.tsx
553
- var import_react10 = require("react");
557
+ var import_react9 = require("react");
554
558
  var import_react_primitive4 = require("@radix-ui/react-primitive");
555
559
  var import_primitive4 = require("@radix-ui/primitive");
556
- var import_react_compose_refs3 = require("@radix-ui/react-compose-refs");
557
- var ComposerContext = (0, import_react10.createContext)(null);
560
+ var import_react_compose_refs2 = require("@radix-ui/react-compose-refs");
561
+ var ComposerContext = (0, import_react9.createContext)(null);
558
562
  var useComposerContext = () => {
559
- const context = (0, import_react10.useContext)(ComposerContext);
563
+ const context = (0, import_react9.useContext)(ComposerContext);
560
564
  if (!context) {
561
565
  throw new Error(
562
566
  "Composer compound components cannot be rendered outside the Composer component"
@@ -564,15 +568,15 @@ var useComposerContext = () => {
564
568
  }
565
569
  return context;
566
570
  };
567
- var ComposerRoot = (0, import_react10.forwardRef)(
571
+ var ComposerRoot = (0, import_react9.forwardRef)(
568
572
  ({ onSubmit, ...rest }, forwardedRef) => {
569
573
  const handleSubmit = useThreadContext(
570
574
  "Composer.Root",
571
575
  (s) => s.chat.handleSubmit
572
576
  );
573
- const formRef = (0, import_react10.useRef)(null);
574
- const ref = (0, import_react_compose_refs3.useComposedRefs)(forwardedRef, formRef);
575
- const composerContextValue = (0, import_react10.useMemo)(
577
+ const formRef = (0, import_react9.useRef)(null);
578
+ const ref = (0, import_react_compose_refs2.useComposedRefs)(forwardedRef, formRef);
579
+ const composerContextValue = (0, import_react9.useMemo)(
576
580
  () => ({
577
581
  submit: () => formRef.current?.dispatchEvent(
578
582
  new Event("submit", { cancelable: true, bubbles: true })
@@ -592,11 +596,11 @@ var ComposerRoot = (0, import_react10.forwardRef)(
592
596
  );
593
597
 
594
598
  // src/primitives/composer/ComposerInput.tsx
595
- var import_react11 = require("react");
599
+ var import_react10 = require("react");
596
600
  var import_react_slot = require("@radix-ui/react-slot");
597
601
  var import_primitive5 = require("@radix-ui/primitive");
598
- var import_react_compose_refs4 = require("@radix-ui/react-compose-refs");
599
- var ComposerInput = (0, import_react11.forwardRef)(({ asChild, onChange, onKeyDown, ...rest }, forwardedRef) => {
602
+ var import_react_textarea_autosize2 = __toESM(require("react-textarea-autosize"));
603
+ var ComposerInput = (0, import_react10.forwardRef)(({ asChild, onChange, onKeyDown, ...rest }, forwardedRef) => {
600
604
  const chat = useThreadContext(
601
605
  "Composer.Input",
602
606
  ({ chat: { input, handleInputChange, isLoading } }) => ({
@@ -605,15 +609,12 @@ var ComposerInput = (0, import_react11.forwardRef)(({ asChild, onChange, onKeyDo
605
609
  isLoading
606
610
  })
607
611
  );
608
- const Component = asChild ? import_react_slot.Slot : "textarea";
609
- const textareaRef = (0, import_react11.useRef)(null);
610
- const ref = (0, import_react_compose_refs4.useComposedRefs)(forwardedRef, textareaRef);
611
- useAutosize(textareaRef);
612
+ const Component = asChild ? import_react_slot.Slot : import_react_textarea_autosize2.default;
612
613
  const composer = useComposerContext();
613
614
  const handleKeyPress = (e) => {
614
615
  if (chat.isLoading || rest.disabled)
615
616
  return;
616
- if (e.key === "Enter" && e.shiftKey == false) {
617
+ if (e.key === "Enter" && e.shiftKey === false) {
617
618
  e.preventDefault();
618
619
  composer.submit();
619
620
  }
@@ -623,7 +624,7 @@ var ComposerInput = (0, import_react11.forwardRef)(({ asChild, onChange, onKeyDo
623
624
  {
624
625
  value: chat.input,
625
626
  ...rest,
626
- ref,
627
+ ref: forwardedRef,
627
628
  onChange: (0, import_primitive5.composeEventHandlers)(onChange, chat.handleInputChange),
628
629
  onKeyDown: (0, import_primitive5.composeEventHandlers)(onKeyDown, handleKeyPress)
629
630
  }
@@ -631,9 +632,9 @@ var ComposerInput = (0, import_react11.forwardRef)(({ asChild, onChange, onKeyDo
631
632
  });
632
633
 
633
634
  // src/primitives/composer/ComposerSend.tsx
634
- var import_react12 = require("react");
635
+ var import_react11 = require("react");
635
636
  var import_react_primitive5 = require("@radix-ui/react-primitive");
636
- var ComposerSend = (0, import_react12.forwardRef)(
637
+ var ComposerSend = (0, import_react11.forwardRef)(
637
638
  ({ disabled, ...rest }, ref) => {
638
639
  const input = useThreadContext("Composer.Send", (s) => s.chat.input);
639
640
  return /* @__PURE__ */ React.createElement(
@@ -649,11 +650,11 @@ var ComposerSend = (0, import_react12.forwardRef)(
649
650
  );
650
651
 
651
652
  // src/utils/createActionButton.tsx
652
- var import_react13 = require("react");
653
+ var import_react12 = require("react");
653
654
  var import_react_primitive6 = require("@radix-ui/react-primitive");
654
655
  var import_primitive6 = require("@radix-ui/primitive");
655
656
  var createActionButton = (useActionButton) => {
656
- return (0, import_react13.forwardRef)(
657
+ return (0, import_react12.forwardRef)(
657
658
  (props, forwardedRef) => {
658
659
  const onClick = useActionButton(props);
659
660
  return /* @__PURE__ */ React.createElement(
@@ -692,41 +693,59 @@ __export(branchPicker_exports, {
692
693
  Root: () => BranchPickerRoot
693
694
  });
694
695
 
695
- // src/primitives/branchPicker/BranchPickerNext.tsx
696
- var useBranchPickerNext = () => {
696
+ // src/actions/useGoToNextBranch.tsx
697
+ var useGoToNextBranch = () => {
697
698
  const switchToBranch = useThreadContext(
698
699
  "BranchPicker.Next",
699
700
  (s) => s.chat.switchToBranch
700
701
  );
701
- const [message, { branchId, branchCount }] = useMessageContext(
702
- "BranchPicker.Next",
703
- (s) => [s.message, s.branchState]
704
- );
705
- if (branchCount <= 1 || branchId + 1 >= branchCount)
702
+ const context = useMessageContext("BranchPicker.Next", (s) => {
703
+ const {
704
+ message: message2,
705
+ editState: { isEditing },
706
+ branchState: { branchId: branchId2, branchCount }
707
+ } = s;
708
+ if (isEditing || branchCount <= 1 || branchId2 + 1 >= branchCount)
709
+ return null;
710
+ return { message: message2, branchId: branchId2 };
711
+ });
712
+ if (!context)
706
713
  return null;
714
+ const { message, branchId } = context;
707
715
  return () => {
708
716
  switchToBranch(message, branchId + 1);
709
717
  };
710
718
  };
711
- var BranchPickerNext = createActionButton(useBranchPickerNext);
712
719
 
713
- // src/primitives/branchPicker/BranchPickerPrevious.tsx
714
- var useBranchPickerPrevious = () => {
720
+ // src/primitives/branchPicker/BranchPickerNext.tsx
721
+ var BranchPickerNext = createActionButton(useGoToNextBranch);
722
+
723
+ // src/actions/useGoToPreviousBranch.tsx
724
+ var useGoToPreviousBranch = () => {
715
725
  const switchToBranch = useThreadContext(
716
726
  "BranchPicker.Previous",
717
727
  (s) => s.chat.switchToBranch
718
728
  );
719
- const [message, { branchId, branchCount }] = useMessageContext(
720
- "BranchPicker.Previous",
721
- (s) => [s.message, s.branchState]
722
- );
723
- if (branchCount <= 1 || branchId <= 0)
729
+ const context = useMessageContext("BranchPicker.Previous", (s) => {
730
+ const {
731
+ message: message2,
732
+ editState: { isEditing },
733
+ branchState: { branchId: branchId2, branchCount }
734
+ } = s;
735
+ if (isEditing || branchCount <= 1 || branchId2 <= 0)
736
+ return null;
737
+ return { message: message2, branchId: branchId2 };
738
+ });
739
+ if (!context)
724
740
  return null;
741
+ const { message, branchId } = context;
725
742
  return () => {
726
743
  switchToBranch(message, branchId - 1);
727
744
  };
728
745
  };
729
- var BranchPickerPrevious = createActionButton(useBranchPickerPrevious);
746
+
747
+ // src/primitives/branchPicker/BranchPickerPrevious.tsx
748
+ var BranchPickerPrevious = createActionButton(useGoToPreviousBranch);
730
749
 
731
750
  // src/primitives/branchPicker/BranchPickerCount.tsx
732
751
  var BranchPickerCount = () => {
@@ -747,10 +766,10 @@ var BranchPickerNumber = () => {
747
766
  };
748
767
 
749
768
  // src/primitives/branchPicker/BranchPickerRoot.tsx
750
- var import_react14 = require("react");
751
769
  var import_react_primitive7 = require("@radix-ui/react-primitive");
752
- var BranchPickerRoot = (0, import_react14.forwardRef)(({ ...rest }, ref) => {
753
- return /* @__PURE__ */ React.createElement(import_react_primitive7.Primitive.div, { ...rest, ref });
770
+ var import_react13 = require("react");
771
+ var BranchPickerRoot = (0, import_react13.forwardRef)(({ hideWhenSingleBranch, ...rest }, ref) => {
772
+ return /* @__PURE__ */ React.createElement(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0 }, /* @__PURE__ */ React.createElement(import_react_primitive7.Primitive.div, { ...rest, ref }));
754
773
  });
755
774
 
756
775
  // src/primitives/actionBar/index.ts
@@ -763,51 +782,79 @@ __export(actionBar_exports, {
763
782
  });
764
783
 
765
784
  // src/primitives/actionBar/ActionBarRoot.tsx
766
- var import_react15 = require("react");
767
785
  var import_react_primitive8 = require("@radix-ui/react-primitive");
768
- var ActionBarRoot = (0, import_react15.forwardRef)(
769
- ({ ...rest }, ref) => {
770
- return /* @__PURE__ */ React.createElement(import_react_primitive8.Primitive.div, { ...rest, ref });
771
- }
772
- );
786
+ var import_react14 = require("react");
787
+ var ActionBarRoot = (0, import_react14.forwardRef)(({ ...rest }, ref) => {
788
+ return /* @__PURE__ */ React.createElement(import_react_primitive8.Primitive.div, { ...rest, ref });
789
+ });
773
790
 
774
- // src/primitives/actionBar/ActionBarCopy.tsx
775
- var useActionBarCopy = ({ copiedDuration = 3e3 }) => {
776
- const [messageContent, setIsCopied] = useMessageContext(
777
- "ActionBar.Copy",
778
- (s) => [s.message.content, s.setIsCopied]
779
- );
791
+ // src/actions/useCopyMessage.tsx
792
+ var useCopyMessage = ({ copiedDuration = 3e3 }) => {
793
+ const context = useMessageContext("ActionBar.Copy", (s) => {
794
+ const {
795
+ editState: { isEditing },
796
+ message: { content: content2 },
797
+ setIsCopied: setIsCopied2
798
+ } = s;
799
+ if (isEditing)
800
+ return null;
801
+ return { content: content2, setIsCopied: setIsCopied2 };
802
+ });
803
+ if (!context)
804
+ return null;
805
+ const { content, setIsCopied } = context;
780
806
  return () => {
781
- navigator.clipboard.writeText(messageContent);
807
+ navigator.clipboard.writeText(content);
782
808
  setIsCopied(true);
783
809
  setTimeout(() => setIsCopied(false), copiedDuration);
784
810
  };
785
811
  };
786
- var ActionBarCopy = createActionButton(useActionBarCopy);
787
812
 
788
- // src/primitives/actionBar/ActionBarReload.tsx
789
- var useActionBarReload = () => {
790
- const chat = useThreadContext("ActionBar.Reload", (s) => s.chat);
791
- const message = useMessageContext("ActionBar.Reload", (s) => s.message);
792
- if (message.role !== "assistant" || chat.isLoading)
813
+ // src/primitives/actionBar/ActionBarCopy.tsx
814
+ var ActionBarCopy = createActionButton(useCopyMessage);
815
+
816
+ // src/actions/useReloadMessage.tsx
817
+ var useReloadMessage = () => {
818
+ const [isLoading, reloadAt] = useThreadContext("ActionBar.Reload", (s) => [
819
+ s.chat.isLoading,
820
+ s.chat.reloadAt
821
+ ]);
822
+ const message = useMessageContext("ActionBar.Reload", (s) => {
823
+ const message2 = s.message;
824
+ if (message2.role !== "assistant" || isLoading)
825
+ return null;
826
+ return message2;
827
+ });
828
+ if (!message)
793
829
  return null;
794
- return () => chat.reloadAt(message);
830
+ return () => reloadAt(message);
795
831
  };
796
- var ActionBarReload = createActionButton(useActionBarReload);
797
832
 
798
- // src/primitives/actionBar/ActionBarEdit.tsx
799
- var useActionBarEdit = () => {
800
- const [editState, messageContent, setEditState] = useMessageContext(
801
- "ActionBar.Edit",
802
- (s) => [s.editState, s.message.content, s.setEditState]
803
- );
804
- if (editState.isEditing)
833
+ // src/primitives/actionBar/ActionBarReload.tsx
834
+ var ActionBarReload = createActionButton(useReloadMessage);
835
+
836
+ // src/actions/useBeginMessageEdit.tsx
837
+ var useBeginMessageEdit = () => {
838
+ const context = useMessageContext("ActionBar.Edit", (s) => {
839
+ const {
840
+ message: { content: content2 },
841
+ editState: { isEditing },
842
+ setEditState: setEditState2
843
+ } = s;
844
+ if (isEditing)
845
+ return null;
846
+ return { content: content2, setEditState: setEditState2 };
847
+ });
848
+ if (!context)
805
849
  return null;
850
+ const { content, setEditState } = context;
806
851
  return () => {
807
- setEditState({ isEditing: true, value: messageContent });
852
+ setEditState({ isEditing: true, value: content });
808
853
  };
809
854
  };
810
- var ActionBarEdit = createActionButton(useActionBarEdit);
855
+
856
+ // src/primitives/actionBar/ActionBarEdit.tsx
857
+ var ActionBarEdit = createActionButton(useBeginMessageEdit);
811
858
 
812
859
  // src/primitives/editBar/index.ts
813
860
  var editBar_exports = {};
@@ -818,57 +865,85 @@ __export(editBar_exports, {
818
865
  });
819
866
 
820
867
  // src/primitives/editBar/EditBarRoot.tsx
821
- var import_react16 = require("react");
822
868
  var import_react_primitive9 = require("@radix-ui/react-primitive");
823
- var EditBarRoot = (0, import_react16.forwardRef)(
869
+ var import_react15 = require("react");
870
+ var EditBarRoot = (0, import_react15.forwardRef)(
824
871
  ({ ...rest }, ref) => {
825
872
  return /* @__PURE__ */ React.createElement(import_react_primitive9.Primitive.div, { ...rest, ref });
826
873
  }
827
874
  );
828
875
 
829
- // src/primitives/editBar/EditBarSave.tsx
830
- var useEditBarSave = () => {
876
+ // src/actions/useSaveMessageEdit.tsx
877
+ var useSaveMessageEdit = () => {
831
878
  const chat = useThreadContext("EditBar.Save", (s) => s.chat);
832
- const [editState, message, setEditState] = useMessageContext(
833
- "EditBar.Save",
834
- (s) => [s.editState, s.message, s.setEditState]
835
- );
836
- if (!editState.isEditing)
879
+ const context = useMessageContext("EditBar.Save", (s) => {
880
+ const { message: message2, editState, setEditState: setEditState2 } = s;
881
+ if (!editState.isEditing)
882
+ return null;
883
+ return { message: message2, content: editState.value, setEditState: setEditState2 };
884
+ });
885
+ if (!context)
837
886
  return null;
887
+ const { message, content, setEditState } = context;
838
888
  return () => {
839
- if (!editState.isEditing)
840
- return;
841
889
  chat.editAt(message, {
842
890
  ...message,
843
891
  id: void 0,
844
892
  // remove id to create a new message
845
- content: editState.value
893
+ content
846
894
  });
847
895
  setEditState({ isEditing: false });
848
896
  };
849
897
  };
850
- var EditBarSave = createActionButton(useEditBarSave);
851
898
 
852
- // src/primitives/editBar/EditBarCancel.tsx
853
- var useEditBarCancel = () => {
854
- const [isEditing, setEditState] = useMessageContext("EditBar.Cancel", (s) => [
855
- s.editState.isEditing,
856
- s.setEditState
857
- ]);
858
- if (!isEditing)
899
+ // src/primitives/editBar/EditBarSave.tsx
900
+ var EditBarSave = createActionButton(useSaveMessageEdit);
901
+
902
+ // src/actions/useCancelMessageEdit.tsx
903
+ var useCancelMessageEdit = () => {
904
+ const context = useMessageContext("EditBar.Cancel", (s) => {
905
+ const {
906
+ editState: { isEditing },
907
+ setEditState: setEditState2
908
+ } = s;
909
+ if (!isEditing)
910
+ return null;
911
+ return { setEditState: setEditState2 };
912
+ });
913
+ if (!context)
859
914
  return null;
915
+ const { setEditState } = context;
860
916
  return () => {
861
917
  setEditState({ isEditing: false });
862
918
  };
863
919
  };
864
- var EditBarCancel = createActionButton(useEditBarCancel);
920
+
921
+ // src/primitives/editBar/EditBarCancel.tsx
922
+ var EditBarCancel = createActionButton(useCancelMessageEdit);
923
+
924
+ // src/vercel/VercelAIThreadProvider.tsx
925
+ var VercelAIThreadProvider = ({
926
+ chat,
927
+ children
928
+ }) => {
929
+ const branches = useChatWithBranches(chat);
930
+ return /* @__PURE__ */ React.createElement(ThreadContextProvider, { chat: branches }, children);
931
+ };
865
932
  // Annotate the CommonJS export names for ESM import in node:
866
933
  0 && (module.exports = {
867
- ActionBar,
868
- BranchPicker,
869
- Composer,
870
- EditBar,
871
- Message,
872
- Thread,
873
- unstable_useMessageContext
934
+ ActionBarPrimitive,
935
+ BranchPickerPrimitive,
936
+ ComposerPrimitive,
937
+ EditBarPrimitive,
938
+ MessagePrimitive,
939
+ ThreadPrimitive,
940
+ VercelAIThreadProvider,
941
+ unstable_useMessageContext,
942
+ useBeginMessageEdit,
943
+ useCancelMessageEdit,
944
+ useCopyMessage,
945
+ useGoToNextBranch,
946
+ useGoToPreviousBranch,
947
+ useReloadMessage,
948
+ useSaveMessageEdit
874
949
  });