@assistant-ui/react 0.1.8 → 0.1.10

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-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