@assistant-ui/react 0.1.9 → 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.mjs CHANGED
@@ -9,9 +9,9 @@ import {
9
9
  useContentPartContext,
10
10
  useMessageContext,
11
11
  useThreadContext
12
- } from "./chunk-7O2URLFI.mjs";
12
+ } from "./chunk-KUACYNLE.mjs";
13
13
 
14
- // src/actions/useCopyMessage.tsx
14
+ // src/primitive-hooks/actionBar/useActionBarCopy.tsx
15
15
  import { useCallback } from "react";
16
16
 
17
17
  // src/utils/combined/useCombinedStore.ts
@@ -48,38 +48,56 @@ var getMessageText = (message) => {
48
48
  return textParts.map((part) => part.text).join("\n\n");
49
49
  };
50
50
 
51
- // src/actions/useCopyMessage.tsx
52
- var useCopyMessage = ({ copiedDuration = 3e3 }) => {
53
- const { useMessage, useMessageUtils, useComposer } = useMessageContext();
51
+ // src/primitive-hooks/actionBar/useActionBarCopy.tsx
52
+ var useActionBarCopy = ({
53
+ copiedDuration = 3e3
54
+ } = {}) => {
55
+ const { useMessage, useMessageUtils, useEditComposer } = useMessageContext();
54
56
  const hasCopyableContent = useCombinedStore(
55
- [useMessage, useComposer],
57
+ [useMessage, useEditComposer],
56
58
  (m, c) => {
57
- return c.isEditing || m.message.content.some((c2) => c2.type === "text");
59
+ return !c.isEditing && m.message.content.some((c2) => c2.type === "text");
58
60
  }
59
61
  );
60
62
  const callback = useCallback(() => {
61
63
  const { message } = useMessage.getState();
62
64
  const { setIsCopied } = useMessageUtils.getState();
63
- const { isEditing, value: composerValue } = useComposer.getState();
65
+ const { isEditing, value: composerValue } = useEditComposer.getState();
64
66
  const valueToCopy = isEditing ? composerValue : getMessageText(message);
65
67
  navigator.clipboard.writeText(valueToCopy);
66
68
  setIsCopied(true);
67
69
  setTimeout(() => setIsCopied(false), copiedDuration);
68
- }, [useMessage, useMessageUtils, useComposer, copiedDuration]);
70
+ }, [useMessage, useMessageUtils, useEditComposer, copiedDuration]);
69
71
  if (!hasCopyableContent) return null;
70
72
  return callback;
71
73
  };
72
74
 
73
- // src/actions/useReloadMessage.tsx
75
+ // src/primitive-hooks/actionBar/useActionBarEdit.tsx
74
76
  import { useCallback as useCallback2 } from "react";
