@assistant-ui/react 0.1.8 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -9,9 +9,9 @@ import {
9
9
  useContentPartContext,
10
10
  useMessageContext,
11
11
  useThreadContext
12
- } from "./chunk-RITM2IUH.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,91 +48,261 @@ 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, 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
- const { isEditing, value: composerValue } = useComposer.getState();
62
- const { message, setIsCopied } = useMessage.getState();
63
+ const { message } = useMessage.getState();
64
+ const { setIsCopied } = useMessageUtils.getState();
65
+ const { isEditing, value: composerValue } = useEditComposer.getState();
63
66
  const valueToCopy = isEditing ? composerValue : getMessageText(message);
64
67
  navigator.clipboard.writeText(valueToCopy);
65
68
  setIsCopied(true);
66
69
  setTimeout(() => setIsCopied(false), copiedDuration);
67
- }, [useComposer, useMessage, copiedDuration]);
70
+ }, [useMessage, useMessageUtils, useEditComposer, copiedDuration]);
68
71
  if (!hasCopyableContent) return null;
69
72
  return callback;
70
73
  };
71
74
 
72
- // src/actions/useReloadMessage.tsx
75
+ // src/primitive-hooks/actionBar/useActionBarEdit.tsx
73
76
  import { useCallback as useCallback2 } from "react";
74
- var useReloadMessage = () => {
75
- const { useThread, useViewport } = useThreadContext();
76
- const { useMessage } = useMessageContext();
77
+ var useActionBarEdit = () => {
78
+ const { useMessage, useEditComposer } = useMessageContext();
77
79
  const disabled = useCombinedStore(
78
- [useThread, useMessage],
79
- (t, m) => t.isRunning || m.message.role !== "assistant"
80
+ [useMessage, useEditComposer],
81
+ (m, c) => m.message.role !== "user" || c.isEditing
80
82
  );
81
83
  const callback = useCallback2(() => {
82
- const { parentId } = useMessage.getState();
83
- useThread.getState().startRun(parentId);
84
- useViewport.getState().scrollToBottom();
85
- }, [useMessage, useThread, useViewport]);
84
+ const { edit } = useEditComposer.getState();
85
+ edit();
86
+ }, [useEditComposer]);
86
87
  if (disabled) return null;
87
88
  return callback;
88
89
  };
89
90
 
90
- // src/actions/useBeginMessageEdit.tsx
91
+ // src/primitive-hooks/actionBar/useActionBarReload.tsx
91
92
  import { useCallback as useCallback3 } from "react";
92
- var useBeginMessageEdit = () => {
93
- const { useMessage, useComposer } = useMessageContext();
93
+ var useActionBarReload = () => {
94
+ const { useThread, useThreadActions, useViewport } = useThreadContext();
95
+ const { useMessage } = useMessageContext();
94
96
  const disabled = useCombinedStore(
95
- [useMessage, useComposer],
96
- (m, c) => m.message.role !== "user" || c.isEditing
97
+ [useThread, useMessage],
98
+ (t, m) => t.isRunning || m.message.role !== "assistant"
97
99
  );
98
100
  const callback = useCallback3(() => {
99
- const { edit } = useComposer.getState();
100
- edit();
101
- }, [useComposer]);
101
+ const { parentId } = useMessage.getState();
102
+ useThreadActions.getState().startRun(parentId);
103
+ useViewport.getState().scrollToBottom();
104
+ }, [useThreadActions, useMessage, useViewport]);
102
105
  if (disabled) return null;
103
106
  return callback;
104
107
  };
105
108
 
106
- // src/actions/useGoToNextBranch.tsx
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;
114
+ };
115
+
116
+ // src/primitive-hooks/branchPicker/useBranchPickerNext.tsx
107
117
  import { useCallback as useCallback4 } from "react";
108
- var useGoToNextBranch = () => {
109
- const { useThread } = useThreadContext();
110
- const { useMessage, useComposer } = useMessageContext();
118
+ var useBranchPickerNext = () => {
119
+ const { useThreadActions } = useThreadContext();
120
+ const { useMessage, useEditComposer } = useMessageContext();
111
121
  const disabled = useCombinedStore(
112
- [useMessage, useComposer],
122
+ [useMessage, useEditComposer],
113
123
  (m, c) => c.isEditing || m.branches.indexOf(m.message.id) + 1 >= m.branches.length
114
124
  );
115
125
  const callback = useCallback4(() => {
116
126
  const { message, branches } = useMessage.getState();
117
- useThread.getState().switchToBranch(branches[branches.indexOf(message.id) + 1]);
118
- }, [useMessage, useThread]);
127
+ useThreadActions.getState().switchToBranch(branches[branches.indexOf(message.id) + 1]);
128
+ }, [useThreadActions, useMessage]);
119
129
  if (disabled) return null;
120
130
  return callback;
121
131
  };
122
132
 
123
- // 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
124
141
  import { useCallback as useCallback5 } from "react";
125
- var useGoToPreviousBranch = () => {
126
- const { useThread } = useThreadContext();
127
- const { useMessage, useComposer } = useMessageContext();
142
+ var useBranchPickerPrevious = () => {
143
+ const { useThreadActions } = useThreadContext();
144
+ const { useMessage, useEditComposer } = useMessageContext();
128
145
  const disabled = useCombinedStore(
129
- [useMessage, useComposer],
146
+ [useMessage, useEditComposer],
130
147
  (m, c) => c.isEditing || m.branches.indexOf(m.message.id) <= 0
131
148
  );
132
149
  const callback = useCallback5(() => {
133
150
  const { message, branches } = useMessage.getState();
134
- useThread.getState().switchToBranch(branches[branches.indexOf(message.id) - 1]);
135
- }, [useMessage, useThread]);
151
+ useThreadActions.getState().switchToBranch(branches[branches.indexOf(message.id) - 1]);
152
+ }, [useThreadActions, useMessage]);
153
+ if (disabled) return null;
154
+ return callback;
155
+ };
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 { useComposer } = useComposerContext();
184
+ const disabled = useComposer((c) => !c.isEditing || c.value.length === 0);
185
+ const callback = useCallback7(() => {
186
+ const { send } = useComposer.getState();
187
+ send();
188
+ }, [useComposer]);
189
+ if (disabled) return null;
190
+ return callback;
191
+ };
192
+
193
+ // src/primitive-hooks/contentPart/useContentPartDisplay.tsx
194
+ var useContentPartDisplay = () => {
195
+ const { useContentPart } = useContentPartContext();
196
+ const display = useContentPart((c) => {
197
+ if (c.part.type !== "ui")
198
+ throw new Error(
199
+ "This component can only be used inside ui content parts."
200
+ );
201
+ return c.part.display;
202
+ });
203
+ return display;
204
+ };
205
+
206
+ // src/primitive-hooks/contentPart/useContentPartImage.tsx
207
+ var useContentPartImage = () => {
208
+ const { useContentPart } = useContentPartContext();
209
+ const image = useContentPart((c) => {
210
+ if (c.part.type !== "image")
211
+ throw new Error(
212
+ "ContentPartImage can only be used inside image content parts."
213
+ );
214
+ return c.part.image;
215
+ });
216
+ return image;
217
+ };
218
+
219
+ // src/primitive-hooks/contentPart/useContentPartInProgressIndicator.tsx
220
+ var useContentPartInProgressIndicator = () => {
221
+ const { useMessageUtils } = useMessageContext();
222
+ const { useContentPart } = useContentPartContext();
223
+ const indicator = useCombinedStore(
224
+ [useMessageUtils, useContentPart],
225
+ (m, c) => c.status === "in_progress" ? m.inProgressIndicator : null
226
+ );
227
+ return indicator;
228
+ };
229
+
230
+ // src/primitive-hooks/contentPart/useContentPartText.tsx
231
+ var useContentPartText = () => {
232
+ const { useContentPart } = useContentPartContext();
233
+ const text = useContentPart((c) => {
234
+ if (c.part.type !== "text")
235
+ throw new Error(
236
+ "ContentPartText can only be used inside text content parts."
237
+ );
238
+ return c.part.text;
239
+ });
240
+ return text;
241
+ };
242
+
243
+ // src/primitive-hooks/message/useMessageIf.tsx
244
+ var useMessageIf = (props) => {
245
+ const { useMessage, useMessageUtils } = useMessageContext();
246
+ return useCombinedStore(
247
+ [useMessage, useMessageUtils],
248
+ ({ message, branches, isLast }, { isCopied, isHovering }) => {
249
+ if (props.hasBranches === true && branches.length < 2) return false;
250
+ if (props.user && message.role !== "user") return false;
251
+ if (props.assistant && message.role !== "assistant") return false;
252
+ if (props.lastOrHover === true && !isHovering && !isLast) return false;
253
+ if (props.copied === true && !isCopied) return false;
254
+ if (props.copied === false && isCopied) return false;
255
+ return true;
256
+ }
257
+ );
258
+ };
259
+
260
+ // src/primitive-hooks/thread/useThreadIf.tsx
261
+ var useThreadIf = (props) => {
262
+ const { useThread } = useThreadContext();
263
+ return useThread((thread) => {
264
+ if (props.empty === true && thread.messages.length !== 0) return false;
265
+ if (props.empty === false && thread.messages.length === 0) return false;
266
+ if (props.running === true && !thread.isRunning) return false;
267
+ if (props.running === false && thread.isRunning) return false;
268
+ return true;
269
+ });
270
+ };
271
+
272
+ // src/primitive-hooks/thread/useThreadEmpty.tsx
273
+ var useThreadEmpty = () => {
274
+ return useThreadIf({ empty: true });
275
+ };
276
+
277
+ // src/primitive-hooks/thread/useThreadScrollToBottom.tsx
278
+ import { useCallback as useCallback8 } from "react";
279
+ var useThreadScrollToBottom = () => {
280
+ const { useViewport } = useThreadContext();
281
+ const isAtBottom = useViewport((s) => s.isAtBottom);
282
+ const handleScrollToBottom = useCallback8(() => {
283
+ const { scrollToBottom } = useViewport.getState();
284
+ scrollToBottom();
285
+ }, [useViewport]);
286
+ if (isAtBottom) return null;
287
+ return handleScrollToBottom;
288
+ };
289
+
290
+ // src/primitive-hooks/thread/useThreadSuggestion.tsx
291
+ import { useCallback as useCallback9 } from "react";
292
+ var useThreadSuggestion = ({
293
+ prompt,
294
+ autoSend
295
+ }) => {
296
+ const { useThread, useComposer } = useThreadContext();
297
+ const disabled = useThread((t) => t.isRunning);
298
+ const callback = useCallback9(() => {
299
+ const thread = useThread.getState();
300
+ const composer = useComposer.getState();
301
+ composer.setValue(prompt);
302
+ if (autoSend && !thread.isRunning) {
303
+ composer.send();
304
+ }
305
+ }, [useThread, useComposer, prompt, autoSend]);
136
306
  if (disabled) return null;
137
307
  return callback;
138
308
  };
