@assistant-ui/react 0.0.1 → 0.0.3

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