75
- var useReloadMessage = () => {
77
+ var useActionBarEdit = () => {
78
+ const { useMessage, useEditComposer } = useMessageContext();
79
+ const disabled = useCombinedStore(
80
+ [useMessage, useEditComposer],
81
+ (m, c) => m.message.role !== "user" || c.isEditing
82
+ );
83
+ const callback = useCallback2(() => {
84
+ const { edit } = useEditComposer.getState();
85
+ edit();
86
+ }, [useEditComposer]);
87
+ if (disabled) return null;
88
+ return callback;
89
+ };
90
+
91
+ // src/primitive-hooks/actionBar/useActionBarReload.tsx
92
+ import { useCallback as useCallback3 } from "react";
93
+ var useActionBarReload = () => {
76
94
  const { useThread, useThreadActions, useViewport } = useThreadContext();
77
95
  const { useMessage } = useMessageContext();
78
96
  const disabled = useCombinedStore(
79
97
  [useThread, useMessage],
80
98
  (t, m) => t.isRunning || m.message.role !== "assistant"
81
99
  );
82
- const callback = useCallback2(() => {
100
+ const callback = useCallback3(() => {
83
101
  const { parentId } = useMessage.getState();
84
102
  useThreadActions.getState().startRun(parentId);
85
103
  useViewport.getState().scrollToBottom();
@@ -88,29 +106,20 @@ var useReloadMessage = () => {
88
106
  return callback;
89
107
  };
90
108
 
91
- // src/actions/useBeginMessageEdit.tsx
92
- import { useCallback as useCallback3 } from "react";
93
- var useBeginMessageEdit = () => {
94
- const { useMessage, useComposer } = useMessageContext();
95
- const disabled = useCombinedStore(
96
- [useMessage, useComposer],
97
- (m, c) => m.message.role !== "user" || c.isEditing
98
- );
99
- const callback = useCallback3(() => {
100
- const { edit } = useComposer.getState();
101
- edit();
102
- }, [useComposer]);
103
- if (disabled) return null;
104
- return callback;
109
+ // src/primitive-hooks/branchPicker/useBranchPickerCount.tsx
110
+ var useBranchPickerCount = () => {
111
+ const { useMessage } = useMessageContext();
112
+ const branchCount = useMessage((s) => s.branches.length);
113
+ return branchCount;
105
114
  };
106
115
 
107
- // src/actions/useGoToNextBranch.tsx
116
+ // src/primitive-hooks/branchPicker/useBranchPickerNext.tsx
108
117
  import { useCallback as useCallback4 } from "react";
109
- var useGoToNextBranch = () => {
118
+ var useBranchPickerNext = () => {
110
119
  const { useThreadActions } = useThreadContext();
111
- const { useMessage, useComposer } = useMessageContext();
120
+ const { useMessage, useEditComposer } = useMessageContext();
112
121
  const disabled = useCombinedStore(
113
- [useMessage, useComposer],
122
+ [useMessage, useEditComposer],
114
123
  (m, c) => c.isEditing || m.branches.indexOf(m.message.id) + 1 >= m.branches.length
115
124
  );
116
125
  const callback = useCallback4(() => {
@@ -121,13 +130,20 @@ var useGoToNextBranch = () => {
121
130
  return callback;
122
131
  };
123
132
 
124
- // src/actions/useGoToPreviousBranch.tsx
133
+ // src/primitive-hooks/branchPicker/useBranchPickerNumber.tsx
134
+ var useBranchPickerNumber = () => {
135
+ const { useMessage } = useMessageContext();
136
+ const branchIdx = useMessage((s) => s.branches.indexOf(s.message.id));
137
+ return branchIdx + 1;
138
+ };
139
+
140
+ // src/primitive-hooks/branchPicker/useBranchPickerPrevious.tsx
125
141
  import { useCallback as useCallback5 } from "react";
126
- var useGoToPreviousBranch = () => {
142
+ var useBranchPickerPrevious = () => {
127
143
  const { useThreadActions } = useThreadContext();
128
- const { useMessage, useComposer } = useMessageContext();
144
+ const { useMessage, useEditComposer } = useMessageContext();
129
145
  const disabled = useCombinedStore(
130
- [useMessage, useComposer],
146
+ [useMessage, useEditComposer],
131
147
  (m, c) => c.isEditing || m.branches.indexOf(m.message.id) <= 0
132
148
  );
133
149
  const callback = useCallback5(() => {
@@ -138,6 +154,162 @@ var useGoToPreviousBranch = () => {
138
154
  return callback;
139
155
  };
140
156
 
157
+ // src/primitive-hooks/composer/useComposerCancel.tsx
158
+ import { useCallback as useCallback6 } from "react";
159
+ var useComposerCancel = () => {
160
+ const { useComposer } = useComposerContext();
161
+ const disabled = useComposer((c) => !c.isEditing);
162
+ const callback = useCallback6(() => {
163
+ const { cancel } = useComposer.getState();
164
+ cancel();
165
+ }, [useComposer]);
166
+ if (disabled) return null;
167
+ return callback;
168
+ };
169
+
170
+ // src/primitive-hooks/composer/useComposerIf.tsx
171
+ var useComposerIf = (props) => {
172
+ const { useComposer } = useComposerContext();
173
+ return useComposer((composer) => {
174
+ if (props.editing === true && !composer.isEditing) return false;
175
+ if (props.editing === false && composer.isEditing) return false;
176
+ return true;
177
+ });
178
+ };
179
+
180
+ // src/primitive-hooks/composer/useComposerSend.tsx
181
+ import { useCallback as useCallback7 } from "react";
182
+ var useComposerSend = () => {
183
+ const { useViewport } = useThreadContext();
184
+ const { useComposer } = useComposerContext();
185
+ const disabled = useComposer((c) => !c.isEditing || c.value.length === 0);
186
+ const callback = useCallback7(() => {
187
+ const composerState = useComposer.getState();
188
+ if (!composerState.isEditing) return;
189
+ composerState.send();
190
+ useViewport.getState().scrollToBottom();
191
+ }, [useComposer, useViewport]);
192
+ if (disabled) return null;
193
+ return callback;
194
+ };
195
+
196
+ // src/primitive-hooks/contentPart/useContentPartDisplay.tsx
197
+ var useContentPartDisplay = () => {
198
+ const { useContentPart } = useContentPartContext();
199
+ const display = useContentPart((c) => {
200
+ if (c.part.type !== "ui")
201
+ throw new Error(
202
+ "This component can only be used inside ui content parts."
203
+ );
204
+ return c.part.display;
205
+ });
206
+ return display;
207
+ };
208
+
209
+ // src/primitive-hooks/contentPart/useContentPartImage.tsx
210
+ var useContentPartImage = () => {
211
+ const { useContentPart } = useContentPartContext();
212
+ const image = useContentPart((c) => {
213
+ if (c.part.type !== "image")
214
+ throw new Error(
215
+ "ContentPartImage can only be used inside image content parts."
216
+ );
217
+ return c.part.image;
218
+ });
219
+ return image;
220
+ };
221
+
222
+ // src/primitive-hooks/contentPart/useContentPartInProgressIndicator.tsx
223
+ var useContentPartInProgressIndicator = () => {
224
+ const { useMessageUtils } = useMessageContext();
225
+ const { useContentPart } = useContentPartContext();
226
+ const indicator = useCombinedStore(
227
+ [useMessageUtils, useContentPart],
228
+ (m, c) => c.status === "in_progress" ? m.inProgressIndicator : null
229
+ );
230
+ return indicator;
231
+ };
232
+
233
+ // src/primitive-hooks/contentPart/useContentPartText.tsx
234
+ var useContentPartText = () => {
235
+ const { useContentPart } = useContentPartContext();
236
+ const text = useContentPart((c) => {
237
+ if (c.part.type !== "text")
238
+ throw new Error(
239
+ "ContentPartText can only be used inside text content parts."
240
+ );
241
+ return c.part.text;
242
+ });
243
+ return text;
244
+ };
245
+
246
+ // src/primitive-hooks/message/useMessageIf.tsx
247
+ var useMessageIf = (props) => {
248
+ const { useMessage, useMessageUtils } = useMessageContext();
249
+ return useCombinedStore(
250
+ [useMessage, useMessageUtils],
251
+ ({ message, branches, isLast }, { isCopied, isHovering }) => {
252
+ if (props.hasBranches === true && branches.length < 2) return false;
253
+ if (props.user && message.role !== "user") return false;
254
+ if (props.assistant && message.role !== "assistant") return false;
255
+ if (props.lastOrHover === true && !isHovering && !isLast) return false;
256
+ if (props.copied === true && !isCopied) return false;
257
+ if (props.copied === false && isCopied) return false;
258
+ return true;
259
+ }
260
+ );
261
+ };
262
+
263
+ // src/primitive-hooks/thread/useThreadIf.tsx
264
+ var useThreadIf = (props) => {
265
+ const { useThread } = useThreadContext();
266
+ return useThread((thread) => {
267
+ if (props.empty === true && thread.messages.length !== 0) return false;
268
+ if (props.empty === false && thread.messages.length === 0) return false;
269
+ if (props.running === true && !thread.isRunning) return false;
270
+ if (props.running === false && thread.isRunning) return false;
271
+ return true;
272
+ });
273
+ };
274
+
275
+ // src/primitive-hooks/thread/useThreadEmpty.tsx
276
+ var useThreadEmpty = () => {
277
+ return useThreadIf({ empty: true });
278
+ };
279
+
280
+ // src/primitive-hooks/thread/useThreadScrollToBottom.tsx
281
+ import { useCallback as useCallback8 } from "react";
282
+ var useThreadScrollToBottom = () => {
283
+ const { useViewport } = useThreadContext();
284
+ const isAtBottom = useViewport((s) => s.isAtBottom);
285
+ const handleScrollToBottom = useCallback8(() => {
286
+ const { scrollToBottom } = useViewport.getState();
287
+ scrollToBottom();
288
+ }, [useViewport]);
289
+ if (isAtBottom) return null;
290
+ return handleScrollToBottom;
291
+ };
292
+
293
+ // src/primitive-hooks/thread/useThreadSuggestion.tsx
294
+ import { useCallback as useCallback9 } from "react";
295
+ var useThreadSuggestion = ({
296
+ prompt,
297
+ autoSend
298
+ }) => {
299
+ const { useThread, useComposer } = useThreadContext();
300
+ const disabled = useThread((t) => t.isRunning);
301
+ const callback = useCallback9(() => {
302
+ const thread = useThread.getState();
303
+ const composer = useComposer.getState();
304
+ composer.setValue(prompt);
305
+ if (autoSend && !thread.isRunning) {
306
+ composer.send();
307
+ }
308
+ }, [useThread, useComposer, prompt, autoSend]);
309
+ if (disabled) return null;
310
+ return callback;
311
+ };
312
+
141
313
  // src/primitives/thread/index.ts
142
314
  var thread_exports = {};
143
315
  __export(thread_exports, {
@@ -161,142 +333,161 @@ var ThreadRoot = forwardRef(
161
333
  );
162
334
  ThreadRoot.displayName = "ThreadRoot";
163
335
 
164
- // src/primitives/thread/ThreadIf.tsx
165
- var useThreadIf = (props) => {
166
- const { useThread } = useThreadContext();
167
- return useThread((thread) => {
168
- if (props.empty === true && thread.messages.length !== 0) return false;
169
- if (props.empty === false && thread.messages.length === 0) return false;
170
- if (props.running === true && !thread.isRunning) return false;
171
- if (props.running === false && thread.isRunning) return false;
172
- return true;
173
- });
336
+ // src/primitives/thread/ThreadEmpty.tsx
337
+ var ThreadEmpty = ({ children }) => {
338
+ const empty = useThreadEmpty();
339
+ return empty ? children : null;
174
340
  };
341
+
342
+ // src/primitives/thread/ThreadIf.tsx
175
343
  var ThreadIf = ({ children, ...query }) => {
176
344
  const result = useThreadIf(query);
177
345
  return result ? children : null;
178
346
  };
179
347
 
180
- // src/primitives/thread/ThreadEmpty.tsx
181
- import { jsx as jsx2 } from "react/jsx-runtime";
182
- var ThreadEmpty = ({ children }) => {
183
- return /* @__PURE__ */ jsx2(ThreadIf, { empty: true, children });
184
- };
185
-
186
348
  // src/primitives/thread/ThreadViewport.tsx
187
- import { composeEventHandlers } from "@radix-ui/primitive";
188
- import { useComposedRefs } from "@radix-ui/react-compose-refs";
349
+ import { useComposedRefs as useComposedRefs2 } from "@radix-ui/react-compose-refs";
189
350
  import { Primitive as Primitive2 } from "@radix-ui/react-primitive";
190
- import {
191
- forwardRef as forwardRef2,
192
- useRef
193
- } from "react";
351
+ import { forwardRef as forwardRef2 } from "react";
352
+
353
+ // src/primitive-hooks/thread/useThreadViewportAutoScroll.tsx
354
+ import { useComposedRefs } from "@radix-ui/react-compose-refs";
355
+ import { useRef as useRef2 } from "react";
194
356
 
195
357
  // src/utils/hooks/useOnResizeContent.tsx
196
358
  import { useCallbackRef } from "@radix-ui/react-use-callback-ref";
197
- import { useEffect } from "react";
198
- var useOnResizeContent = (ref, callback) => {
359
+ import { useCallback as useCallback11 } from "react";
360
+
361
+ // src/utils/hooks/useManagedRef.ts
362
+ import { useCallback as useCallback10, useRef } from "react";
363
+ var useManagedRef = (callback) => {
364
+ const cleanupRef = useRef();
365
+ const ref = useCallback10(
366
+ (el) => {
367
+ if (cleanupRef.current) {
368
+ cleanupRef.current();
369
+ }
370
+ if (el) {
371
+ cleanupRef.current = callback(el);
372
+ }
373
+ },
374
+ [callback]
375
+ );
376
+ return ref;
377
+ };
378
+
379
+ // src/utils/hooks/useOnResizeContent.tsx
380
+ var useOnResizeContent = (callback) => {
199
381
  const callbackRef = useCallbackRef(callback);
200
- const el = ref.current;
201
- useEffect(() => {
202
- if (!el) return;
203
- const resizeObserver = new ResizeObserver(() => {
204
- callbackRef();
205
- });
206
- const mutationObserver = new MutationObserver((mutations) => {
207
- for (const mutation of mutations) {
208
- for (const node of mutation.addedNodes) {
209
- if (node instanceof Element) {
210
- resizeObserver.observe(node);
382
+ const refCallback = useCallback11(
383
+ (el) => {
384
+ const resizeObserver = new ResizeObserver(() => {
385
+ callbackRef();
386
+ });
387
+ const mutationObserver = new MutationObserver((mutations) => {
388
+ for (const mutation of mutations) {
389
+ for (const node of mutation.addedNodes) {
390
+ if (node instanceof Element) {
391
+ resizeObserver.observe(node);
392
+ }
211
393
  }
212
- }
213
- for (const node of mutation.removedNodes) {
214
- if (node instanceof Element) {
215
- resizeObserver.unobserve(node);
394
+ for (const node of mutation.removedNodes) {
395
+ if (node instanceof Element) {
396
+ resizeObserver.unobserve(node);
397
+ }
216
398
  }
217
399
  }
400
+ callbackRef();
401
+ });
402
+ resizeObserver.observe(el);
403
+ mutationObserver.observe(el, { childList: true });
404
+ for (const child of el.children) {
405
+ resizeObserver.observe(child);
218
406
  }
219
- callbackRef();
220
- });
221
- resizeObserver.observe(el);
222
- mutationObserver.observe(el, { childList: true });
223
- for (const child of el.children) {
224
- resizeObserver.observe(child);
225
- }
226
- return () => {
227
- resizeObserver.disconnect();
228
- mutationObserver.disconnect();
229
- };
230
- }, [el, callbackRef]);
407
+ return () => {
408
+ resizeObserver.disconnect();
409
+ mutationObserver.disconnect();
410
+ };
411
+ },
412
+ [callbackRef]
413
+ );
414
+ return useManagedRef(refCallback);
231
415
  };
232
416
 
233
417
  // src/utils/hooks/useOnScrollToBottom.tsx
234
418
  import { useCallbackRef as useCallbackRef2 } from "@radix-ui/react-use-callback-ref";
235
- import { useEffect as useEffect2 } from "react";
419
+ import { useEffect } from "react";
236
420
  var useOnScrollToBottom = (callback) => {
237
421
  const callbackRef = useCallbackRef2(callback);
238
422
  const { useViewport } = useThreadContext();
239
- useEffect2(() => {
423
+ useEffect(() => {
240
424
  return useViewport.getState().onScrollToBottom(() => {
241
425
  callbackRef();
242
426
  });
243
427
  }, [useViewport, callbackRef]);
244
428
  };
245
429
 
246
- // src/primitives/thread/ThreadViewport.tsx
247
- import { jsx as jsx3, jsxs } from "react/jsx-runtime";
248
- var ThreadViewport = forwardRef2(({ autoScroll = true, onScroll, children, ...rest }, forwardedRef) => {
249
- const messagesEndRef = useRef(null);
250
- const divRef = useRef(null);
251
- const ref = useComposedRefs(forwardedRef, divRef);
430
+ // src/primitive-hooks/thread/useThreadViewportAutoScroll.tsx
431
+ var useThreadViewportAutoScroll = ({
432
+ autoScroll = true
433
+ }) => {
434
+ const divRef = useRef2(null);
252
435
  const { useViewport } = useThreadContext();
253
- const firstRenderRef = useRef(true);
254
- const isScrollingToBottomRef = useRef(false);
255
- const lastScrollTop = useRef(0);
436
+ const firstRenderRef = useRef2(true);
437
+ const lastScrollTop = useRef2(0);
438
+ const isScrollingToBottomRef = useRef2(false);
256
439
  const scrollToBottom = () => {
257
- const div = messagesEndRef.current;
440
+ const div = divRef.current;
258
441
  if (!div || !autoScroll) return;
259
442
  const behavior = firstRenderRef.current ? "instant" : "auto";
260
443
  firstRenderRef.current = false;
261
444
  isScrollingToBottomRef.current = true;
262
- div.scrollIntoView({ behavior });
445
+ div.scrollTo({ top: div.scrollHeight, behavior });
263
446
  };
264
- useOnResizeContent(divRef, () => {
265
- if (!isScrollingToBottomRef.current && !useViewport.getState().isAtBottom) {
266
- handleScroll();
267
- } else {
268
- scrollToBottom();
269
- }
270
- });
271
- useOnScrollToBottom(() => {
272
- scrollToBottom();
273
- });
274
447
  const handleScroll = () => {
275
448
  const div = divRef.current;
276
449
  if (!div) return;
277
450
  const isAtBottom = useViewport.getState().isAtBottom;
278
451
  const newIsAtBottom = div.scrollHeight - div.scrollTop <= div.clientHeight;
279
452
  if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {
280
- } else if (newIsAtBottom !== isAtBottom) {
281
- isScrollingToBottomRef.current = false;
282
- useViewport.setState({
283
- isAtBottom: newIsAtBottom
284
- });
453
+ } else {
454
+ isScrollingToBottomRef.current = newIsAtBottom;
455
+ if (newIsAtBottom !== isAtBottom) {
456
+ useViewport.setState({
457
+ isAtBottom: newIsAtBottom
458
+ });
459
+ }
285
460
  }
286
461
  lastScrollTop.current = div.scrollTop;
287
462
  };
288
- return /* @__PURE__ */ jsxs(
289
- Primitive2.div,
290
- {
291
- ...rest,
292
- onScroll: composeEventHandlers(onScroll, handleScroll),
293
- ref,
294
- children: [
295
- children,
296
- /* @__PURE__ */ jsx3("div", { ref: messagesEndRef })
297
- ]
463
+ const resizeRef = useOnResizeContent(() => {
464
+ if (!isScrollingToBottomRef.current && !useViewport.getState().isAtBottom && !firstRenderRef.current) {
465
+ handleScroll();
466
+ } else {
467
+ scrollToBottom();
298
468
  }
299
- );
469
+ });
470
+ const scrollRef = useManagedRef((el) => {
471
+ el.addEventListener("scroll", handleScroll);
472
+ return () => {
473
+ el.removeEventListener("scroll", handleScroll);
474
+ };
475
+ });
476
+ const autoScrollRef = useComposedRefs(resizeRef, scrollRef, divRef);
477
+ useOnScrollToBottom(() => {
478
+ scrollToBottom();
479
+ });
480
+ return autoScrollRef;
481
+ };
482
+
483
+ // src/primitives/thread/ThreadViewport.tsx
484
+ import { jsx as jsx2 } from "react/jsx-runtime";
485
+ var ThreadViewport = forwardRef2(({ autoScroll, onScroll, children, ...rest }, forwardedRef) => {
486
+ const autoScrollRef = useThreadViewportAutoScroll({
487
+ autoScroll
488
+ });
489
+ const ref = useComposedRefs2(forwardedRef, autoScrollRef);
490
+ return /* @__PURE__ */ jsx2(Primitive2.div, { ...rest, ref, children });
300
491
  });
301
492
  ThreadViewport.displayName = "ThreadViewport";
302
493
 
@@ -304,10 +495,10 @@ ThreadViewport.displayName = "ThreadViewport";
304
495
  import { memo } from "react";
305
496
 
306
497
  // src/context/providers/MessageProvider.tsx
307
- import { useEffect as useEffect3, useState } from "react";
498
+ import { useEffect as useEffect2, useState } from "react";
308
499
  import { create as create3 } from "zustand";
309
500
 
310
- // src/context/stores/MessageComposer.ts
501
+ // src/context/stores/EditComposer.ts
311
502
  import { create } from "zustand";
312
503
 
313
504
  // src/context/stores/BaseComposer.ts
@@ -318,7 +509,7 @@ var makeBaseComposer = (set) => ({
318
509
  }
319
510
  });
320
511
 
321
- // src/context/stores/MessageComposer.ts
512
+ // src/context/stores/EditComposer.ts
322
513
  var makeEditComposerStore = ({
323
514
  onEdit,
324
515
  onSend
@@ -359,7 +550,7 @@ var makeMessageUtilsStore = () => create2((set) => ({
359
550
  }));
360
551
 
361
552
  // src/context/providers/MessageProvider.tsx
362
- import { jsx as jsx4 } from "react/jsx-runtime";
553
+ import { jsx as jsx3 } from "react/jsx-runtime";
363
554
  var getIsLast = (thread, message) => {
364
555
  return thread.messages[thread.messages.length - 1]?.id === message.id;
365
556
  };
@@ -384,7 +575,7 @@ var useMessageContext2 = (messageIndex) => {
384
575
  const [context] = useState(() => {
385
576
  const useMessage = create3(() => ({}));
386
577
  const useMessageUtils = makeMessageUtilsStore();
387
- const useComposer = makeEditComposerStore({
578
+ const useEditComposer = makeEditComposerStore({
388
579
  onEdit: () => {
389
580
  const message = useMessage.getState().message;
390
581
  if (message.role !== "user")
@@ -405,6 +596,7 @@ var useMessageContext2 = (messageIndex) => {
405
596
  );
406
597
  useThreadActions.getState().append({
407
598
  parentId,
599
+ role: "user",
408
600
  content: [{ type: "text", text }, ...nonTextParts]
409
601
  });
410
602
  }
@@ -415,9 +607,9 @@ var useMessageContext2 = (messageIndex) => {
415
607
  useMessage,
416
608
  messageIndex
417
609
  );
418
- return { useMessage, useMessageUtils, useComposer };
610
+ return { useMessage, useMessageUtils, useEditComposer };
419
611
  });
420
- useEffect3(() => {
612
+ useEffect2(() => {
421
613
  return useThread.subscribe((thread) => {
422
614
  syncMessage(
423
615
  thread,
@@ -434,46 +626,23 @@ var MessageProvider = ({
434
626
  children
435
627
  }) => {
436
628
  const context = useMessageContext2(messageIndex);
437
- return /* @__PURE__ */ jsx4(MessageContext.Provider, { value: context, children });
629
+ return /* @__PURE__ */ jsx3(MessageContext.Provider, { value: context, children });
438
630
  };
439
631
 
440
632
  // src/primitives/composer/ComposerIf.tsx
441
- var useComposerIf = (props) => {
442
- const { useComposer } = useComposerContext();
443
- return useComposer((composer) => {
444
- if (props.editing === true && !composer.isEditing) return false;
445
- if (props.editing === false && composer.isEditing) return false;
446
- return true;
447
- });
448
- };
449
633
  var ComposerIf = ({ children, ...query }) => {
450
634
  const result = useComposerIf(query);
451
635
  return result ? children : null;
452
636
  };
453
637
 
454
638
  // src/primitives/message/MessageIf.tsx
455
- var useMessageIf = (props) => {
456
- const { useMessage, useMessageUtils } = useMessageContext();
457
- return useCombinedStore(
458
- [useMessage, useMessageUtils],
459
- ({ message, branches, isLast }, { isCopied, isHovering }) => {
460
- if (props.hasBranches === true && branches.length < 2) return false;
461
- if (props.user && message.role !== "user") return false;
462
- if (props.assistant && message.role !== "assistant") return false;
463
- if (props.lastOrHover === true && !isHovering && !isLast) return false;
464
- if (props.copied === true && !isCopied) return false;
465
- if (props.copied === false && isCopied) return false;
466
- return true;
467
- }
468
- );
469
- };
470
639
  var MessageIf = ({ children, ...query }) => {
471
640
  const result = useMessageIf(query);
472
641
  return result ? children : null;
473
642
  };
474
643
 
475
644
  // src/primitives/thread/ThreadMessages.tsx
476
- import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
645
+ import { jsx as jsx4, jsxs } from "react/jsx-runtime";
477
646
  var getComponents = (components) => {
478
647
  return {
479
648
  EditComposer: components.EditComposer ?? components.UserMessage ?? components.Message,
@@ -486,12 +655,12 @@ var ThreadMessageImpl = ({
486
655
  components
487
656
  }) => {
488
657
  const { UserMessage, EditComposer, AssistantMessage } = getComponents(components);
489
- return /* @__PURE__ */ jsxs2(MessageProvider, { messageIndex, children: [
490
- /* @__PURE__ */ jsxs2(MessageIf, { user: true, children: [
491
- /* @__PURE__ */ jsx5(ComposerIf, { editing: false, children: /* @__PURE__ */ jsx5(UserMessage, {}) }),
492
- /* @__PURE__ */ jsx5(ComposerIf, { editing: true, children: /* @__PURE__ */ jsx5(EditComposer, {}) })
658
+ return /* @__PURE__ */ jsxs(MessageProvider, { messageIndex, children: [
659
+ /* @__PURE__ */ jsxs(MessageIf, { user: true, children: [
660
+ /* @__PURE__ */ jsx4(ComposerIf, { editing: false, children: /* @__PURE__ */ jsx4(UserMessage, {}) }),
661
+ /* @__PURE__ */ jsx4(ComposerIf, { editing: true, children: /* @__PURE__ */ jsx4(EditComposer, {}) })
493
662
  ] }),
494
- /* @__PURE__ */ jsx5(MessageIf, { assistant: true, children: /* @__PURE__ */ jsx5(AssistantMessage, {}) })
663
+ /* @__PURE__ */ jsx4(MessageIf, { assistant: true, children: /* @__PURE__ */ jsx4(AssistantMessage, {}) })
495
664
  ] });
496
665
  };
497
666
  var ThreadMessage = memo(
@@ -504,7 +673,7 @@ var ThreadMessages = ({ components }) => {
504
673
  if (messagesLength === 0) return null;
505
674
  return new Array(messagesLength).fill(null).map((_, idx) => {
506
675
  const messageIndex = idx;
507
- return /* @__PURE__ */ jsx5(
676
+ return /* @__PURE__ */ jsx4(
508
677
  ThreadMessage,
509
678
  {
510
679
  messageIndex,
@@ -515,56 +684,42 @@ var ThreadMessages = ({ components }) => {
515
684
  });
516
685
  };
517
686
 
518
- // src/primitives/thread/ThreadScrollToBottom.tsx
519
- import { composeEventHandlers as composeEventHandlers2 } from "@radix-ui/primitive";
687
+ // src/utils/createActionButton.tsx
688
+ import { composeEventHandlers } from "@radix-ui/primitive";
520
689
  import { Primitive as Primitive3 } from "@radix-ui/react-primitive";
521
690
  import { forwardRef as forwardRef3 } from "react";
522
- import { jsx as jsx6 } from "react/jsx-runtime";
523
- var ThreadScrollToBottom = forwardRef3(({ onClick, ...rest }, ref) => {
524
- const { useViewport } = useThreadContext();
525
- const isAtBottom = useViewport((s) => s.isAtBottom);
526
- const handleScrollToBottom = () => {
527
- useViewport.getState().scrollToBottom();
528
- };
529
- return /* @__PURE__ */ jsx6(
530
- Primitive3.button,
531
- {
532
- ...rest,
533
- disabled: isAtBottom,
534
- ref,
535
- onClick: composeEventHandlers2(onClick, handleScrollToBottom)
536
- }
537
- );
538
- });
539
- ThreadScrollToBottom.displayName = "ThreadScrollToBottom";
691
+ import { jsx as jsx5 } from "react/jsx-runtime";
692
+ var createActionButton = (displayName, useActionButton) => {
693
+ const ActionButton = forwardRef3((props, forwardedRef) => {
694
+ const callback = useActionButton(props);
695
+ return /* @__PURE__ */ jsx5(
696
+ Primitive3.button,
697
+ {
698
+ type: "button",
699
+ disabled: !callback,
700
+ ...props,
701
+ ref: forwardedRef,
702
+ onClick: composeEventHandlers(props.onClick, () => {
703
+ callback?.();
704
+ })
705
+ }
706
+ );
707
+ });
708
+ ActionButton.displayName = displayName;
709
+ return ActionButton;
710
+ };
711
+
712
+ // src/primitives/thread/ThreadScrollToBottom.tsx
713
+ var ThreadScrollToBottom = createActionButton(
714
+ "ThreadScrollToBottom",
715
+ useThreadScrollToBottom
716
+ );
540
717
 
541
718
  // src/primitives/thread/ThreadSuggestion.tsx
542
- import { composeEventHandlers as composeEventHandlers3 } from "@radix-ui/primitive";
543
- import { Primitive as Primitive4 } from "@radix-ui/react-primitive";
544
- import { forwardRef as forwardRef4 } from "react";
545
- import { jsx as jsx7 } from "react/jsx-runtime";
546
- var ThreadSuggestion = forwardRef4(({ onClick, prompt, method, autoSend: send, ...rest }, ref) => {
547
- const { useThread, useComposer } = useThreadContext();
548
- const isDisabled = useThread((t) => t.isRunning);
549
- const handleApplySuggestion = () => {
550
- const thread = useThread.getState();
551
- const composer = useComposer.getState();
552
- composer.setValue(prompt);
553
- if (send && !thread.isRunning) {
554
- composer.send();
555
- }
556
- };
557
- return /* @__PURE__ */ jsx7(
558
- Primitive4.button,
559
- {
560
- ...rest,
561
- disabled: isDisabled,
562
- ref,
563
- onClick: composeEventHandlers3(onClick, handleApplySuggestion)
564
- }
565
- );
566
- });
567
- ThreadSuggestion.displayName = "ThreadSuggestion";
719
+ var ThreadSuggestion = createActionButton(
720
+ "ThreadSuggestion",
721
+ useThreadSuggestion
722
+ );
568
723
 
569
724
  // src/primitives/composer/index.ts
570
725
  var composer_exports = {};
@@ -577,33 +732,26 @@ __export(composer_exports, {
577
732
  });
578
733
 
579
734
  // src/primitives/composer/ComposerRoot.tsx
580
- import { composeEventHandlers as composeEventHandlers4 } from "@radix-ui/primitive";
581
- import { useComposedRefs as useComposedRefs2 } from "@radix-ui/react-compose-refs";
582
- import { Primitive as Primitive5 } from "@radix-ui/react-primitive";
735
+ import { composeEventHandlers as composeEventHandlers2 } from "@radix-ui/primitive";
736
+ import { Primitive as Primitive4 } from "@radix-ui/react-primitive";
583
737
  import {
584
- forwardRef as forwardRef5,
585
- useRef as useRef2
738
+ forwardRef as forwardRef4
586
739
  } from "react";
587
- import { jsx as jsx8 } from "react/jsx-runtime";
588
- var ComposerRoot = forwardRef5(
740
+ import { jsx as jsx6 } from "react/jsx-runtime";
741
+ var ComposerRoot = forwardRef4(
589
742
  ({ onSubmit, ...rest }, forwardedRef) => {
590
- const { useViewport } = useThreadContext();
591
- const { useComposer } = useComposerContext();
592
- const formRef = useRef2(null);
593
- const ref = useComposedRefs2(forwardedRef, formRef);
743
+ const send = useComposerSend();
594
744
  const handleSubmit = (e) => {
595
- const composerState = useComposer.getState();
596
- if (!composerState.isEditing) return;
745
+ if (!send) return;
597
746
  e.preventDefault();
598
- composerState.send();
599
- useViewport.getState().scrollToBottom();
747
+ send();
600
748
  };
601
- return /* @__PURE__ */ jsx8(
602
- Primitive5.form,
749
+ return /* @__PURE__ */ jsx6(
750
+ Primitive4.form,
603
751
  {
604
752
  ...rest,
605
- ref,
606
- onSubmit: composeEventHandlers4(onSubmit, handleSubmit)
753
+ ref: forwardedRef,
754
+ onSubmit: composeEventHandlers2(onSubmit, handleSubmit)
607
755
  }
608
756
  );
609
757
  }
@@ -611,18 +759,19 @@ var ComposerRoot = forwardRef5(
611
759
  ComposerRoot.displayName = "ComposerRoot";
612
760
 
613
761
  // src/primitives/composer/ComposerInput.tsx
614
- import { composeEventHandlers as composeEventHandlers5 } from "@radix-ui/primitive";
762
+ import { composeEventHandlers as composeEventHandlers3 } from "@radix-ui/primitive";
615
763
  import { useComposedRefs as useComposedRefs3 } from "@radix-ui/react-compose-refs";
616
764
  import { Slot } from "@radix-ui/react-slot";
617
765
  import {
618
- forwardRef as forwardRef6,
619
- useCallback as useCallback6,
620
- useEffect as useEffect4,
766
+ forwardRef as forwardRef5,
767
+ useCallback as useCallback12,
768
+ useEffect as useEffect3,
621
769
  useRef as useRef3
622
770
  } from "react";
623
771
  import TextareaAutosize from "react-textarea-autosize";
624
- import { jsx as jsx9 } from "react/jsx-runtime";
625
- var ComposerInput = forwardRef6(
772
+ import { useEscapeKeydown } from "@radix-ui/react-use-escape-keydown";
773
+ import { jsx as jsx7 } from "react/jsx-runtime";
774
+ var ComposerInput = forwardRef5(
626
775
  ({ autoFocus = false, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
627
776
  const { useThread } = useThreadContext();
628
777
  const { useComposer, type } = useComposerContext();
@@ -633,14 +782,15 @@ var ComposerInput = forwardRef6(
633
782
  const Component = asChild ? Slot : TextareaAutosize;
634
783
  const textareaRef = useRef3(null);
635
784
  const ref = useComposedRefs3(forwardedRef, textareaRef);
785
+ useEscapeKeydown((e) => {
786
+ const composer = useComposer.getState();
787
+ if (composer.cancel()) {
788
+ e.preventDefault();
789
+ }
790
+ });
636
791
  const handleKeyPress = (e) => {
637
792
  if (disabled) return;
638
- if (e.key === "Escape") {
639
- const composer = useComposer.getState();
640
- if (composer.cancel()) {
641
- e.preventDefault();
642
- }
643
- } else if (e.key === "Enter" && e.shiftKey === false) {
793
+ if (e.key === "Enter" && e.shiftKey === false) {
644
794
  const isRunning = useThread.getState().isRunning;
645
795
  if (!isRunning) {
646
796
  e.preventDefault();
@@ -649,23 +799,22 @@ var ComposerInput = forwardRef6(
649
799
  }
650
800
  };
651
801
  const autoFocusEnabled = autoFocus && !disabled;
652
- const focus = useCallback6(() => {
802
+ const focus = useCallback12(() => {
653
803
  const textarea = textareaRef.current;
654
804
  if (!textarea || !autoFocusEnabled) return;
655
- console.log("focus");
656
805
  textarea.focus();
657
806
  textarea.setSelectionRange(
658
807
  textareaRef.current.value.length,
659
808
  textareaRef.current.value.length
660
809
  );
661
810
  }, [autoFocusEnabled]);
662
- useEffect4(() => focus(), [focus]);
811
+ useEffect3(() => focus(), [focus]);
663
812
  useOnScrollToBottom(() => {
664
813
  if (type === "new") {
665
814
  focus();
666
815
  }
667
816
  });
668
- return /* @__PURE__ */ jsx9(
817
+ return /* @__PURE__ */ jsx7(
669
818
  Component,
670
819
  {
671
820
  value,
@@ -673,12 +822,12 @@ var ComposerInput = forwardRef6(
673
822
  ref,
674
823
  autoFocus,
675
824
  disabled,
676
- onChange: composeEventHandlers5(onChange, (e) => {
825
+ onChange: composeEventHandlers3(onChange, (e) => {
677
826
  const composerState = useComposer.getState();
678
827
  if (!composerState.isEditing) return;
679
828
  return composerState.setValue(e.target.value);
680
829
  }),
681
- onKeyDown: composeEventHandlers5(onKeyDown, handleKeyPress)
830
+ onKeyDown: composeEventHandlers3(onKeyDown, handleKeyPress)
682
831
  }
683
832
  );
684
833
  }
@@ -686,15 +835,15 @@ var ComposerInput = forwardRef6(
686
835
  ComposerInput.displayName = "ComposerInput";
687
836
 
688
837
  // src/primitives/composer/ComposerSend.tsx
689
- import { Primitive as Primitive6 } from "@radix-ui/react-primitive";
690
- import { forwardRef as forwardRef7 } from "react";
691
- import { jsx as jsx10 } from "react/jsx-runtime";
692
- var ComposerSend = forwardRef7(
838
+ import { forwardRef as forwardRef6 } from "react";
839
+ import { Primitive as Primitive5 } from "@radix-ui/react-primitive";
840
+ import { jsx as jsx8 } from "react/jsx-runtime";
841
+ var ComposerSend = forwardRef6(
693
842
  ({ disabled, ...rest }, ref) => {
694
843
  const { useComposer } = useComposerContext();
695
844
  const hasValue = useComposer((c) => c.isEditing && c.value.length > 0);
696
- return /* @__PURE__ */ jsx10(
697
- Primitive6.button,
845
+ return /* @__PURE__ */ jsx8(
846
+ Primitive5.button,
698
847
  {
699
848
  type: "submit",
700
849
  ...rest,
@@ -707,26 +856,10 @@ var ComposerSend = forwardRef7(
707
856
  ComposerSend.displayName = "ComposerSend";
708
857
 
709
858
  // src/primitives/composer/ComposerCancel.tsx
710
- import { composeEventHandlers as composeEventHandlers6 } from "@radix-ui/primitive";
711
- import { Primitive as Primitive7 } from "@radix-ui/react-primitive";
712
- import { forwardRef as forwardRef8 } from "react";
713
- import { jsx as jsx11 } from "react/jsx-runtime";
714
- var ComposerCancel = forwardRef8(({ onClick, ...rest }, ref) => {
715
- const { useComposer } = useComposerContext();
716
- const handleCancel = () => {
717
- useComposer.getState().cancel();
718
- };
719
- return /* @__PURE__ */ jsx11(
720
- Primitive7.button,
721
- {
722
- type: "button",
723
- ...rest,
724
- ref,
725
- onClick: composeEventHandlers6(onClick, handleCancel)
726
- }
727
- );
728
- });
729
- ComposerCancel.displayName = "ComposerCancel";
859
+ var ComposerCancel = createActionButton(
860
+ "ComposerCancel",
861
+ useComposerCancel
862
+ );
730
863
 
731
864
  // src/primitives/message/index.ts
732
865
  var message_exports = {};
@@ -738,11 +871,11 @@ __export(message_exports, {
738
871
  });
739
872
 
740
873
  // src/primitives/message/MessageRoot.tsx
741
- import { composeEventHandlers as composeEventHandlers7 } from "@radix-ui/primitive";
742
- import { Primitive as Primitive8 } from "@radix-ui/react-primitive";
743
- import { forwardRef as forwardRef9 } from "react";
744
- import { jsx as jsx12 } from "react/jsx-runtime";
745
- var MessageRoot = forwardRef9(
874
+ import { composeEventHandlers as composeEventHandlers4 } from "@radix-ui/primitive";
875
+ import { Primitive as Primitive6 } from "@radix-ui/react-primitive";
876
+ import { forwardRef as forwardRef7 } from "react";
877
+ import { jsx as jsx9 } from "react/jsx-runtime";
878
+ var MessageRoot = forwardRef7(
746
879
  ({ onMouseEnter, onMouseLeave, ...rest }, ref) => {
747
880
  const { useMessageUtils } = useMessageContext();
748
881
  const setIsHovering = useMessageUtils((s) => s.setIsHovering);
@@ -752,13 +885,13 @@ var MessageRoot = forwardRef9(
752
885
  const handleMouseLeave = () => {
753
886
  setIsHovering(false);
754
887
  };
755
- return /* @__PURE__ */ jsx12(
756
- Primitive8.div,
888
+ return /* @__PURE__ */ jsx9(
889
+ Primitive6.div,
757
890
  {
758
891
  ...rest,
759
892
  ref,
760
- onMouseEnter: composeEventHandlers7(onMouseEnter, handleMouseEnter),
761
- onMouseLeave: composeEventHandlers7(onMouseLeave, handleMouseLeave)
893
+ onMouseEnter: composeEventHandlers4(onMouseEnter, handleMouseEnter),
894
+ onMouseLeave: composeEventHandlers4(onMouseLeave, handleMouseLeave)
762
895
  }
763
896
  );
764
897
  }
@@ -769,9 +902,9 @@ MessageRoot.displayName = "MessageRoot";
769
902
  import { memo as memo2 } from "react";
770
903
 
771
904
  // src/context/providers/ContentPartProvider.tsx
772
- import { useEffect as useEffect5, useState as useState2 } from "react";
905
+ import { useEffect as useEffect4, useState as useState2 } from "react";
773
906
  import { create as create4 } from "zustand";
774
- import { jsx as jsx13 } from "react/jsx-runtime";
907
+ import { jsx as jsx10 } from "react/jsx-runtime";
775
908
  var syncContentPart = ({ message }, useContentPart, partIndex) => {
776
909
  const part = message.content[partIndex];
777
910
  if (!part) return;
@@ -795,7 +928,7 @@ var useContentPartContext2 = (partIndex) => {
795
928
  syncContentPart(useMessage.getState(), useContentPart, partIndex);
796
929
  return { useContentPart };
797
930
  });
798
- useEffect5(() => {
931
+ useEffect4(() => {
799
932
  syncContentPart(useMessage.getState(), context.useContentPart, partIndex);
800
933
  return useMessage.subscribe((message) => {
801
934
  syncContentPart(message, context.useContentPart, partIndex);
@@ -808,65 +941,46 @@ var ContentPartProvider = ({
808
941
  children
809
942
  }) => {
810
943
  const context = useContentPartContext2(partIndex);
811
- return /* @__PURE__ */ jsx13(ContentPartContext.Provider, { value: context, children });
944
+ return /* @__PURE__ */ jsx10(ContentPartContext.Provider, { value: context, children });
812
945
  };
813
946
 
814
947
  // src/primitives/contentPart/ContentPartDisplay.tsx
815
948
  var ContentPartDisplay = () => {
816
- const { useContentPart } = useContentPartContext();
817
- const display = useContentPart((c) => {
818
- if (c.part.type !== "ui")
819
- throw new Error(
820
- "ContentPartDisplay can only be used inside ui content parts."
821
- );
822
- return c.part.display;
823
- });
949
+ const display = useContentPartDisplay();
824
950
  return display ?? null;
825
951
  };
826
952
 
827
953
  // src/primitives/contentPart/ContentPartInProgressIndicator.tsx
828
954
  var ContentPartInProgressIndicator = () => {
829
- const { useMessageUtils } = useMessageContext();
830
- const { useContentPart } = useContentPartContext();
831
- const indicator = useCombinedStore(
832
- [useMessageUtils, useContentPart],
833
- (m, c) => c.status === "in_progress" ? m.inProgressIndicator : null
834
- );
955
+ const indicator = useContentPartInProgressIndicator();
835
956
  return indicator;
836
957
  };
837
958
 
838
959
  // src/primitives/contentPart/ContentPartText.tsx
839
- import { Primitive as Primitive9 } from "@radix-ui/react-primitive";
840
- import { forwardRef as forwardRef10 } from "react";
841
- import { jsx as jsx14 } from "react/jsx-runtime";
842
- var ContentPartText = forwardRef10((props, forwardedRef) => {
843
- const { useContentPart } = useContentPartContext();
844
- const text = useContentPart((c) => {
845
- if (c.part.type !== "text")
846
- throw new Error(
847
- "ContentPartText can only be used inside text content parts."
848
- );
849
- return c.part.text;
850
- });
851
- return /* @__PURE__ */ jsx14(Primitive9.span, { ...props, ref: forwardedRef, children: text });
960
+ import { Primitive as Primitive7 } from "@radix-ui/react-primitive";
961
+ import { forwardRef as forwardRef8 } from "react";
962
+ import { jsx as jsx11 } from "react/jsx-runtime";
963
+ var ContentPartText = forwardRef8((props, forwardedRef) => {
964
+ const text = useContentPartText();
965
+ return /* @__PURE__ */ jsx11(Primitive7.span, { ...props, ref: forwardedRef, children: text });
852
966
  });
853
967
  ContentPartText.displayName = "ContentPartText";
854
968
 
855
969
  // src/primitives/message/MessageContent.tsx
856
- import { Fragment, jsx as jsx15, jsxs as jsxs3 } from "react/jsx-runtime";
970
+ import { Fragment, jsx as jsx12, jsxs as jsxs2 } from "react/jsx-runtime";
857
971
  var defaultComponents = {
858
- Text: () => /* @__PURE__ */ jsxs3(Fragment, { children: [
859
- /* @__PURE__ */ jsx15(ContentPartText, {}),
860
- /* @__PURE__ */ jsx15(ContentPartInProgressIndicator, {})
972
+ Text: () => /* @__PURE__ */ jsxs2(Fragment, { children: [
973
+ /* @__PURE__ */ jsx12(ContentPartText, {}),
974
+ /* @__PURE__ */ jsx12(ContentPartInProgressIndicator, {})
861
975
  ] }),
862
976
  Image: () => null,
863
- UI: () => /* @__PURE__ */ jsx15(ContentPartDisplay, {}),
977
+ UI: () => /* @__PURE__ */ jsx12(ContentPartDisplay, {}),
864
978
  tools: {
865
979
  Fallback: (props) => {
866
980
  const { useToolUIs } = useAssistantContext();
867
981
  const Render = useToolUIs((s) => s.getToolUI(props.part.toolName));
868
982
  if (!Render) return null;
869
- return /* @__PURE__ */ jsx15(Render, { ...props });
983
+ return /* @__PURE__ */ jsx12(Render, { ...props });
870
984
  }
871
985
  }
872
986
  };
@@ -885,15 +999,15 @@ var MessageContentPartComponent = ({
885
999
  const type = part.type;
886
1000
  switch (type) {
887
1001
  case "text":
888
- return /* @__PURE__ */ jsx15(Text, { part, status });
1002
+ return /* @__PURE__ */ jsx12(Text, { part, status });
889
1003
  case "image":
890
- return /* @__PURE__ */ jsx15(Image, { part, status });
1004
+ return /* @__PURE__ */ jsx12(Image, { part, status });
891
1005
  case "ui":
892
- return /* @__PURE__ */ jsx15(UI, { part, status });
1006
+ return /* @__PURE__ */ jsx12(UI, { part, status });
893
1007
  case "tool-call": {
894
1008
  const Tool = by_name[part.toolName] || Fallback;
895
1009
  const addResult = (result) => addToolResult(part.toolCallId, result);
896
- return /* @__PURE__ */ jsx15(Tool, { part, status, addResult });
1010
+ return /* @__PURE__ */ jsx12(Tool, { part, status, addResult });
897
1011
  }
898
1012
  default:
899
1013
  throw new Error(`Unknown content part type: ${type}`);
@@ -903,7 +1017,7 @@ var MessageContentPartImpl = ({
903
1017
  partIndex,
904
1018
  components
905
1019
  }) => {
906
- return /* @__PURE__ */ jsx15(ContentPartProvider, { partIndex, children: /* @__PURE__ */ jsx15(MessageContentPartComponent, { components }) });
1020
+ return /* @__PURE__ */ jsx12(ContentPartProvider, { partIndex, children: /* @__PURE__ */ jsx12(MessageContentPartComponent, { components }) });
907
1021
  };
908
1022
  var MessageContentPart = memo2(
909
1023
  MessageContentPartImpl,
@@ -914,7 +1028,7 @@ var MessageContent = ({ components }) => {
914
1028
  const contentLength = useMessage((s) => s.message.content.length);
915
1029
  return new Array(contentLength).fill(null).map((_, idx) => {
916
1030
  const partIndex = idx;
917
- return /* @__PURE__ */ jsx15(
1031
+ return /* @__PURE__ */ jsx12(
918
1032
  MessageContentPart,
919
1033
  {
920
1034
  partIndex,
@@ -926,16 +1040,16 @@ var MessageContent = ({ components }) => {
926
1040
  };
927
1041
 
928
1042
  // src/primitives/message/MessageInProgress.tsx
929
- import { Primitive as Primitive10 } from "@radix-ui/react-primitive";
1043
+ import { Primitive as Primitive8 } from "@radix-ui/react-primitive";
930
1044
  import {
931
- forwardRef as forwardRef11,
1045
+ forwardRef as forwardRef9,
932
1046
  useMemo as useMemo2
933
1047
  } from "react";
934
- import { jsx as jsx16 } from "react/jsx-runtime";
935
- var MessageInProgress = forwardRef11((props, ref) => {
1048
+ import { jsx as jsx13 } from "react/jsx-runtime";
1049
+ var MessageInProgress = forwardRef9((props, ref) => {
936
1050
  const { useMessageUtils } = useMessageContext();
937
1051
  useMemo2(() => {
938
- useMessageUtils.getState().setInProgressIndicator(/* @__PURE__ */ jsx16(Primitive10.span, { ...props, ref }));
1052
+ useMessageUtils.getState().setInProgressIndicator(/* @__PURE__ */ jsx13(Primitive8.span, { ...props, ref }));
939
1053
  }, [useMessageUtils, props, ref]);
940
1054
  return null;
941
1055
  });
@@ -951,57 +1065,38 @@ __export(branchPicker_exports, {
951
1065
  Root: () => BranchPickerRoot
952
1066
  });
953
1067
 
954
- // src/utils/createActionButton.tsx
955
- import { composeEventHandlers as composeEventHandlers8 } from "@radix-ui/primitive";
956
- import { Primitive as Primitive11 } from "@radix-ui/react-primitive";
957
- import { forwardRef as forwardRef12 } from "react";
958
- import { jsx as jsx17 } from "react/jsx-runtime";
959
- var createActionButton = (useActionButton) => {
960
- const ActionButton = forwardRef12((props, forwardedRef) => {
961
- const onClick = useActionButton(props);
962
- return /* @__PURE__ */ jsx17(
963
- Primitive11.button,
964
- {
965
- type: "button",
966
- disabled: !onClick,
967
- ...props,
968
- ref: forwardedRef,
969
- onClick: composeEventHandlers8(props.onClick, onClick ?? void 0)
970
- }
971
- );
972
- });
973
- ActionButton.displayName = "ActionButton";
974
- return ActionButton;
975
- };
976
-
977
1068
  // src/primitives/branchPicker/BranchPickerNext.tsx
978
- var BranchPickerNext = createActionButton(useGoToNextBranch);
1069
+ var BranchPickerNext = createActionButton(
1070
+ "BranchPickerNext",
1071
+ useBranchPickerNext
1072
+ );
979
1073
 
980
1074
  // src/primitives/branchPicker/BranchPickerPrevious.tsx
981
- var BranchPickerPrevious = createActionButton(useGoToPreviousBranch);
1075
+ var BranchPickerPrevious = createActionButton(
1076
+ "BranchPickerPrevious",
1077
+ useBranchPickerPrevious
1078
+ );
982
1079
 
983
1080
  // src/primitives/branchPicker/BranchPickerCount.tsx
984
- import { Fragment as Fragment2, jsx as jsx18 } from "react/jsx-runtime";
1081
+ import { Fragment as Fragment2, jsx as jsx14 } from "react/jsx-runtime";
985
1082
  var BranchPickerCount = () => {
986
- const { useMessage } = useMessageContext();
987
- const branchCount = useMessage((s) => s.branches.length);
988
- return /* @__PURE__ */ jsx18(Fragment2, { children: branchCount });
1083
+ const branchCount = useBranchPickerCount();
1084
+ return /* @__PURE__ */ jsx14(Fragment2, { children: branchCount });
989
1085
  };
990
1086
 
991
1087
  // src/primitives/branchPicker/BranchPickerNumber.tsx
992
- import { Fragment as Fragment3, jsx as jsx19 } from "react/jsx-runtime";
1088
+ import { Fragment as Fragment3, jsx as jsx15 } from "react/jsx-runtime";
993
1089
  var BranchPickerNumber = () => {
994
- const { useMessage } = useMessageContext();
995
- const branchIdx = useMessage((s) => s.branches.indexOf(s.message.id));
996
- return /* @__PURE__ */ jsx19(Fragment3, { children: branchIdx + 1 });
1090
+ const branchNumber = useBranchPickerNumber();
1091
+ return /* @__PURE__ */ jsx15(Fragment3, { children: branchNumber });
997
1092
  };
998
1093
 
999
1094
  // src/primitives/branchPicker/BranchPickerRoot.tsx
1000
- import { Primitive as Primitive12 } from "@radix-ui/react-primitive";
1001
- import { forwardRef as forwardRef13 } from "react";
1002
- import { jsx as jsx20 } from "react/jsx-runtime";
1003
- var BranchPickerRoot = forwardRef13(({ hideWhenSingleBranch, ...rest }, ref) => {
1004
- return /* @__PURE__ */ jsx20(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0, children: /* @__PURE__ */ jsx20(Primitive12.div, { ...rest, ref }) });
1095
+ import { Primitive as Primitive9 } from "@radix-ui/react-primitive";
1096
+ import { forwardRef as forwardRef10 } from "react";
1097
+ import { jsx as jsx16 } from "react/jsx-runtime";
1098
+ var BranchPickerRoot = forwardRef10(({ hideWhenSingleBranch, ...rest }, ref) => {
1099
+ return /* @__PURE__ */ jsx16(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0, children: /* @__PURE__ */ jsx16(Primitive9.div, { ...rest, ref }) });
1005
1100
  });
1006
1101
  BranchPickerRoot.displayName = "BranchPickerRoot";
1007
1102
 
@@ -1015,13 +1110,17 @@ __export(actionBar_exports, {
1015
1110
  });
1016
1111
 
1017
1112
  // src/primitives/actionBar/ActionBarRoot.tsx
1018
- import { Primitive as Primitive13 } from "@radix-ui/react-primitive";
1019
- import { forwardRef as forwardRef14 } from "react";
1020
- import { jsx as jsx21 } from "react/jsx-runtime";
1021
- var ActionBarRoot = forwardRef14(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
1113
+ import { Primitive as Primitive10 } from "@radix-ui/react-primitive";
1114
+ import { forwardRef as forwardRef11 } from "react";
1115
+ import { jsx as jsx17 } from "react/jsx-runtime";
1116
+ var useActionBarFloatStatus = ({
1117
+ hideWhenRunning,
1118
+ autohide,
1119
+ autohideFloat
1120
+ }) => {
1022
1121
  const { useThread } = useThreadContext();
1023
1122
  const { useMessage, useMessageUtils } = useMessageContext();
1024
- const hideAndfloatStatus = useCombinedStore(
1123
+ return useCombinedStore(
1025
1124
  [useThread, useMessage, useMessageUtils],
1026
1125
  (t, m, mu) => {
1027
1126
  if (hideWhenRunning && t.isRunning) return "hidden" /* Hidden */;
@@ -1033,9 +1132,16 @@ var ActionBarRoot = forwardRef14(({ hideWhenRunning, autohide, autohideFloat, ..
1033
1132
  return "normal" /* Normal */;
1034
1133
  }
1035
1134
  );
1135
+ };
1136
+ var ActionBarRoot = forwardRef11(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
1137
+ const hideAndfloatStatus = useActionBarFloatStatus({
1138
+ hideWhenRunning,
1139
+ autohide,
1140
+ autohideFloat
1141
+ });
1036
1142
  if (hideAndfloatStatus === "hidden" /* Hidden */) return null;
1037
- return /* @__PURE__ */ jsx21(
1038
- Primitive13.div,
1143
+ return /* @__PURE__ */ jsx17(
1144
+ Primitive10.div,
1039
1145
  {
1040
1146
  ...hideAndfloatStatus === "floating" /* Floating */ ? { "data-floating": "true" } : null,
1041
1147
  ...rest,
@@ -1046,13 +1152,22 @@ var ActionBarRoot = forwardRef14(({ hideWhenRunning, autohide, autohideFloat, ..
1046
1152
  ActionBarRoot.displayName = "ActionBarRoot";
1047
1153
 
1048
1154
  // src/primitives/actionBar/ActionBarCopy.tsx
1049
- var ActionBarCopy = createActionButton(useCopyMessage);
1155
+ var ActionBarCopy = createActionButton(
1156
+ "ActionBarCopy",
1157
+ useActionBarCopy
1158
+ );
1050
1159
 
1051
1160
  // src/primitives/actionBar/ActionBarReload.tsx
1052
- var ActionBarReload = createActionButton(useReloadMessage);
1161
+ var ActionBarReload = createActionButton(
1162
+ "ActionBarReload",
1163
+ useActionBarReload
1164
+ );
1053
1165
 
1054
1166
  // src/primitives/actionBar/ActionBarEdit.tsx
1055
- var ActionBarEdit = createActionButton(useBeginMessageEdit);
1167
+ var ActionBarEdit = createActionButton(
1168
+ "ActionBarEdit",
1169
+ useActionBarEdit
1170
+ );
1056
1171
 
1057
1172
  // src/primitives/contentPart/index.ts
1058
1173
  var contentPart_exports = {};
@@ -1064,19 +1179,12 @@ __export(contentPart_exports, {
1064
1179
  });
1065
1180
 
1066
1181
  // src/primitives/contentPart/ContentPartImage.tsx
1067
- import { Primitive as Primitive14 } from "@radix-ui/react-primitive";
1068
- import { forwardRef as forwardRef15 } from "react";
1069
- import { jsx as jsx22 } from "react/jsx-runtime";
1070
- var ContentPartImage = forwardRef15((props, forwardedRef) => {
1071
- const { useContentPart } = useContentPartContext();
1072
- const image = useContentPart((c) => {
1073
- if (c.part.type !== "image")
1074
- throw new Error(
1075
- "ContentPartImage can only be used inside image content parts."
1076
- );
1077
- return c.part.image;
1078
- });
1079
- return /* @__PURE__ */ jsx22(Primitive14.img, { src: image, ...props, ref: forwardedRef });
1182
+ import { Primitive as Primitive11 } from "@radix-ui/react-primitive";
1183
+ import { forwardRef as forwardRef12 } from "react";
1184
+ import { jsx as jsx18 } from "react/jsx-runtime";
1185
+ var ContentPartImage = forwardRef12((props, forwardedRef) => {
1186
+ const image = useContentPartImage();
1187
+ return /* @__PURE__ */ jsx18(Primitive11.img, { src: image, ...props, ref: forwardedRef });
1080
1188
  });
1081
1189
  ContentPartImage.displayName = "ContentPartImage";
1082
1190
 
@@ -1378,7 +1486,7 @@ var useLocalRuntime = (adapter) => {
1378
1486
  import { memo as memo3 } from "react";
1379
1487
 
1380
1488
  // src/context/providers/AssistantProvider.tsx
1381
- import { useEffect as useEffect7, useInsertionEffect as useInsertionEffect3, useRef as useRef5, useState as useState5 } from "react";
1489
+ import { useEffect as useEffect6, useInsertionEffect as useInsertionEffect3, useRef as useRef5, useState as useState5 } from "react";
1382
1490
 
1383
1491
  // src/context/stores/AssistantModelConfig.ts
1384
1492
  import { create as create5 } from "zustand";
@@ -1443,7 +1551,7 @@ var makeAssistantToolUIsStore = () => create6((set) => {
1443
1551
  });
1444
1552
 
1445
1553
  // src/context/providers/ThreadProvider.tsx
1446
- import { useEffect as useEffect6, useInsertionEffect as useInsertionEffect2, useRef as useRef4, useState as useState4 } from "react";
1554
+ import { useEffect as useEffect5, useInsertionEffect as useInsertionEffect2, useRef as useRef4, useState as useState4 } from "react";
1447
1555
 
1448
1556
  // src/context/stores/Composer.ts
1449
1557
  import { create as create7 } from "zustand";
@@ -1456,6 +1564,7 @@ var makeComposerStore = (useThread, useThreadActions) => create7()((set, get, st
1456
1564
  setValue("");
1457
1565
  useThreadActions.getState().append({
1458
1566
  parentId: useThread.getState().messages.at(-1)?.id ?? null,
1567
+ role: "user",
1459
1568
  content: [{ type: "text", text: value }]
1460
1569
  });
1461
1570
  },
@@ -1513,7 +1622,7 @@ var makeThreadActionStore = (runtimeRef) => {
1513
1622
  };
1514
1623
 
1515
1624
  // src/context/providers/ThreadProvider.tsx
1516
- import { jsx as jsx23, jsxs as jsxs4 } from "react/jsx-runtime";
1625
+ import { jsx as jsx19, jsxs as jsxs3 } from "react/jsx-runtime";
1517
1626
  var ThreadProvider = ({
1518
1627
  children,
1519
1628
  runtime
@@ -1534,7 +1643,7 @@ var ThreadProvider = ({
1534
1643
  useViewport
1535
1644
  };
1536
1645
  });
1537
- useEffect6(() => {
1646
+ useEffect5(() => {
1538
1647
  const onRuntimeUpdate = () => {
1539
1648
  context.useThread.setState(
1540
1649
  Object.freeze({
@@ -1548,14 +1657,14 @@ var ThreadProvider = ({
1548
1657
  return runtime.subscribe(onRuntimeUpdate);
1549
1658
  }, [context, runtime]);
1550
1659
  const RuntimeSynchronizer = runtime.unstable_synchronizer;
1551
- return /* @__PURE__ */ jsxs4(ThreadContext.Provider, { value: context, children: [
1552
- RuntimeSynchronizer && /* @__PURE__ */ jsx23(RuntimeSynchronizer, {}),
1660
+ return /* @__PURE__ */ jsxs3(ThreadContext.Provider, { value: context, children: [
1661
+ RuntimeSynchronizer && /* @__PURE__ */ jsx19(RuntimeSynchronizer, {}),
1553
1662
  children
1554
1663
  ] });
1555
1664
  };
1556
1665
 
1557
1666
  // src/context/providers/AssistantProvider.tsx
1558
- import { jsx as jsx24 } from "react/jsx-runtime";
1667
+ import { jsx as jsx20 } from "react/jsx-runtime";
1559
1668
  var AssistantProvider = ({ children, runtime }) => {
1560
1669
  const runtimeRef = useRef5(runtime);
1561
1670
  useInsertionEffect3(() => {
@@ -1567,16 +1676,16 @@ var AssistantProvider = ({ children, runtime }) => {
1567
1676
  return { useModelConfig, useToolUIs };
1568
1677
  });
1569
1678
  const getModelCOnfig = context.useModelConfig((c) => c.getModelConfig);
1570
- useEffect7(() => {
1679
+ useEffect6(() => {
1571
1680
  return runtime.registerModelConfigProvider(getModelCOnfig);
1572
1681
  }, [runtime, getModelCOnfig]);
1573
- return /* @__PURE__ */ jsx24(AssistantContext.Provider, { value: context, children: /* @__PURE__ */ jsx24(ThreadProvider, { runtime, children }) });
1682
+ return /* @__PURE__ */ jsx20(AssistantContext.Provider, { value: context, children: /* @__PURE__ */ jsx20(ThreadProvider, { runtime, children }) });
1574
1683
  };
1575
1684
 
1576
1685
  // src/context/providers/AssistantRuntimeProvider.tsx
1577
- import { jsx as jsx25 } from "react/jsx-runtime";
1686
+ import { jsx as jsx21 } from "react/jsx-runtime";
1578
1687
  var AssistantRuntimeProviderImpl = ({ children, runtime }) => {
1579
- return /* @__PURE__ */ jsx25(AssistantProvider, { runtime, children });
1688
+ return /* @__PURE__ */ jsx21(AssistantProvider, { runtime, children });
1580
1689
  };
1581
1690
  var AssistantRuntimeProvider = memo3(AssistantRuntimeProviderImpl);
1582
1691
 
@@ -1595,11 +1704,25 @@ export {
1595
1704
  internal_exports as INTERNAL,
1596
1705
  message_exports as MessagePrimitive,
1597
1706
  thread_exports as ThreadPrimitive,
1598
- useBeginMessageEdit,
1599
- useCopyMessage,
1600
- useGoToNextBranch,
1601
- useGoToPreviousBranch,
1707
+ useActionBarCopy,
1708
+ useActionBarEdit,
1709
+ useActionBarReload,
1710
+ useBranchPickerCount,
1711
+ useBranchPickerNext,
1712
+ useBranchPickerNumber,
1713
+ useBranchPickerPrevious,
1714
+ useComposerCancel,
1715
+ useComposerIf,
1716
+ useComposerSend,
1717
+ useContentPartDisplay,
1718
+ useContentPartImage,
1719
+ useContentPartInProgressIndicator,
1720
+ useContentPartText,
1602
1721
  useLocalRuntime,
1603
- useReloadMessage
1722
+ useMessageIf,
1723
+ useThreadEmpty,
1724
+ useThreadIf,
1725
+ useThreadScrollToBottom,
1726
+ useThreadSuggestion
1604
1727
  };
1605
1728
  //# sourceMappingURL=index.mjs.map