@@ -161,16 +331,6 @@ var ThreadRoot = forwardRef(
161
331
  ThreadRoot.displayName = "ThreadRoot";
162
332
 
163
333
  // src/primitives/thread/ThreadIf.tsx
164
- var useThreadIf = (props) => {
165
- const { useThread } = useThreadContext();
166
- return useThread((thread) => {
167
- if (props.empty === true && thread.messages.length !== 0) return false;
168
- if (props.empty === false && thread.messages.length === 0) return false;
169
- if (props.running === true && !thread.isRunning) return false;
170
- if (props.running === false && thread.isRunning) return false;
171
- return true;
172
- });
173
- };
174
334
  var ThreadIf = ({ children, ...query }) => {
175
335
  const result = useThreadIf(query);
176
336
  return result ? children : null;
@@ -196,8 +356,8 @@ import { useCallbackRef } from "@radix-ui/react-use-callback-ref";
196
356
  import { useEffect } from "react";
197
357
  var useOnResizeContent = (ref, callback) => {
198
358
  const callbackRef = useCallbackRef(callback);
199
- const el = ref.current;
200
359
  useEffect(() => {
360
+ const el = ref.current;
201
361
  if (!el) return;
202
362
  const resizeObserver = new ResizeObserver(() => {
203
363
  callbackRef();
@@ -226,7 +386,7 @@ var useOnResizeContent = (ref, callback) => {
226
386
  resizeObserver.disconnect();
227
387
  mutationObserver.disconnect();
228
388
  };
229
- }, [el, callbackRef]);
389
+ }, [ref, callbackRef]);
230
390
  };
231
391
 
232
392
  // src/utils/hooks/useOnScrollToBottom.tsx
@@ -278,7 +438,9 @@ var ThreadViewport = forwardRef2(({ autoScroll = true, onScroll, children, ...re
278
438
  if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {
279
439
  } else if (newIsAtBottom !== isAtBottom) {
280
440
  isScrollingToBottomRef.current = false;
281
- useViewport.setState({ isAtBottom: newIsAtBottom });
441
+ useViewport.setState({
442
+ isAtBottom: newIsAtBottom
443
+ });
282
444
  }
283
445
  lastScrollTop.current = div.scrollTop;
284
446
  };
@@ -302,9 +464,9 @@ import { memo } from "react";
302
464
 
303
465
  // src/context/providers/MessageProvider.tsx
304
466
  import { useEffect as useEffect3, useState } from "react";
305
- import { create as create2 } from "zustand";
467
+ import { create as create3 } from "zustand";
306
468
 
307
- // src/context/stores/MessageComposer.ts
469
+ // src/context/stores/EditComposer.ts
308
470
  import { create } from "zustand";
309
471
 
310
472
  // src/context/stores/BaseComposer.ts
@@ -315,7 +477,7 @@ var makeBaseComposer = (set) => ({
315
477
  }
316
478
  });
317
479
 
318
- // src/context/stores/MessageComposer.ts
480
+ // src/context/stores/EditComposer.ts
319
481
  var makeEditComposerStore = ({
320
482
  onEdit,
321
483
  onSend
@@ -338,17 +500,34 @@ var makeEditComposerStore = ({
338
500
  }
339
501
  }));
340
502
 
503
+ // src/context/stores/MessageUtils.ts
504
+ import { create as create2 } from "zustand";
505
+ var makeMessageUtilsStore = () => create2((set) => ({
506
+ inProgressIndicator: null,
507
+ setInProgressIndicator: (value) => {
508
+ set({ inProgressIndicator: value });
509
+ },
510
+ isCopied: false,
511
+ setIsCopied: (value) => {
512
+ set({ isCopied: value });
513
+ },
514
+ isHovering: false,
515
+ setIsHovering: (value) => {
516
+ set({ isHovering: value });
517
+ }
518
+ }));
519
+
341
520
  // src/context/providers/MessageProvider.tsx
342
521
  import { jsx as jsx4 } from "react/jsx-runtime";
343
522
  var getIsLast = (thread, message) => {
344
523
  return thread.messages[thread.messages.length - 1]?.id === message.id;
345
524
  };
346
- var syncMessage = (thread, useMessage, messageIndex) => {
525
+ var syncMessage = (thread, getBranches, useMessage, messageIndex) => {
347
526
  const parentId = thread.messages[messageIndex - 1]?.id ?? null;
348
527
  const message = thread.messages[messageIndex];
349
528
  if (!message) return;
350
529
  const isLast = getIsLast(thread, message);
351
- const branches = thread.getBranches(message.id);
530
+ const branches = getBranches(message.id);
352
531
  const currentState = useMessage.getState();
353
532
  if (currentState.message === message && currentState.parentId === parentId && currentState.branches === branches && currentState.isLast === isLast)
354
533
  return;
@@ -360,27 +539,11 @@ var syncMessage = (thread, useMessage, messageIndex) => {
360
539
  });
361
540
  };
362
541
  var useMessageContext2 = (messageIndex) => {
363
- const { useThread } = useThreadContext();
542
+ const { useThread, useThreadActions } = useThreadContext();
364
543
  const [context] = useState(() => {
365
- const useMessage = create2((set) => ({
366
- message: null,
367
- parentId: null,
368
- branches: [],
369
- isLast: false,
370
- inProgressIndicator: null,
371
- isCopied: false,
372
- isHovering: false,
373
- setInProgressIndicator: (value) => {
374
- set({ inProgressIndicator: value });
375
- },
376
- setIsCopied: (value) => {
377
- set({ isCopied: value });
378
- },
379
- setIsHovering: (value) => {
380
- set({ isHovering: value });
381
- }
382
- }));
383
- const useComposer = makeEditComposerStore({
544
+ const useMessage = create3(() => ({}));
545
+ const useMessageUtils = makeMessageUtilsStore();
546
+ const useEditComposer = makeEditComposerStore({
384
547
  onEdit: () => {
385
548
  const message = useMessage.getState().message;
386
549
  if (message.role !== "user")
@@ -399,20 +562,30 @@ var useMessageContext2 = (messageIndex) => {
399
562
  const nonTextParts = message.content.filter(
400
563
  (part) => part.type !== "text" && part.type !== "ui"
401
564
  );
402
- useThread.getState().append({
565
+ useThreadActions.getState().append({
403
566
  parentId,
404
567
  content: [{ type: "text", text }, ...nonTextParts]
405
568
  });
406
569
  }
407
570
  });
408
- syncMessage(useThread.getState(), useMessage, messageIndex);
409
- return { useMessage, useComposer };
571
+ syncMessage(
572
+ useThread.getState(),
573
+ useThreadActions.getState().getBranches,
574
+ useMessage,
575
+ messageIndex
576
+ );
577
+ return { useMessage, useMessageUtils, useEditComposer };
410
578
  });
411
579
  useEffect3(() => {
412
580
  return useThread.subscribe((thread) => {
413
- syncMessage(thread, context.useMessage, messageIndex);
581
+ syncMessage(
582
+ thread,
583
+ useThreadActions.getState().getBranches,
584
+ context.useMessage,
585
+ messageIndex
586
+ );
414
587
  });
415
- }, [context, useThread, messageIndex]);
588
+ }, [useThread, useThreadActions, context, messageIndex]);
416
589
  return context;
417
590
  };
418
591
  var MessageProvider = ({
@@ -424,32 +597,12 @@ var MessageProvider = ({
424
597
  };
425
598
 
426
599
  // src/primitives/composer/ComposerIf.tsx
427
- var useComposerIf = (props) => {
428
- const { useComposer } = useComposerContext();
429
- return useComposer((composer) => {
430
- if (props.editing === true && !composer.isEditing) return false;
431
- if (props.editing === false && composer.isEditing) return false;
432
- return true;
433
- });
434
- };
435
600
  var ComposerIf = ({ children, ...query }) => {
436
601
  const result = useComposerIf(query);
437
602
  return result ? children : null;
438
603
  };
439
604
 
440
605
  // src/primitives/message/MessageIf.tsx
441
- var useMessageIf = (props) => {
442
- const { useMessage } = useMessageContext();
443
- return useMessage(({ message, branches, isLast, isCopied, isHovering }) => {
444
- if (props.hasBranches === true && branches.length < 2) return false;
445
- if (props.user && message.role !== "user") return false;
446
- if (props.assistant && message.role !== "assistant") return false;
447
- if (props.lastOrHover === true && !isHovering && !isLast) return false;
448
- if (props.copied === true && !isCopied) return false;
449
- if (props.copied === false && isCopied) return false;
450
- return true;
451
- });
452
- };
453
606
  var MessageIf = ({ children, ...query }) => {
454
607
  const result = useMessageIf(query);
455
608
  return result ? children : null;
@@ -498,56 +651,42 @@ var ThreadMessages = ({ components }) => {
498
651
  });
499
652
  };
500
653
 
501
- // src/primitives/thread/ThreadScrollToBottom.tsx
654
+ // src/utils/createActionButton.tsx
502
655
  import { composeEventHandlers as composeEventHandlers2 } from "@radix-ui/primitive";
503
656
  import { Primitive as Primitive3 } from "@radix-ui/react-primitive";
504
657
  import { forwardRef as forwardRef3 } from "react";
505
658
  import { jsx as jsx6 } from "react/jsx-runtime";
506
- var ThreadScrollToBottom = forwardRef3(({ onClick, ...rest }, ref) => {
507
- const { useViewport } = useThreadContext();
508
- const isAtBottom = useViewport((s) => s.isAtBottom);
509
- const handleScrollToBottom = () => {
510
- useViewport.getState().scrollToBottom();
511
- };
512
- return /* @__PURE__ */ jsx6(
513
- Primitive3.button,
514
- {
515
- ...rest,
516
- disabled: isAtBottom,
517
- ref,
518
- onClick: composeEventHandlers2(onClick, handleScrollToBottom)
519
- }
520
- );
521
- });
522
- ThreadScrollToBottom.displayName = "ThreadScrollToBottom";
659
+ var createActionButton = (displayName, useActionButton) => {
660
+ const ActionButton = forwardRef3((props, forwardedRef) => {
661
+ const callback = useActionButton(props);
662
+ return /* @__PURE__ */ jsx6(
663
+ Primitive3.button,
664
+ {
665
+ type: "button",
666
+ disabled: !callback,
667
+ ...props,
668
+ ref: forwardedRef,
669
+ onClick: composeEventHandlers2(props.onClick, () => {
670
+ callback?.();
671
+ })
672
+ }
673
+ );
674
+ });
675
+ ActionButton.displayName = displayName;
676
+ return ActionButton;
677
+ };
678
+
679
+ // src/primitives/thread/ThreadScrollToBottom.tsx
680
+ var ThreadScrollToBottom = createActionButton(
681
+ "ThreadScrollToBottom",
682
+ useThreadScrollToBottom
683
+ );
523
684
 
524
685
  // src/primitives/thread/ThreadSuggestion.tsx
525
- import { composeEventHandlers as composeEventHandlers3 } from "@radix-ui/primitive";
526
- import { Primitive as Primitive4 } from "@radix-ui/react-primitive";
527
- import { forwardRef as forwardRef4 } from "react";
528
- import { jsx as jsx7 } from "react/jsx-runtime";
529
- var ThreadSuggestion = forwardRef4(({ onClick, prompt, method, autoSend: send, ...rest }, ref) => {
530
- const { useThread, useComposer } = useThreadContext();
531
- const isDisabled = useThread((t) => t.isRunning);
532
- const handleApplySuggestion = () => {
533
- const thread = useThread.getState();
534
- const composer = useComposer.getState();
535
- composer.setValue(prompt);
536
- if (send && !thread.isRunning) {
537
- composer.send();
538
- }
539
- };
540
- return /* @__PURE__ */ jsx7(
541
- Primitive4.button,
542
- {
543
- ...rest,
544
- disabled: isDisabled,
545
- ref,
546
- onClick: composeEventHandlers3(onClick, handleApplySuggestion)
547
- }
548
- );
549
- });
550
- ThreadSuggestion.displayName = "ThreadSuggestion";
686
+ var ThreadSuggestion = createActionButton(
687
+ "ThreadSuggestion",
688
+ useThreadSuggestion
689
+ );
551
690
 
552
691
  // src/primitives/composer/index.ts
553
692
  var composer_exports = {};
@@ -560,15 +699,15 @@ __export(composer_exports, {
560
699
  });
561
700
 
562
701
  // src/primitives/composer/ComposerRoot.tsx
563
- import { composeEventHandlers as composeEventHandlers4 } from "@radix-ui/primitive";
702
+ import { composeEventHandlers as composeEventHandlers3 } from "@radix-ui/primitive";
564
703
  import { useComposedRefs as useComposedRefs2 } from "@radix-ui/react-compose-refs";
565
- import { Primitive as Primitive5 } from "@radix-ui/react-primitive";
704
+ import { Primitive as Primitive4 } from "@radix-ui/react-primitive";
566
705
  import {
567
- forwardRef as forwardRef5,
706
+ forwardRef as forwardRef4,
568
707
  useRef as useRef2
569
708
  } from "react";
570
- import { jsx as jsx8 } from "react/jsx-runtime";
571
- var ComposerRoot = forwardRef5(
709
+ import { jsx as jsx7 } from "react/jsx-runtime";
710
+ var ComposerRoot = forwardRef4(
572
711
  ({ onSubmit, ...rest }, forwardedRef) => {
573
712
  const { useViewport } = useThreadContext();
574
713
  const { useComposer } = useComposerContext();
@@ -581,12 +720,12 @@ var ComposerRoot = forwardRef5(
581
720
  composerState.send();
582
721
  useViewport.getState().scrollToBottom();
583
722
  };
584
- return /* @__PURE__ */ jsx8(
585
- Primitive5.form,
723
+ return /* @__PURE__ */ jsx7(
724
+ Primitive4.form,
586
725
  {
587
726
  ...rest,
588
727
  ref,
589
- onSubmit: composeEventHandlers4(onSubmit, handleSubmit)
728
+ onSubmit: composeEventHandlers3(onSubmit, handleSubmit)
590
729
  }
591
730
  );
592
731
  }
@@ -594,18 +733,18 @@ var ComposerRoot = forwardRef5(
594
733
  ComposerRoot.displayName = "ComposerRoot";
595
734
 
596
735
  // src/primitives/composer/ComposerInput.tsx
597
- import { composeEventHandlers as composeEventHandlers5 } from "@radix-ui/primitive";
736
+ import { composeEventHandlers as composeEventHandlers4 } from "@radix-ui/primitive";
598
737
  import { useComposedRefs as useComposedRefs3 } from "@radix-ui/react-compose-refs";
599
738
  import { Slot } from "@radix-ui/react-slot";
600
739
  import {
601
- forwardRef as forwardRef6,
602
- useCallback as useCallback6,
740
+ forwardRef as forwardRef5,
741
+ useCallback as useCallback10,
603
742
  useEffect as useEffect4,
604
743
  useRef as useRef3
605
744
  } from "react";
606
745
  import TextareaAutosize from "react-textarea-autosize";
607
- import { jsx as jsx9 } from "react/jsx-runtime";
608
- var ComposerInput = forwardRef6(
746
+ import { jsx as jsx8 } from "react/jsx-runtime";
747
+ var ComposerInput = forwardRef5(
609
748
  ({ autoFocus = false, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
610
749
  const { useThread } = useThreadContext();
611
750
  const { useComposer, type } = useComposerContext();
@@ -632,10 +771,9 @@ var ComposerInput = forwardRef6(
632
771
  }
633
772
  };
634
773
  const autoFocusEnabled = autoFocus && !disabled;
635
- const focus = useCallback6(() => {
774
+ const focus = useCallback10(() => {
636
775
  const textarea = textareaRef.current;
637
776
  if (!textarea || !autoFocusEnabled) return;
638
- console.log("focus");
639
777
  textarea.focus();
640
778
  textarea.setSelectionRange(
641
779
  textareaRef.current.value.length,
@@ -648,7 +786,7 @@ var ComposerInput = forwardRef6(
648
786
  focus();
649
787
  }
650
788
  });
651
- return /* @__PURE__ */ jsx9(
789
+ return /* @__PURE__ */ jsx8(
652
790
  Component,
653
791
  {
654
792
  value,
@@ -656,12 +794,12 @@ var ComposerInput = forwardRef6(
656
794
  ref,
657
795
  autoFocus,
658
796
  disabled,
659
- onChange: composeEventHandlers5(onChange, (e) => {
797
+ onChange: composeEventHandlers4(onChange, (e) => {
660
798
  const composerState = useComposer.getState();
661
799
  if (!composerState.isEditing) return;
662
800
  return composerState.setValue(e.target.value);
663
801
  }),
664
- onKeyDown: composeEventHandlers5(onKeyDown, handleKeyPress)
802
+ onKeyDown: composeEventHandlers4(onKeyDown, handleKeyPress)
665
803
  }
666
804
  );
667
805
  }
@@ -669,47 +807,13 @@ var ComposerInput = forwardRef6(
669
807
  ComposerInput.displayName = "ComposerInput";
670
808
 
671
809
  // src/primitives/composer/ComposerSend.tsx
672
- import { Primitive as Primitive6 } from "@radix-ui/react-primitive";
673
- import { forwardRef as forwardRef7 } from "react";
674
- import { jsx as jsx10 } from "react/jsx-runtime";
675
- var ComposerSend = forwardRef7(
676
- ({ disabled, ...rest }, ref) => {
677
- const { useComposer } = useComposerContext();
678
- const hasValue = useComposer((c) => c.isEditing && c.value.length > 0);
679
- return /* @__PURE__ */ jsx10(
680
- Primitive6.button,
681
- {
682
- type: "submit",
683
- ...rest,
684
- ref,
685
- disabled: disabled || !hasValue
686
- }
687
- );
688
- }
689
- );
690
- ComposerSend.displayName = "ComposerSend";
810
+ var ComposerSend = createActionButton("ComposerSend", useComposerSend);
691
811
 
692
812
  // src/primitives/composer/ComposerCancel.tsx
693
- import { composeEventHandlers as composeEventHandlers6 } from "@radix-ui/primitive";
694
- import { Primitive as Primitive7 } from "@radix-ui/react-primitive";
695
- import { forwardRef as forwardRef8 } from "react";
696
- import { jsx as jsx11 } from "react/jsx-runtime";
697
- var ComposerCancel = forwardRef8(({ onClick, ...rest }, ref) => {
698
- const { useComposer } = useComposerContext();
699
- const handleCancel = () => {
700
- useComposer.getState().cancel();
701
- };
702
- return /* @__PURE__ */ jsx11(
703
- Primitive7.button,
704
- {
705
- type: "button",
706
- ...rest,
707
- ref,
708
- onClick: composeEventHandlers6(onClick, handleCancel)
709
- }
710
- );
711
- });
712
- ComposerCancel.displayName = "ComposerCancel";
813
+ var ComposerCancel = createActionButton(
814
+ "ComposerCancel",
815
+ useComposerCancel
816
+ );
713
817
 
714
818
  // src/primitives/message/index.ts
715
819
  var message_exports = {};
@@ -721,27 +825,27 @@ __export(message_exports, {
721
825
  });
722
826
 
723
827
  // src/primitives/message/MessageRoot.tsx
724
- import { composeEventHandlers as composeEventHandlers7 } from "@radix-ui/primitive";
725
- import { Primitive as Primitive8 } from "@radix-ui/react-primitive";
726
- import { forwardRef as forwardRef9 } from "react";
727
- import { jsx as jsx12 } from "react/jsx-runtime";
728
- var MessageRoot = forwardRef9(
828
+ import { composeEventHandlers as composeEventHandlers5 } from "@radix-ui/primitive";
829
+ import { Primitive as Primitive5 } from "@radix-ui/react-primitive";
830
+ import { forwardRef as forwardRef6 } from "react";
831
+ import { jsx as jsx9 } from "react/jsx-runtime";
832
+ var MessageRoot = forwardRef6(
729
833
  ({ onMouseEnter, onMouseLeave, ...rest }, ref) => {
730
- const { useMessage } = useMessageContext();
731
- const setIsHovering = useMessage((s) => s.setIsHovering);
834
+ const { useMessageUtils } = useMessageContext();
835
+ const setIsHovering = useMessageUtils((s) => s.setIsHovering);
732
836
  const handleMouseEnter = () => {
733
837
  setIsHovering(true);
734
838
  };
735
839
  const handleMouseLeave = () => {
736
840
  setIsHovering(false);
737
841
  };
738
- return /* @__PURE__ */ jsx12(
739
- Primitive8.div,
842
+ return /* @__PURE__ */ jsx9(
843
+ Primitive5.div,
740
844
  {
741
845
  ...rest,
742
846
  ref,
743
- onMouseEnter: composeEventHandlers7(onMouseEnter, handleMouseEnter),
744
- onMouseLeave: composeEventHandlers7(onMouseLeave, handleMouseLeave)
847
+ onMouseEnter: composeEventHandlers5(onMouseEnter, handleMouseEnter),
848
+ onMouseLeave: composeEventHandlers5(onMouseLeave, handleMouseLeave)
745
849
  }
746
850
  );
747
851
  }
@@ -753,8 +857,8 @@ import { memo as memo2 } from "react";
753
857
 
754
858
  // src/context/providers/ContentPartProvider.tsx
755
859
  import { useEffect as useEffect5, useState as useState2 } from "react";
756
- import { create as create3 } from "zustand";
757
- import { jsx as jsx13 } from "react/jsx-runtime";
860
+ import { create as create4 } from "zustand";
861
+ import { jsx as jsx10 } from "react/jsx-runtime";
758
862
  var syncContentPart = ({ message }, useContentPart, partIndex) => {
759
863
  const part = message.content[partIndex];
760
864
  if (!part) return;
@@ -762,19 +866,24 @@ var syncContentPart = ({ message }, useContentPart, partIndex) => {
762
866
  const status = partIndex === message.content.length - 1 ? messageStatus : "done";
763
867
  const currentState = useContentPart.getState();
764
868
  if (currentState.part === part && currentState.status === status) return;
765
- useContentPart.setState({ part, status });
869
+ useContentPart.setState(
870
+ Object.freeze({
871
+ part,
872
+ status
873
+ })
874
+ );
766
875
  };
767
876
  var useContentPartContext2 = (partIndex) => {
768
877
  const { useMessage } = useMessageContext();
769
878
  const [context] = useState2(() => {
770
- const useContentPart = create3(() => ({
771
- part: { type: "text", text: "" },
772
- status: "done"
773
- }));
879
+ const useContentPart = create4(
880
+ () => ({})
881
+ );
774
882
  syncContentPart(useMessage.getState(), useContentPart, partIndex);
775
883
  return { useContentPart };
776
884
  });
777
885
  useEffect5(() => {
886
+ syncContentPart(useMessage.getState(), context.useContentPart, partIndex);
778
887
  return useMessage.subscribe((message) => {
779
888
  syncContentPart(message, context.useContentPart, partIndex);
780
889
  });
@@ -786,65 +895,46 @@ var ContentPartProvider = ({
786
895
  children
787
896
  }) => {
788
897
  const context = useContentPartContext2(partIndex);
789
- return /* @__PURE__ */ jsx13(ContentPartContext.Provider, { value: context, children });
898
+ return /* @__PURE__ */ jsx10(ContentPartContext.Provider, { value: context, children });
790
899
  };
791
900
 
792
901
  // src/primitives/contentPart/ContentPartDisplay.tsx
793
902
  var ContentPartDisplay = () => {
794
- const { useContentPart } = useContentPartContext();
795
- const display = useContentPart((c) => {
796
- if (c.part.type !== "ui")
797
- throw new Error(
798
- "ContentPartDisplay can only be used inside ui content parts."
799
- );
800
- return c.part.display;
801
- });
903
+ const display = useContentPartDisplay();
802
904
  return display ?? null;
803
905
  };
804
906
 
805
907
  // src/primitives/contentPart/ContentPartInProgressIndicator.tsx
806
908
  var ContentPartInProgressIndicator = () => {
807
- const { useMessage } = useMessageContext();
808
- const { useContentPart } = useContentPartContext();
809
- const indicator = useCombinedStore(
810
- [useMessage, useContentPart],
811
- (m, c) => c.status === "in_progress" ? m.inProgressIndicator : null
812
- );
909
+ const indicator = useContentPartInProgressIndicator();
813
910
  return indicator;
814
911
  };
815
912
 
816
913
  // src/primitives/contentPart/ContentPartText.tsx
817
- import { Primitive as Primitive9 } from "@radix-ui/react-primitive";
818
- import { forwardRef as forwardRef10 } from "react";
819
- import { jsx as jsx14 } from "react/jsx-runtime";
820
- var ContentPartText = forwardRef10((props, forwardedRef) => {
821
- const { useContentPart } = useContentPartContext();
822
- const text = useContentPart((c) => {
823
- if (c.part.type !== "text")
824
- throw new Error(
825
- "ContentPartText can only be used inside text content parts."
826
- );
827
- return c.part.text;
828
- });
829
- return /* @__PURE__ */ jsx14(Primitive9.span, { ...props, ref: forwardedRef, children: text });
914
+ import { Primitive as Primitive6 } from "@radix-ui/react-primitive";
915
+ import { forwardRef as forwardRef7 } from "react";
916
+ import { jsx as jsx11 } from "react/jsx-runtime";
917
+ var ContentPartText = forwardRef7((props, forwardedRef) => {
918
+ const text = useContentPartText();
919
+ return /* @__PURE__ */ jsx11(Primitive6.span, { ...props, ref: forwardedRef, children: text });
830
920
  });
831
921
  ContentPartText.displayName = "ContentPartText";
832
922
 
833
923
  // src/primitives/message/MessageContent.tsx
834
- import { Fragment, jsx as jsx15, jsxs as jsxs3 } from "react/jsx-runtime";
924
+ import { Fragment, jsx as jsx12, jsxs as jsxs3 } from "react/jsx-runtime";
835
925
  var defaultComponents = {
836
926
  Text: () => /* @__PURE__ */ jsxs3(Fragment, { children: [
837
- /* @__PURE__ */ jsx15(ContentPartText, {}),
838
- /* @__PURE__ */ jsx15(ContentPartInProgressIndicator, {})
927
+ /* @__PURE__ */ jsx12(ContentPartText, {}),
928
+ /* @__PURE__ */ jsx12(ContentPartInProgressIndicator, {})
839
929
  ] }),
840
930
  Image: () => null,
841
- UI: () => /* @__PURE__ */ jsx15(ContentPartDisplay, {}),
931
+ UI: () => /* @__PURE__ */ jsx12(ContentPartDisplay, {}),
842
932
  tools: {
843
933
  Fallback: (props) => {
844
934
  const { useToolUIs } = useAssistantContext();
845
935
  const Render = useToolUIs((s) => s.getToolUI(props.part.toolName));
846
936
  if (!Render) return null;
847
- return /* @__PURE__ */ jsx15(Render, { ...props });
937
+ return /* @__PURE__ */ jsx12(Render, { ...props });
848
938
  }
849
939
  }
850
940
  };
@@ -856,22 +946,22 @@ var MessageContentPartComponent = ({
856
946
  tools: { by_name = {}, Fallback = defaultComponents.tools.Fallback } = {}
857
947
  } = {}
858
948
  }) => {
859
- const { useThread } = useThreadContext();
860
- const addToolResult = useThread((t) => t.addToolResult);
949
+ const { useThreadActions } = useThreadContext();
950
+ const addToolResult = useThreadActions((t) => t.addToolResult);
861
951
  const { useContentPart } = useContentPartContext();
862
952
  const { part, status } = useContentPart();
863
953
  const type = part.type;
864
954
  switch (type) {
865
955
  case "text":
866
- return /* @__PURE__ */ jsx15(Text, { part, status });
956
+ return /* @__PURE__ */ jsx12(Text, { part, status });
867
957
  case "image":
868
- return /* @__PURE__ */ jsx15(Image, { part, status });
958
+ return /* @__PURE__ */ jsx12(Image, { part, status });
869
959
  case "ui":
870
- return /* @__PURE__ */ jsx15(UI, { part, status });
960
+ return /* @__PURE__ */ jsx12(UI, { part, status });
871
961
  case "tool-call": {
872
962
  const Tool = by_name[part.toolName] || Fallback;
873
963
  const addResult = (result) => addToolResult(part.toolCallId, result);
874
- return /* @__PURE__ */ jsx15(Tool, { part, status, addResult });
964
+ return /* @__PURE__ */ jsx12(Tool, { part, status, addResult });
875
965
  }
876
966
  default:
877
967
  throw new Error(`Unknown content part type: ${type}`);
@@ -881,7 +971,7 @@ var MessageContentPartImpl = ({
881
971
  partIndex,
882
972
  components
883
973
  }) => {
884
- return /* @__PURE__ */ jsx15(ContentPartProvider, { partIndex, children: /* @__PURE__ */ jsx15(MessageContentPartComponent, { components }) });
974
+ return /* @__PURE__ */ jsx12(ContentPartProvider, { partIndex, children: /* @__PURE__ */ jsx12(MessageContentPartComponent, { components }) });
885
975
  };
886
976
  var MessageContentPart = memo2(
887
977
  MessageContentPartImpl,
@@ -892,7 +982,7 @@ var MessageContent = ({ components }) => {
892
982
  const contentLength = useMessage((s) => s.message.content.length);
893
983
  return new Array(contentLength).fill(null).map((_, idx) => {
894
984
  const partIndex = idx;
895
- return /* @__PURE__ */ jsx15(
985
+ return /* @__PURE__ */ jsx12(
896
986
  MessageContentPart,
897
987
  {
898
988
  partIndex,
@@ -904,17 +994,17 @@ var MessageContent = ({ components }) => {
904
994
  };
905
995
 
906
996
  // src/primitives/message/MessageInProgress.tsx
907
- import { Primitive as Primitive10 } from "@radix-ui/react-primitive";
997
+ import { Primitive as Primitive7 } from "@radix-ui/react-primitive";
908
998
  import {
909
- forwardRef as forwardRef11,
999
+ forwardRef as forwardRef8,
910
1000
  useMemo as useMemo2
911
1001
  } from "react";
912
- import { jsx as jsx16 } from "react/jsx-runtime";
913
- var MessageInProgress = forwardRef11((props, ref) => {
914
- const { useMessage } = useMessageContext();
1002
+ import { jsx as jsx13 } from "react/jsx-runtime";
1003
+ var MessageInProgress = forwardRef8((props, ref) => {
1004
+ const { useMessageUtils } = useMessageContext();
915
1005
  useMemo2(() => {
916
- useMessage.getState().setInProgressIndicator(/* @__PURE__ */ jsx16(Primitive10.span, { ...props, ref }));
917
- }, [useMessage, props, ref]);
1006
+ useMessageUtils.getState().setInProgressIndicator(/* @__PURE__ */ jsx13(Primitive7.span, { ...props, ref }));
1007
+ }, [useMessageUtils, props, ref]);
918
1008
  return null;
919
1009
  });
920
1010
  MessageInProgress.displayName = "MessageInProgress";
@@ -929,57 +1019,38 @@ __export(branchPicker_exports, {
929
1019
  Root: () => BranchPickerRoot
930
1020
  });
931
1021
 
932
- // src/utils/createActionButton.tsx
933
- import { composeEventHandlers as composeEventHandlers8 } from "@radix-ui/primitive";
934
- import { Primitive as Primitive11 } from "@radix-ui/react-primitive";
935
- import { forwardRef as forwardRef12 } from "react";
936
- import { jsx as jsx17 } from "react/jsx-runtime";
937
- var createActionButton = (useActionButton) => {
938
- const ActionButton = forwardRef12((props, forwardedRef) => {
939
- const onClick = useActionButton(props);
940
- return /* @__PURE__ */ jsx17(
941
- Primitive11.button,
942
- {
943
- type: "button",
944
- disabled: !onClick,
945
- ...props,
946
- ref: forwardedRef,
947
- onClick: composeEventHandlers8(props.onClick, onClick ?? void 0)
948
- }
949
- );
950
- });
951
- ActionButton.displayName = "ActionButton";
952
- return ActionButton;
953
- };
954
-
955
1022
  // src/primitives/branchPicker/BranchPickerNext.tsx
956
- var BranchPickerNext = createActionButton(useGoToNextBranch);
1023
+ var BranchPickerNext = createActionButton(
1024
+ "BranchPickerNext",
1025
+ useBranchPickerNext
1026
+ );
957
1027
 
958
1028
  // src/primitives/branchPicker/BranchPickerPrevious.tsx
959
- var BranchPickerPrevious = createActionButton(useGoToPreviousBranch);
1029
+ var BranchPickerPrevious = createActionButton(
1030
+ "BranchPickerPrevious",
1031
+ useBranchPickerPrevious
1032
+ );
960
1033
 
961
1034
  // src/primitives/branchPicker/BranchPickerCount.tsx
962
- import { Fragment as Fragment2, jsx as jsx18 } from "react/jsx-runtime";
1035
+ import { Fragment as Fragment2, jsx as jsx14 } from "react/jsx-runtime";
963
1036
  var BranchPickerCount = () => {
964
- const { useMessage } = useMessageContext();
965
- const branchCount = useMessage((s) => s.branches.length);
966
- return /* @__PURE__ */ jsx18(Fragment2, { children: branchCount });
1037
+ const branchCount = useBranchPickerCount();
1038
+ return /* @__PURE__ */ jsx14(Fragment2, { children: branchCount });
967
1039
  };
968
1040
 
969
1041
  // src/primitives/branchPicker/BranchPickerNumber.tsx
970
- import { Fragment as Fragment3, jsx as jsx19 } from "react/jsx-runtime";
1042
+ import { Fragment as Fragment3, jsx as jsx15 } from "react/jsx-runtime";
971
1043
  var BranchPickerNumber = () => {
972
- const { useMessage } = useMessageContext();
973
- const branchIdx = useMessage((s) => s.branches.indexOf(s.message.id));
974
- return /* @__PURE__ */ jsx19(Fragment3, { children: branchIdx + 1 });
1044
+ const branchNumber = useBranchPickerNumber();
1045
+ return /* @__PURE__ */ jsx15(Fragment3, { children: branchNumber });
975
1046
  };
976
1047
 
977
1048
  // src/primitives/branchPicker/BranchPickerRoot.tsx
978
- import { Primitive as Primitive12 } from "@radix-ui/react-primitive";
979
- import { forwardRef as forwardRef13 } from "react";
980
- import { jsx as jsx20 } from "react/jsx-runtime";
981
- var BranchPickerRoot = forwardRef13(({ hideWhenSingleBranch, ...rest }, ref) => {
982
- return /* @__PURE__ */ jsx20(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0, children: /* @__PURE__ */ jsx20(Primitive12.div, { ...rest, ref }) });
1049
+ import { Primitive as Primitive8 } from "@radix-ui/react-primitive";
1050
+ import { forwardRef as forwardRef9 } from "react";
1051
+ import { jsx as jsx16 } from "react/jsx-runtime";
1052
+ var BranchPickerRoot = forwardRef9(({ hideWhenSingleBranch, ...rest }, ref) => {
1053
+ return /* @__PURE__ */ jsx16(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0, children: /* @__PURE__ */ jsx16(Primitive8.div, { ...rest, ref }) });
983
1054
  });
984
1055
  BranchPickerRoot.displayName = "BranchPickerRoot";
985
1056
 
@@ -993,27 +1064,38 @@ __export(actionBar_exports, {
993
1064
  });
994
1065
 
995
1066
  // src/primitives/actionBar/ActionBarRoot.tsx
996
- import { Primitive as Primitive13 } from "@radix-ui/react-primitive";
997
- import { forwardRef as forwardRef14 } from "react";
998
- import { jsx as jsx21 } from "react/jsx-runtime";
999
- var ActionBarRoot = forwardRef14(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
1067
+ import { Primitive as Primitive9 } from "@radix-ui/react-primitive";
1068
+ import { forwardRef as forwardRef10 } from "react";
1069
+ import { jsx as jsx17 } from "react/jsx-runtime";
1070
+ var useActionBarFloatStatus = ({
1071
+ hideWhenRunning,
1072
+ autohide,
1073
+ autohideFloat
1074
+ }) => {
1000
1075
  const { useThread } = useThreadContext();
1001
- const { useMessage } = useMessageContext();
1002
- const hideAndfloatStatus = useCombinedStore(
1003
- [useThread, useMessage],
1004
- (t, m) => {
1076
+ const { useMessage, useMessageUtils } = useMessageContext();
1077
+ return useCombinedStore(
1078
+ [useThread, useMessage, useMessageUtils],
1079
+ (t, m, mu) => {
1005
1080
  if (hideWhenRunning && t.isRunning) return "hidden" /* Hidden */;
1006
1081
  const autohideEnabled = autohide === "always" || autohide === "not-last" && !m.isLast;
1007
1082
  if (!autohideEnabled) return "normal" /* Normal */;
1008
- if (!m.isHovering) return "hidden" /* Hidden */;
1083
+ if (!mu.isHovering) return "hidden" /* Hidden */;
1009
1084
  if (autohideFloat === "always" || autohideFloat === "single-branch" && m.branches.length <= 1)
1010
1085
  return "floating" /* Floating */;
1011
1086
  return "normal" /* Normal */;
1012
1087
  }
1013
1088
  );
1089
+ };
1090
+ var ActionBarRoot = forwardRef10(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
1091
+ const hideAndfloatStatus = useActionBarFloatStatus({
1092
+ hideWhenRunning,
1093
+ autohide,
1094
+ autohideFloat
1095
+ });
1014
1096
  if (hideAndfloatStatus === "hidden" /* Hidden */) return null;
1015
- return /* @__PURE__ */ jsx21(
1016
- Primitive13.div,
1097
+ return /* @__PURE__ */ jsx17(
1098
+ Primitive9.div,
1017
1099
  {
1018
1100
  ...hideAndfloatStatus === "floating" /* Floating */ ? { "data-floating": "true" } : null,
1019
1101
  ...rest,
@@ -1024,13 +1106,22 @@ var ActionBarRoot = forwardRef14(({ hideWhenRunning, autohide, autohideFloat, ..
1024
1106
  ActionBarRoot.displayName = "ActionBarRoot";
1025
1107
 
1026
1108
  // src/primitives/actionBar/ActionBarCopy.tsx
1027
- var ActionBarCopy = createActionButton(useCopyMessage);
1109
+ var ActionBarCopy = createActionButton(
1110
+ "ActionBarCopy",
1111
+ useActionBarCopy
1112
+ );
1028
1113
 
1029
1114
  // src/primitives/actionBar/ActionBarReload.tsx
1030
- var ActionBarReload = createActionButton(useReloadMessage);
1115
+ var ActionBarReload = createActionButton(
1116
+ "ActionBarReload",
1117
+ useActionBarReload
1118
+ );
1031
1119
 
1032
1120
  // src/primitives/actionBar/ActionBarEdit.tsx
1033
- var ActionBarEdit = createActionButton(useBeginMessageEdit);
1121
+ var ActionBarEdit = createActionButton(
1122
+ "ActionBarEdit",
1123
+ useActionBarEdit
1124
+ );
1034
1125
 
1035
1126
  // src/primitives/contentPart/index.ts
1036
1127
  var contentPart_exports = {};
@@ -1042,19 +1133,12 @@ __export(contentPart_exports, {
1042
1133
  });
1043
1134
 
1044
1135
  // src/primitives/contentPart/ContentPartImage.tsx
1045
- import { Primitive as Primitive14 } from "@radix-ui/react-primitive";
1046
- import { forwardRef as forwardRef15 } from "react";
1047
- import { jsx as jsx22 } from "react/jsx-runtime";
1048
- var ContentPartImage = forwardRef15((props, forwardedRef) => {
1049
- const { useContentPart } = useContentPartContext();
1050
- const image = useContentPart((c) => {
1051
- if (c.part.type !== "image")
1052
- throw new Error(
1053
- "ContentPartImage can only be used inside image content parts."
1054
- );
1055
- return c.part.image;
1056
- });
1057
- return /* @__PURE__ */ jsx22(Primitive14.img, { src: image, ...props, ref: forwardedRef });
1136
+ import { Primitive as Primitive10 } from "@radix-ui/react-primitive";
1137
+ import { forwardRef as forwardRef11 } from "react";
1138
+ import { jsx as jsx18 } from "react/jsx-runtime";
1139
+ var ContentPartImage = forwardRef11((props, forwardedRef) => {
1140
+ const image = useContentPartImage();
1141
+ return /* @__PURE__ */ jsx18(Primitive10.img, { src: image, ...props, ref: forwardedRef });
1058
1142
  });
1059
1143
  ContentPartImage.displayName = "ContentPartImage";
1060
1144
 
@@ -1359,7 +1443,7 @@ import { memo as memo3 } from "react";
1359
1443
  import { useEffect as useEffect7, useInsertionEffect as useInsertionEffect3, useRef as useRef5, useState as useState5 } from "react";
1360
1444
 
1361
1445
  // src/context/stores/AssistantModelConfig.ts
1362
- import { create as create4 } from "zustand";
1446
+ import { create as create5 } from "zustand";
1363
1447
 
1364
1448
  // src/utils/ProxyConfigProvider.ts
1365
1449
  var ProxyConfigProvider = class {
@@ -1376,23 +1460,23 @@ var ProxyConfigProvider = class {
1376
1460
  };
1377
1461
 
1378
1462
  // src/context/stores/AssistantModelConfig.ts
1379
- var makeAssistantModelConfigStore = () => create4(() => {
1463
+ var makeAssistantModelConfigStore = () => create5(() => {
1380
1464
  const proxy = new ProxyConfigProvider();
1381
- return {
1465
+ return Object.freeze({
1382
1466
  getModelConfig: () => {
1383
1467
  return proxy.getModelConfig();
1384
1468
  },
1385
1469
  registerModelConfigProvider: (provider) => {
1386
1470
  return proxy.registerModelConfigProvider(provider);
1387
1471
  }
1388
- };
1472
+ });
1389
1473
  });
1390
1474
 
1391
1475
  // src/context/stores/AssistantToolUIs.ts
1392
- import { create as create5 } from "zustand";
1393
- var makeAssistantToolUIsStore = () => create5((set) => {
1476
+ import { create as create6 } from "zustand";
1477
+ var makeAssistantToolUIsStore = () => create6((set) => {
1394
1478
  const renderers = /* @__PURE__ */ new Map();
1395
- return {
1479
+ return Object.freeze({
1396
1480
  getToolUI: (name) => {
1397
1481
  const arr = renderers.get(name);
1398
1482
  const last = arr?.at(-1);
@@ -1412,25 +1496,27 @@ var makeAssistantToolUIsStore = () => create5((set) => {
1412
1496
  if (index !== -1) {
1413
1497
  arr.splice(index, 1);
1414
1498
  }
1415
- set({});
1499
+ if (index === arr.length) {
1500
+ set({});
1501
+ }
1416
1502
  };
1417
1503
  }
1418
- };
1504
+ });
1419
1505
  });
1420
1506
 
1421
1507
  // src/context/providers/ThreadProvider.tsx
1422
1508
  import { useEffect as useEffect6, useInsertionEffect as useInsertionEffect2, useRef as useRef4, useState as useState4 } from "react";
1423
1509
 
1424
1510
  // src/context/stores/Composer.ts
1425
- import { create as create6 } from "zustand";
1426
- var makeComposerStore = (useThread) => create6()((set, get, store) => {
1511
+ import { create as create7 } from "zustand";
1512
+ var makeComposerStore = (useThread, useThreadActions) => create7()((set, get, store) => {
1427
1513
  return {
1428
1514
  ...makeBaseComposer(set, get, store),
1429
1515
  isEditing: true,
1430
1516
  send: () => {
1431
1517
  const { setValue, value } = get();
1432
1518
  setValue("");
1433
- useThread.getState().append({
1519
+ useThreadActions.getState().append({
1434
1520
  parentId: useThread.getState().messages.at(-1)?.id ?? null,
1435
1521
  content: [{ type: "text", text: value }]
1436
1522
  });
@@ -1438,42 +1524,26 @@ var makeComposerStore = (useThread) => create6()((set, get, store) => {
1438
1524
  cancel: () => {
1439
1525
  const thread = useThread.getState();
1440
1526
  if (!thread.isRunning) return false;
1441
- useThread.getState().cancelRun();
1527
+ useThreadActions.getState().cancelRun();
1442
1528
  return true;
1443
1529
  }
1444
1530
  };
1445
1531
  });
1446
1532
 
1447
1533
  // src/context/stores/Thread.ts
1448
- import { create as create7 } from "zustand";
1534
+ import { create as create8 } from "zustand";
1449
1535
  var makeThreadStore = (runtimeRef) => {
1450
- const useThread = create7(() => ({
1536
+ return create8(() => ({
1451
1537
  messages: runtimeRef.current.messages,
1452
- isRunning: runtimeRef.current.isRunning,
1453
- getBranches: (messageId) => runtimeRef.current.getBranches(messageId),
1454
- switchToBranch: (branchId) => runtimeRef.current.switchToBranch(branchId),
1455
- startRun: (parentId) => runtimeRef.current.startRun(parentId),
1456
- append: (message) => runtimeRef.current.append(message),
1457
- cancelRun: () => runtimeRef.current.cancelRun(),
1458
- addToolResult: (toolCallId, result) => runtimeRef.current.addToolResult(toolCallId, result)
1538
+ isRunning: runtimeRef.current.isRunning
1459
1539
  }));
1460
- const onRuntimeUpdate = () => {
1461
- useThread.setState({
1462
- messages: runtimeRef.current.messages,
1463
- isRunning: runtimeRef.current.isRunning
1464
- });
1465
- };
1466
- return {
1467
- useThread,
1468
- onRuntimeUpdate
1469
- };
1470
1540
  };
1471
1541
 
1472
1542
  // src/context/stores/ThreadViewport.tsx
1473
- import { create as create8 } from "zustand";
1543
+ import { create as create9 } from "zustand";
1474
1544
  var makeThreadViewportStore = () => {
1475
1545
  const scrollToBottomListeners = /* @__PURE__ */ new Set();
1476
- return create8(() => ({
1546
+ return create9(() => ({
1477
1547
  isAtBottom: true,
1478
1548
  scrollToBottom: () => {
1479
1549
  for (const listener of scrollToBottomListeners) {
@@ -1489,8 +1559,23 @@ var makeThreadViewportStore = () => {
1489
1559
  }));
1490
1560
  };
1491
1561
 
1562
+ // src/context/stores/ThreadActions.ts
1563
+ import { create as create10 } from "zustand";
1564
+ var makeThreadActionStore = (runtimeRef) => {
1565
+ return create10(
1566
+ () => Object.freeze({
1567
+ getBranches: (messageId) => runtimeRef.current.getBranches(messageId),
1568
+ switchToBranch: (branchId) => runtimeRef.current.switchToBranch(branchId),
1569
+ startRun: (parentId) => runtimeRef.current.startRun(parentId),
1570
+ append: (message) => runtimeRef.current.append(message),
1571
+ cancelRun: () => runtimeRef.current.cancelRun(),
1572
+ addToolResult: (toolCallId, result) => runtimeRef.current.addToolResult(toolCallId, result)
1573
+ })
1574
+ );
1575
+ };
1576
+
1492
1577
  // src/context/providers/ThreadProvider.tsx
1493
- import { jsx as jsx23, jsxs as jsxs4 } from "react/jsx-runtime";
1578
+ import { jsx as jsx19, jsxs as jsxs4 } from "react/jsx-runtime";
1494
1579
  var ThreadProvider = ({
1495
1580
  children,
1496
1581
  runtime
@@ -1499,32 +1584,40 @@ var ThreadProvider = ({
1499
1584
  useInsertionEffect2(() => {
1500
1585
  runtimeRef.current = runtime;
1501
1586
  });
1502
- const [{ context, onRuntimeUpdate }] = useState4(() => {
1503
- const { useThread, onRuntimeUpdate: onRuntimeUpdate2 } = makeThreadStore(runtimeRef);
1587
+ const [context] = useState4(() => {
1588
+ const useThread = makeThreadStore(runtimeRef);
1589
+ const useThreadActions = makeThreadActionStore(runtimeRef);
1504
1590
  const useViewport = makeThreadViewportStore();
1505
- const useComposer = makeComposerStore(useThread);
1591
+ const useComposer = makeComposerStore(useThread, useThreadActions);
1506
1592
  return {
1507
- context: {
1508
- useViewport,
1509
- useThread,
1510
- useComposer
1511
- },
1512
- onRuntimeUpdate: onRuntimeUpdate2
1593
+ useThread,
1594
+ useThreadActions,
1595
+ useComposer,
1596
+ useViewport
1513
1597
  };
1514
1598
  });
1515
1599
  useEffect6(() => {
1600
+ const onRuntimeUpdate = () => {
1601
+ context.useThread.setState(
1602
+ Object.freeze({
1603
+ messages: runtimeRef.current.messages,
1604
+ isRunning: runtimeRef.current.isRunning
1605
+ }),
1606
+ true
1607
+ );
1608
+ };
1516
1609
  onRuntimeUpdate();
1517
1610
  return runtime.subscribe(onRuntimeUpdate);
1518
- }, [onRuntimeUpdate, runtime]);
1611
+ }, [context, runtime]);
1519
1612
  const RuntimeSynchronizer = runtime.unstable_synchronizer;
1520
1613
  return /* @__PURE__ */ jsxs4(ThreadContext.Provider, { value: context, children: [
1521
- RuntimeSynchronizer && /* @__PURE__ */ jsx23(RuntimeSynchronizer, {}),
1614
+ RuntimeSynchronizer && /* @__PURE__ */ jsx19(RuntimeSynchronizer, {}),
1522
1615
  children
1523
1616
  ] });
1524
1617
  };
1525
1618
 
1526
1619
  // src/context/providers/AssistantProvider.tsx
1527
- import { jsx as jsx24 } from "react/jsx-runtime";
1620
+ import { jsx as jsx20 } from "react/jsx-runtime";
1528
1621
  var AssistantProvider = ({ children, runtime }) => {
1529
1622
  const runtimeRef = useRef5(runtime);
1530
1623
  useInsertionEffect3(() => {
@@ -1539,13 +1632,13 @@ var AssistantProvider = ({ children, runtime }) => {
1539
1632
  useEffect7(() => {
1540
1633
  return runtime.registerModelConfigProvider(getModelCOnfig);
1541
1634
  }, [runtime, getModelCOnfig]);
1542
- return /* @__PURE__ */ jsx24(AssistantContext.Provider, { value: context, children: /* @__PURE__ */ jsx24(ThreadProvider, { runtime, children }) });
1635
+ return /* @__PURE__ */ jsx20(AssistantContext.Provider, { value: context, children: /* @__PURE__ */ jsx20(ThreadProvider, { runtime, children }) });
1543
1636
  };
1544
1637
 
1545
1638
  // src/context/providers/AssistantRuntimeProvider.tsx
1546
- import { jsx as jsx25 } from "react/jsx-runtime";
1639
+ import { jsx as jsx21 } from "react/jsx-runtime";
1547
1640
  var AssistantRuntimeProviderImpl = ({ children, runtime }) => {
1548
- return /* @__PURE__ */ jsx25(AssistantProvider, { runtime, children });
1641
+ return /* @__PURE__ */ jsx21(AssistantProvider, { runtime, children });
1549
1642
  };
1550
1643
  var AssistantRuntimeProvider = memo3(AssistantRuntimeProviderImpl);
1551
1644
 
@@ -1564,11 +1657,25 @@ export {
1564
1657
  internal_exports as INTERNAL,
1565
1658
  message_exports as MessagePrimitive,
1566
1659
  thread_exports as ThreadPrimitive,
1567
- useBeginMessageEdit,
1568
- useCopyMessage,
1569
- useGoToNextBranch,
1570
- useGoToPreviousBranch,
1660
+ useActionBarCopy,
1661
+ useActionBarEdit,
1662
+ useActionBarReload,
1663
+ useBranchPickerCount,
1664
+ useBranchPickerNext,
1665
+ useBranchPickerNumber,
1666
+ useBranchPickerPrevious,
1667
+ useComposerCancel,
1668
+ useComposerIf,
1669
+ useComposerSend,
1670
+ useContentPartDisplay,
1671
+ useContentPartImage,
1672
+ useContentPartInProgressIndicator,
1673
+ useContentPartText,
1571
1674
  useLocalRuntime,
1572
- useReloadMessage
1675
+ useMessageIf,
1676
+ useThreadEmpty,
1677
+ useThreadIf,
1678
+ useThreadScrollToBottom,
1679
+ useThreadSuggestion
1573
1680
  };
1574
1681
  //# sourceMappingURL=index.mjs.map