@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.js CHANGED
@@ -38,19 +38,33 @@ __export(src_exports, {
38
38
  INTERNAL: () => internal_exports,
39
39
  MessagePrimitive: () => message_exports,
40
40
  ThreadPrimitive: () => thread_exports,
41
- useBeginMessageEdit: () => useBeginMessageEdit,
42
- useCopyMessage: () => useCopyMessage,
43
- useGoToNextBranch: () => useGoToNextBranch,
44
- useGoToPreviousBranch: () => useGoToPreviousBranch,
41
+ useActionBarCopy: () => useActionBarCopy,
42
+ useActionBarEdit: () => useActionBarEdit,
43
+ useActionBarReload: () => useActionBarReload,
44
+ useBranchPickerCount: () => useBranchPickerCount,
45
+ useBranchPickerNext: () => useBranchPickerNext,
46
+ useBranchPickerNumber: () => useBranchPickerNumber,
47
+ useBranchPickerPrevious: () => useBranchPickerPrevious,
48
+ useComposerCancel: () => useComposerCancel,
49
+ useComposerIf: () => useComposerIf,
50
+ useComposerSend: () => useComposerSend,
51
+ useContentPartDisplay: () => useContentPartDisplay,
52
+ useContentPartImage: () => useContentPartImage,
53
+ useContentPartInProgressIndicator: () => useContentPartInProgressIndicator,
54
+ useContentPartText: () => useContentPartText,
45
55
  useLocalRuntime: () => useLocalRuntime,
46
- useReloadMessage: () => useReloadMessage
56
+ useMessageIf: () => useMessageIf,
57
+ useThreadEmpty: () => useThreadEmpty,
58
+ useThreadIf: () => useThreadIf,
59
+ useThreadScrollToBottom: () => useThreadScrollToBottom,
60
+ useThreadSuggestion: () => useThreadSuggestion
47
61
  });
48
62
  module.exports = __toCommonJS(src_exports);
49
63
 
50
- // src/actions/useCopyMessage.tsx
64
+ // src/primitive-hooks/actionBar/useActionBarCopy.tsx
51
65
  var import_react4 = require("react");
52
66
 
53
- // src/context/MessageContext.ts
67
+ // src/context/react/MessageContext.ts
54
68
  var import_react = require("react");
55
69
  var MessageContext = (0, import_react.createContext)(null);
56
70
  var useMessageContext = () => {
@@ -96,35 +110,54 @@ var getMessageText = (message) => {
96
110
  return textParts.map((part) => part.text).join("\n\n");
97
111
  };
98
112
 
99
- // src/actions/useCopyMessage.tsx
100
- var useCopyMessage = ({ copiedDuration = 3e3 }) => {
101
- const { useMessage, useComposer } = useMessageContext();
113
+ // src/primitive-hooks/actionBar/useActionBarCopy.tsx
114
+ var useActionBarCopy = ({
115
+ copiedDuration = 3e3
116
+ } = {}) => {
117
+ const { useMessage, useMessageUtils, useEditComposer } = useMessageContext();
102
118
  const hasCopyableContent = useCombinedStore(
103
- [useMessage, useComposer],
119
+ [useMessage, useEditComposer],
104
120
  (m, c) => {
105
- return c.isEditing || m.message.content.some((c2) => c2.type === "text");
121
+ return !c.isEditing && m.message.content.some((c2) => c2.type === "text");
106
122
  }
107
123
  );
108
124
  const callback = (0, import_react4.useCallback)(() => {
109
- const { isEditing, value: composerValue } = useComposer.getState();
110
- const { message, setIsCopied } = useMessage.getState();
125
+ const { message } = useMessage.getState();
126
+ const { setIsCopied } = useMessageUtils.getState();
127
+ const { isEditing, value: composerValue } = useEditComposer.getState();
111
128
  const valueToCopy = isEditing ? composerValue : getMessageText(message);
112
129
  navigator.clipboard.writeText(valueToCopy);
113
130
  setIsCopied(true);
114
131
  setTimeout(() => setIsCopied(false), copiedDuration);
115
- }, [useComposer, useMessage, copiedDuration]);
132
+ }, [useMessage, useMessageUtils, useEditComposer, copiedDuration]);
116
133
  if (!hasCopyableContent) return null;
117
134
  return callback;
118
135
  };
119
136
 
120
- // src/actions/useReloadMessage.tsx
121
- var import_react6 = require("react");
122
-
123
- // src/context/ThreadContext.ts
137
+ // src/primitive-hooks/actionBar/useActionBarEdit.tsx
124
138
  var import_react5 = require("react");
125
- var ThreadContext = (0, import_react5.createContext)(null);
139
+ var useActionBarEdit = () => {
140
+ const { useMessage, useEditComposer } = useMessageContext();
141
+ const disabled = useCombinedStore(
142
+ [useMessage, useEditComposer],
143
+ (m, c) => m.message.role !== "user" || c.isEditing
144
+ );
145
+ const callback = (0, import_react5.useCallback)(() => {
146
+ const { edit } = useEditComposer.getState();
147
+ edit();
148
+ }, [useEditComposer]);
149
+ if (disabled) return null;
150
+ return callback;
151
+ };
152
+
153
+ // src/primitive-hooks/actionBar/useActionBarReload.tsx
154
+ var import_react7 = require("react");
155
+
156
+ // src/context/react/ThreadContext.ts
157
+ var import_react6 = require("react");
158
+ var ThreadContext = (0, import_react6.createContext)(null);
126
159
  var useThreadContext = () => {
127
- const context = (0, import_react5.useContext)(ThreadContext);
160
+ const context = (0, import_react6.useContext)(ThreadContext);
128
161
  if (!context)
129
162
  throw new Error(
130
163
  "This component must be used within an AssistantRuntimeProvider."
@@ -132,69 +165,264 @@ var useThreadContext = () => {
132
165
  return context;
133
166
  };
134
167
 
135
- // src/actions/useReloadMessage.tsx
136
- var useReloadMessage = () => {
137
- const { useThread, useViewport } = useThreadContext();
168
+ // src/primitive-hooks/actionBar/useActionBarReload.tsx
169
+ var useActionBarReload = () => {
170
+ const { useThread, useThreadActions, useViewport } = useThreadContext();
138
171
  const { useMessage } = useMessageContext();
139
172
  const disabled = useCombinedStore(
140
173
  [useThread, useMessage],
141
174
  (t, m) => t.isRunning || m.message.role !== "assistant"
142
175
  );
143
- const callback = (0, import_react6.useCallback)(() => {
176
+ const callback = (0, import_react7.useCallback)(() => {
144
177
  const { parentId } = useMessage.getState();
145
- useThread.getState().startRun(parentId);
178
+ useThreadActions.getState().startRun(parentId);
146
179
  useViewport.getState().scrollToBottom();
147
- }, [useMessage, useThread, useViewport]);
180
+ }, [useThreadActions, useMessage, useViewport]);
148
181
  if (disabled) return null;
149
182
  return callback;
150
183
  };
151
184
 
152
- // src/actions/useBeginMessageEdit.tsx
153
- var import_react7 = require("react");
154
- var useBeginMessageEdit = () => {
155
- const { useMessage, useComposer } = useMessageContext();
156
- const disabled = useCombinedStore(
157
- [useMessage, useComposer],
158
- (m, c) => m.message.role !== "user" || c.isEditing
159
- );
160
- const callback = (0, import_react7.useCallback)(() => {
161
- const { edit } = useComposer.getState();
162
- edit();
163
- }, [useComposer]);
164
- if (disabled) return null;
165
- return callback;
185
+ // src/primitive-hooks/branchPicker/useBranchPickerCount.tsx
186
+ var useBranchPickerCount = () => {
187
+ const { useMessage } = useMessageContext();
188
+ const branchCount = useMessage((s) => s.branches.length);
189
+ return branchCount;
166
190
  };
167
191
 
168
- // src/actions/useGoToNextBranch.tsx
192
+ // src/primitive-hooks/branchPicker/useBranchPickerNext.tsx
169
193
  var import_react8 = require("react");
170
- var useGoToNextBranch = () => {
171
- const { useThread } = useThreadContext();
172
- const { useMessage, useComposer } = useMessageContext();
194
+ var useBranchPickerNext = () => {
195
+ const { useThreadActions } = useThreadContext();
196
+ const { useMessage, useEditComposer } = useMessageContext();
173
197
  const disabled = useCombinedStore(
174
- [useMessage, useComposer],
198
+ [useMessage, useEditComposer],
175
199
  (m, c) => c.isEditing || m.branches.indexOf(m.message.id) + 1 >= m.branches.length
176
200
  );
177
201
  const callback = (0, import_react8.useCallback)(() => {
178
202
  const { message, branches } = useMessage.getState();
179
- useThread.getState().switchToBranch(branches[branches.indexOf(message.id) + 1]);
180
- }, [useMessage, useThread]);
203
+ useThreadActions.getState().switchToBranch(branches[branches.indexOf(message.id) + 1]);
204
+ }, [useThreadActions, useMessage]);
181
205
  if (disabled) return null;
182
206
  return callback;
183
207
  };
184
208
 
185
- // src/actions/useGoToPreviousBranch.tsx
209
+ // src/primitive-hooks/branchPicker/useBranchPickerNumber.tsx
210
+ var useBranchPickerNumber = () => {
211
+ const { useMessage } = useMessageContext();
212
+ const branchIdx = useMessage((s) => s.branches.indexOf(s.message.id));
213
+ return branchIdx + 1;
214
+ };
215
+
216
+ // src/primitive-hooks/branchPicker/useBranchPickerPrevious.tsx
186
217
  var import_react9 = require("react");
187
- var useGoToPreviousBranch = () => {
188
- const { useThread } = useThreadContext();
189
- const { useMessage, useComposer } = useMessageContext();
218
+ var useBranchPickerPrevious = () => {
219
+ const { useThreadActions } = useThreadContext();
220
+ const { useMessage, useEditComposer } = useMessageContext();
190
221
  const disabled = useCombinedStore(
191
- [useMessage, useComposer],
222
+ [useMessage, useEditComposer],
192
223
  (m, c) => c.isEditing || m.branches.indexOf(m.message.id) <= 0
193
224
  );
194
225
  const callback = (0, import_react9.useCallback)(() => {
195
226
  const { message, branches } = useMessage.getState();
196
- useThread.getState().switchToBranch(branches[branches.indexOf(message.id) - 1]);
197
- }, [useMessage, useThread]);
227
+ useThreadActions.getState().switchToBranch(branches[branches.indexOf(message.id) - 1]);
228
+ }, [useThreadActions, useMessage]);
229
+ if (disabled) return null;
230
+ return callback;
231
+ };
232
+
233
+ // src/primitive-hooks/composer/useComposerCancel.tsx
234
+ var import_react13 = require("react");
235
+
236
+ // src/context/react/AssistantContext.ts
237
+ var import_react10 = require("react");
238
+ var AssistantContext = (0, import_react10.createContext)(
239
+ null
240
+ );
241
+ var useAssistantContext = () => {
242
+ const context = (0, import_react10.useContext)(AssistantContext);
243
+ if (!context)
244
+ throw new Error(
245
+ "This component must be used within an AssistantRuntimeProvider."
246
+ );
247
+ return context;
248
+ };
249
+
250
+ // src/context/react/ComposerContext.ts
251
+ var import_react11 = require("react");
252
+ var useComposerContext = () => {
253
+ const { useComposer } = useThreadContext();
254
+ const { useEditComposer } = (0, import_react11.useContext)(MessageContext) ?? {};
255
+ return (0, import_react11.useMemo)(
256
+ () => ({
257
+ useComposer: useEditComposer ?? useComposer,
258
+ type: useEditComposer ? "edit" : "new"
259
+ }),
260
+ [useEditComposer, useComposer]
261
+ );
262
+ };
263
+
264
+ // src/context/react/ContentPartContext.ts
265
+ var import_react12 = require("react");
266
+ var ContentPartContext = (0, import_react12.createContext)(
267
+ null
268
+ );
269
+ var useContentPartContext = () => {
270
+ const context = (0, import_react12.useContext)(ContentPartContext);
271
+ if (!context)
272
+ throw new Error(
273
+ "This component can only be used inside a component passed to <MessagePrimitive.Content components={...} >."
274
+ );
275
+ return context;
276
+ };
277
+
278
+ // src/primitive-hooks/composer/useComposerCancel.tsx
279
+ var useComposerCancel = () => {
280
+ const { useComposer } = useComposerContext();
281
+ const disabled = useComposer((c) => !c.isEditing);
282
+ const callback = (0, import_react13.useCallback)(() => {
283
+ const { cancel } = useComposer.getState();
284
+ cancel();
285
+ }, [useComposer]);
286
+ if (disabled) return null;
287
+ return callback;
288
+ };
289
+
290
+ // src/primitive-hooks/composer/useComposerIf.tsx
291
+ var useComposerIf = (props) => {
292
+ const { useComposer } = useComposerContext();
293
+ return useComposer((composer) => {
294
+ if (props.editing === true && !composer.isEditing) return false;
295
+ if (props.editing === false && composer.isEditing) return false;
296
+ return true;
297
+ });
298
+ };
299
+
300
+ // src/primitive-hooks/composer/useComposerSend.tsx
301
+ var import_react14 = require("react");
302
+ var useComposerSend = () => {
303
+ const { useComposer } = useComposerContext();
304
+ const disabled = useComposer((c) => !c.isEditing || c.value.length === 0);
305
+ const callback = (0, import_react14.useCallback)(() => {
306
+ const { send } = useComposer.getState();
307
+ send();
308
+ }, [useComposer]);
309
+ if (disabled) return null;
310
+ return callback;
311
+ };
312
+
313
+ // src/primitive-hooks/contentPart/useContentPartDisplay.tsx
314
+ var useContentPartDisplay = () => {
315
+ const { useContentPart } = useContentPartContext();
316
+ const display = useContentPart((c) => {
317
+ if (c.part.type !== "ui")
318
+ throw new Error(
319
+ "This component can only be used inside ui content parts."
320
+ );
321
+ return c.part.display;
322
+ });
323
+ return display;
324
+ };
325
+
326
+ // src/primitive-hooks/contentPart/useContentPartImage.tsx
327
+ var useContentPartImage = () => {
328
+ const { useContentPart } = useContentPartContext();
329
+ const image = useContentPart((c) => {
330
+ if (c.part.type !== "image")
331
+ throw new Error(
332
+ "ContentPartImage can only be used inside image content parts."
333
+ );
334
+ return c.part.image;
335
+ });
336
+ return image;
337
+ };
338
+
339
+ // src/primitive-hooks/contentPart/useContentPartInProgressIndicator.tsx
340
+ var useContentPartInProgressIndicator = () => {
341
+ const { useMessageUtils } = useMessageContext();
342
+ const { useContentPart } = useContentPartContext();
343
+ const indicator = useCombinedStore(
344
+ [useMessageUtils, useContentPart],
345
+ (m, c) => c.status === "in_progress" ? m.inProgressIndicator : null
346
+ );
347
+ return indicator;
348
+ };
349
+
350
+ // src/primitive-hooks/contentPart/useContentPartText.tsx
351
+ var useContentPartText = () => {
352
+ const { useContentPart } = useContentPartContext();
353
+ const text = useContentPart((c) => {
354
+ if (c.part.type !== "text")
355
+ throw new Error(
356
+ "ContentPartText can only be used inside text content parts."
357
+ );
358
+ return c.part.text;
359
+ });
360
+ return text;
361
+ };
362
+
363
+ // src/primitive-hooks/message/useMessageIf.tsx
364
+ var useMessageIf = (props) => {
365
+ const { useMessage, useMessageUtils } = useMessageContext();
366
+ return useCombinedStore(
367
+ [useMessage, useMessageUtils],
368
+ ({ message, branches, isLast }, { isCopied, isHovering }) => {
369
+ if (props.hasBranches === true && branches.length < 2) return false;
370
+ if (props.user && message.role !== "user") return false;
371
+ if (props.assistant && message.role !== "assistant") return false;
372
+ if (props.lastOrHover === true && !isHovering && !isLast) return false;
373
+ if (props.copied === true && !isCopied) return false;
374
+ if (props.copied === false && isCopied) return false;
375
+ return true;
376
+ }
377
+ );
378
+ };
379
+
380
+ // src/primitive-hooks/thread/useThreadIf.tsx
381
+ var useThreadIf = (props) => {
382
+ const { useThread } = useThreadContext();
383
+ return useThread((thread) => {
384
+ if (props.empty === true && thread.messages.length !== 0) return false;
385
+ if (props.empty === false && thread.messages.length === 0) return false;
386
+ if (props.running === true && !thread.isRunning) return false;
387
+ if (props.running === false && thread.isRunning) return false;
388
+ return true;
389
+ });
390
+ };
391
+
392
+ // src/primitive-hooks/thread/useThreadEmpty.tsx
393
+ var useThreadEmpty = () => {
394
+ return useThreadIf({ empty: true });
395
+ };
396
+
397
+ // src/primitive-hooks/thread/useThreadScrollToBottom.tsx
398
+ var import_react15 = require("react");
399
+ var useThreadScrollToBottom = () => {
400
+ const { useViewport } = useThreadContext();
401
+ const isAtBottom = useViewport((s) => s.isAtBottom);
402
+ const handleScrollToBottom = (0, import_react15.useCallback)(() => {
403
+ const { scrollToBottom } = useViewport.getState();
404
+ scrollToBottom();
405
+ }, [useViewport]);
406
+ if (isAtBottom) return null;
407
+ return handleScrollToBottom;
408
+ };
409
+
410
+ // src/primitive-hooks/thread/useThreadSuggestion.tsx
411
+ var import_react16 = require("react");
412
+ var useThreadSuggestion = ({
413
+ prompt,
414
+ autoSend
415
+ }) => {
416
+ const { useThread, useComposer } = useThreadContext();
417
+ const disabled = useThread((t) => t.isRunning);
418
+ const callback = (0, import_react16.useCallback)(() => {
419
+ const thread = useThread.getState();
420
+ const composer = useComposer.getState();
421
+ composer.setValue(prompt);
422
+ if (autoSend && !thread.isRunning) {
423
+ composer.send();
424
+ }
425
+ }, [useThread, useComposer, prompt, autoSend]);
198
426
  if (disabled) return null;
199
427
  return callback;
200
428
  };
@@ -213,9 +441,9 @@ __export(thread_exports, {
213
441
 
214
442
  // src/primitives/thread/ThreadRoot.tsx
215
443
  var import_react_primitive = require("@radix-ui/react-primitive");
216
- var import_react10 = require("react");
444
+ var import_react17 = require("react");
217
445
  var import_jsx_runtime = require("react/jsx-runtime");
218
- var ThreadRoot = (0, import_react10.forwardRef)(
446
+ var ThreadRoot = (0, import_react17.forwardRef)(
219
447
  (props, ref) => {
220
448
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_primitive.Primitive.div, { ...props, ref });
221
449
  }
@@ -223,16 +451,6 @@ var ThreadRoot = (0, import_react10.forwardRef)(
223
451
  ThreadRoot.displayName = "ThreadRoot";
224
452
 
225
453
  // src/primitives/thread/ThreadIf.tsx
226
- var useThreadIf = (props) => {
227
- const { useThread } = useThreadContext();
228
- return useThread((thread) => {
229
- if (props.empty === true && thread.messages.length !== 0) return false;
230
- if (props.empty === false && thread.messages.length === 0) return false;
231
- if (props.running === true && !thread.isRunning) return false;
232
- if (props.running === false && thread.isRunning) return false;
233
- return true;
234
- });
235
- };
236
454
  var ThreadIf = ({ children, ...query }) => {
237
455
  const result = useThreadIf(query);
238
456
  return result ? children : null;
@@ -248,15 +466,15 @@ var ThreadEmpty = ({ children }) => {
248
466
  var import_primitive = require("@radix-ui/primitive");
249
467
  var import_react_compose_refs = require("@radix-ui/react-compose-refs");
250
468
  var import_react_primitive2 = require("@radix-ui/react-primitive");
251
- var import_react13 = require("react");
469
+ var import_react20 = require("react");
252
470
 
253
471
  // src/utils/hooks/useOnResizeContent.tsx
254
472
  var import_react_use_callback_ref = require("@radix-ui/react-use-callback-ref");
255
- var import_react11 = require("react");
473
+ var import_react18 = require("react");
256
474
  var useOnResizeContent = (ref, callback) => {
257
475
  const callbackRef = (0, import_react_use_callback_ref.useCallbackRef)(callback);
258
- const el = ref.current;
259
- (0, import_react11.useEffect)(() => {
476
+ (0, import_react18.useEffect)(() => {
477
+ const el = ref.current;
260
478
  if (!el) return;
261
479
  const resizeObserver = new ResizeObserver(() => {
262
480
  callbackRef();
@@ -285,16 +503,16 @@ var useOnResizeContent = (ref, callback) => {
285
503
  resizeObserver.disconnect();
286
504
  mutationObserver.disconnect();
287
505
  };
288
- }, [el, callbackRef]);
506
+ }, [ref, callbackRef]);
289
507
  };
290
508
 
291
509
  // src/utils/hooks/useOnScrollToBottom.tsx
292
510
  var import_react_use_callback_ref2 = require("@radix-ui/react-use-callback-ref");
293
- var import_react12 = require("react");
511
+ var import_react19 = require("react");
294
512
  var useOnScrollToBottom = (callback) => {
295
513
  const callbackRef = (0, import_react_use_callback_ref2.useCallbackRef)(callback);
296
514
  const { useViewport } = useThreadContext();
297
- (0, import_react12.useEffect)(() => {
515
+ (0, import_react19.useEffect)(() => {
298
516
  return useViewport.getState().onScrollToBottom(() => {
299
517
  callbackRef();
300
518
  });
@@ -303,14 +521,14 @@ var useOnScrollToBottom = (callback) => {
303
521
 
304
522
  // src/primitives/thread/ThreadViewport.tsx
305
523
  var import_jsx_runtime3 = require("react/jsx-runtime");
306
- var ThreadViewport = (0, import_react13.forwardRef)(({ autoScroll = true, onScroll, children, ...rest }, forwardedRef) => {
307
- const messagesEndRef = (0, import_react13.useRef)(null);
308
- const divRef = (0, import_react13.useRef)(null);
524
+ var ThreadViewport = (0, import_react20.forwardRef)(({ autoScroll = true, onScroll, children, ...rest }, forwardedRef) => {
525
+ const messagesEndRef = (0, import_react20.useRef)(null);
526
+ const divRef = (0, import_react20.useRef)(null);
309
527
  const ref = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, divRef);
310
528
  const { useViewport } = useThreadContext();
311
- const firstRenderRef = (0, import_react13.useRef)(true);
312
- const isScrollingToBottomRef = (0, import_react13.useRef)(false);
313
- const lastScrollTop = (0, import_react13.useRef)(0);
529
+ const firstRenderRef = (0, import_react20.useRef)(true);
530
+ const isScrollingToBottomRef = (0, import_react20.useRef)(false);
531
+ const lastScrollTop = (0, import_react20.useRef)(0);
314
532
  const scrollToBottom = () => {
315
533
  const div = messagesEndRef.current;
316
534
  if (!div || !autoScroll) return;
@@ -337,7 +555,9 @@ var ThreadViewport = (0, import_react13.forwardRef)(({ autoScroll = true, onScro
337
555
  if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {
338
556
  } else if (newIsAtBottom !== isAtBottom) {
339
557
  isScrollingToBottomRef.current = false;
340
- useViewport.setState({ isAtBottom: newIsAtBottom });
558
+ useViewport.setState({
559
+ isAtBottom: newIsAtBottom
560
+ });
341
561
  }
342
562
  lastScrollTop.current = div.scrollTop;
343
563
  };
@@ -357,13 +577,13 @@ var ThreadViewport = (0, import_react13.forwardRef)(({ autoScroll = true, onScro
357
577
  ThreadViewport.displayName = "ThreadViewport";
358
578
 
359
579
  // src/primitives/thread/ThreadMessages.tsx
360
- var import_react16 = require("react");
580
+ var import_react22 = require("react");
361
581
 
362
582
  // src/context/providers/MessageProvider.tsx
363
- var import_react14 = require("react");
364
- var import_zustand2 = require("zustand");
583
+ var import_react21 = require("react");
584
+ var import_zustand3 = require("zustand");
365
585
 
366
- // src/context/stores/MessageComposer.ts
586
+ // src/context/stores/EditComposer.ts
367
587
  var import_zustand = require("zustand");
368
588
 
369
589
  // src/context/stores/BaseComposer.ts
@@ -374,7 +594,7 @@ var makeBaseComposer = (set) => ({
374
594
  }
375
595
  });
376
596
 
377
- // src/context/stores/MessageComposer.ts
597
+ // src/context/stores/EditComposer.ts
378
598
  var makeEditComposerStore = ({
379
599
  onEdit,
380
600
  onSend
@@ -397,17 +617,34 @@ var makeEditComposerStore = ({
397
617
  }
398
618
  }));
399
619
 
620
+ // src/context/stores/MessageUtils.ts
621
+ var import_zustand2 = require("zustand");
622
+ var makeMessageUtilsStore = () => (0, import_zustand2.create)((set) => ({
623
+ inProgressIndicator: null,
624
+ setInProgressIndicator: (value) => {
625
+ set({ inProgressIndicator: value });
626
+ },
627
+ isCopied: false,
628
+ setIsCopied: (value) => {
629
+ set({ isCopied: value });
630
+ },
631
+ isHovering: false,
632
+ setIsHovering: (value) => {
633
+ set({ isHovering: value });
634
+ }
635
+ }));
636
+
400
637
  // src/context/providers/MessageProvider.tsx
401
638
  var import_jsx_runtime4 = require("react/jsx-runtime");
402
639
  var getIsLast = (thread, message) => {
403
640
  return thread.messages[thread.messages.length - 1]?.id === message.id;
404
641
  };
405
- var syncMessage = (thread, useMessage, messageIndex) => {
642
+ var syncMessage = (thread, getBranches, useMessage, messageIndex) => {
406
643
  const parentId = thread.messages[messageIndex - 1]?.id ?? null;
407
644
  const message = thread.messages[messageIndex];
408
645
  if (!message) return;
409
646
  const isLast = getIsLast(thread, message);
410
- const branches = thread.getBranches(message.id);
647
+ const branches = getBranches(message.id);
411
648
  const currentState = useMessage.getState();
412
649
  if (currentState.message === message && currentState.parentId === parentId && currentState.branches === branches && currentState.isLast === isLast)
413
650
  return;
@@ -419,27 +656,11 @@ var syncMessage = (thread, useMessage, messageIndex) => {
419
656
  });
420
657
  };
421
658
  var useMessageContext2 = (messageIndex) => {
422
- const { useThread } = useThreadContext();
423
- const [context] = (0, import_react14.useState)(() => {
424
- const useMessage = (0, import_zustand2.create)((set) => ({
425
- message: null,
426
- parentId: null,
427
- branches: [],
428
- isLast: false,
429
- inProgressIndicator: null,
430
- isCopied: false,
431
- isHovering: false,
432
- setInProgressIndicator: (value) => {
433
- set({ inProgressIndicator: value });
434
- },
435
- setIsCopied: (value) => {
436
- set({ isCopied: value });
437
- },
438
- setIsHovering: (value) => {
439
- set({ isHovering: value });
440
- }
441
- }));
442
- const useComposer = makeEditComposerStore({
659
+ const { useThread, useThreadActions } = useThreadContext();
660
+ const [context] = (0, import_react21.useState)(() => {
661
+ const useMessage = (0, import_zustand3.create)(() => ({}));
662
+ const useMessageUtils = makeMessageUtilsStore();
663
+ const useEditComposer = makeEditComposerStore({
443
664
  onEdit: () => {
444
665
  const message = useMessage.getState().message;
445
666
  if (message.role !== "user")
@@ -458,20 +679,30 @@ var useMessageContext2 = (messageIndex) => {
458
679
  const nonTextParts = message.content.filter(
459
680
  (part) => part.type !== "text" && part.type !== "ui"
460
681
  );
461
- useThread.getState().append({
682
+ useThreadActions.getState().append({
462
683
  parentId,
463
684
  content: [{ type: "text", text }, ...nonTextParts]
464
685
  });
465
686
  }
466
687
  });
467
- syncMessage(useThread.getState(), useMessage, messageIndex);
468
- return { useMessage, useComposer };
688
+ syncMessage(
689
+ useThread.getState(),
690
+ useThreadActions.getState().getBranches,
691
+ useMessage,
692
+ messageIndex
693
+ );
694
+ return { useMessage, useMessageUtils, useEditComposer };
469
695
  });
470
- (0, import_react14.useEffect)(() => {
696
+ (0, import_react21.useEffect)(() => {
471
697
  return useThread.subscribe((thread) => {
472
- syncMessage(thread, context.useMessage, messageIndex);
698
+ syncMessage(
699
+ thread,
700
+ useThreadActions.getState().getBranches,
701
+ context.useMessage,
702
+ messageIndex
703
+ );
473
704
  });
474
- }, [context, useThread, messageIndex]);
705
+ }, [useThread, useThreadActions, context, messageIndex]);
475
706
  return context;
476
707
  };
477
708
  var MessageProvider = ({
@@ -482,47 +713,13 @@ var MessageProvider = ({
482
713
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MessageContext.Provider, { value: context, children });
483
714
  };
484
715
 
485
- // src/context/ComposerContext.ts
486
- var import_react15 = require("react");
487
- var useComposerContext = () => {
488
- const { useComposer } = useThreadContext();
489
- const { useComposer: useEditComposer } = (0, import_react15.useContext)(MessageContext) ?? {};
490
- return (0, import_react15.useMemo)(
491
- () => ({
492
- useComposer: useEditComposer ?? useComposer,
493
- type: useEditComposer ? "edit" : "new"
494
- }),
495
- [useEditComposer, useComposer]
496
- );
497
- };
498
-
499
716
  // src/primitives/composer/ComposerIf.tsx
500
- var useComposerIf = (props) => {
501
- const { useComposer } = useComposerContext();
502
- return useComposer((composer) => {
503
- if (props.editing === true && !composer.isEditing) return false;
504
- if (props.editing === false && composer.isEditing) return false;
505
- return true;
506
- });
507
- };
508
717
  var ComposerIf = ({ children, ...query }) => {
509
718
  const result = useComposerIf(query);
510
719
  return result ? children : null;
511
720
  };
512
721
 
513
722
  // src/primitives/message/MessageIf.tsx
514
- var useMessageIf = (props) => {
515
- const { useMessage } = useMessageContext();
516
- return useMessage(({ message, branches, isLast, isCopied, isHovering }) => {
517
- if (props.hasBranches === true && branches.length < 2) return false;
518
- if (props.user && message.role !== "user") return false;
519
- if (props.assistant && message.role !== "assistant") return false;
520
- if (props.lastOrHover === true && !isHovering && !isLast) return false;
521
- if (props.copied === true && !isCopied) return false;
522
- if (props.copied === false && isCopied) return false;
523
- return true;
524
- });
525
- };
526
723
  var MessageIf = ({ children, ...query }) => {
527
724
  const result = useMessageIf(query);
528
725
  return result ? children : null;
@@ -550,7 +747,7 @@ var ThreadMessageImpl = ({
550
747
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageIf, { assistant: true, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AssistantMessage, {}) })
551
748
  ] });
552
749
  };
553
- var ThreadMessage = (0, import_react16.memo)(
750
+ var ThreadMessage = (0, import_react22.memo)(
554
751
  ThreadMessageImpl,
555
752
  (prev, next) => prev.messageIndex === next.messageIndex && prev.components.UserMessage === next.components.UserMessage && prev.components.EditComposer === next.components.EditComposer && prev.components.AssistantMessage === next.components.AssistantMessage
556
753
  );
@@ -571,56 +768,42 @@ var ThreadMessages = ({ components }) => {
571
768
  });
572
769
  };
573
770
 
574
- // src/primitives/thread/ThreadScrollToBottom.tsx
771
+ // src/utils/createActionButton.tsx
575
772
  var import_primitive2 = require("@radix-ui/primitive");
576
773
  var import_react_primitive3 = require("@radix-ui/react-primitive");
577
- var import_react17 = require("react");
774
+ var import_react23 = require("react");
578
775
  var import_jsx_runtime6 = require("react/jsx-runtime");
579
- var ThreadScrollToBottom = (0, import_react17.forwardRef)(({ onClick, ...rest }, ref) => {
580
- const { useViewport } = useThreadContext();
581
- const isAtBottom = useViewport((s) => s.isAtBottom);
582
- const handleScrollToBottom = () => {
583
- useViewport.getState().scrollToBottom();
584
- };
585
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
586
- import_react_primitive3.Primitive.button,
587
- {
588
- ...rest,
589
- disabled: isAtBottom,
590
- ref,
591
- onClick: (0, import_primitive2.composeEventHandlers)(onClick, handleScrollToBottom)
592
- }
593
- );
594
- });
595
- ThreadScrollToBottom.displayName = "ThreadScrollToBottom";
776
+ var createActionButton = (displayName, useActionButton) => {
777
+ const ActionButton = (0, import_react23.forwardRef)((props, forwardedRef) => {
778
+ const callback = useActionButton(props);
779
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
780
+ import_react_primitive3.Primitive.button,
781
+ {
782
+ type: "button",
783
+ disabled: !callback,
784
+ ...props,
785
+ ref: forwardedRef,
786
+ onClick: (0, import_primitive2.composeEventHandlers)(props.onClick, () => {
787
+ callback?.();
788
+ })
789
+ }
790
+ );
791
+ });
792
+ ActionButton.displayName = displayName;
793
+ return ActionButton;
794
+ };
795
+
796
+ // src/primitives/thread/ThreadScrollToBottom.tsx
797
+ var ThreadScrollToBottom = createActionButton(
798
+ "ThreadScrollToBottom",
799
+ useThreadScrollToBottom
800
+ );
596
801
 
597
802
  // src/primitives/thread/ThreadSuggestion.tsx
598
- var import_primitive3 = require("@radix-ui/primitive");
599
- var import_react_primitive4 = require("@radix-ui/react-primitive");
600
- var import_react18 = require("react");
601
- var import_jsx_runtime7 = require("react/jsx-runtime");
602
- var ThreadSuggestion = (0, import_react18.forwardRef)(({ onClick, prompt, method, autoSend: send, ...rest }, ref) => {
603
- const { useThread, useComposer } = useThreadContext();
604
- const isDisabled = useThread((t) => t.isRunning);
605
- const handleApplySuggestion = () => {
606
- const thread = useThread.getState();
607
- const composer = useComposer.getState();
608
- composer.setValue(prompt);
609
- if (send && !thread.isRunning) {
610
- composer.send();
611
- }
612
- };
613
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
614
- import_react_primitive4.Primitive.button,
615
- {
616
- ...rest,
617
- disabled: isDisabled,
618
- ref,
619
- onClick: (0, import_primitive3.composeEventHandlers)(onClick, handleApplySuggestion)
620
- }
621
- );
622
- });
623
- ThreadSuggestion.displayName = "ThreadSuggestion";
803
+ var ThreadSuggestion = createActionButton(
804
+ "ThreadSuggestion",
805
+ useThreadSuggestion
806
+ );
624
807
 
625
808
  // src/primitives/composer/index.ts
626
809
  var composer_exports = {};
@@ -633,16 +816,16 @@ __export(composer_exports, {
633
816
  });
634
817
 
635
818
  // src/primitives/composer/ComposerRoot.tsx
636
- var import_primitive4 = require("@radix-ui/primitive");
819
+ var import_primitive3 = require("@radix-ui/primitive");
637
820
  var import_react_compose_refs2 = require("@radix-ui/react-compose-refs");
638
- var import_react_primitive5 = require("@radix-ui/react-primitive");
639
- var import_react19 = require("react");
640
- var import_jsx_runtime8 = require("react/jsx-runtime");
641
- var ComposerRoot = (0, import_react19.forwardRef)(
821
+ var import_react_primitive4 = require("@radix-ui/react-primitive");
822
+ var import_react24 = require("react");
823
+ var import_jsx_runtime7 = require("react/jsx-runtime");
824
+ var ComposerRoot = (0, import_react24.forwardRef)(
642
825
  ({ onSubmit, ...rest }, forwardedRef) => {
643
826
  const { useViewport } = useThreadContext();
644
827
  const { useComposer } = useComposerContext();
645
- const formRef = (0, import_react19.useRef)(null);
828
+ const formRef = (0, import_react24.useRef)(null);
646
829
  const ref = (0, import_react_compose_refs2.useComposedRefs)(forwardedRef, formRef);
647
830
  const handleSubmit = (e) => {
648
831
  const composerState = useComposer.getState();
@@ -651,12 +834,12 @@ var ComposerRoot = (0, import_react19.forwardRef)(
651
834
  composerState.send();
652
835
  useViewport.getState().scrollToBottom();
653
836
  };
654
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
655
- import_react_primitive5.Primitive.form,
837
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
838
+ import_react_primitive4.Primitive.form,
656
839
  {
657
840
  ...rest,
658
841
  ref,
659
- onSubmit: (0, import_primitive4.composeEventHandlers)(onSubmit, handleSubmit)
842
+ onSubmit: (0, import_primitive3.composeEventHandlers)(onSubmit, handleSubmit)
660
843
  }
661
844
  );
662
845
  }
@@ -664,13 +847,13 @@ var ComposerRoot = (0, import_react19.forwardRef)(
664
847
  ComposerRoot.displayName = "ComposerRoot";
665
848
 
666
849
  // src/primitives/composer/ComposerInput.tsx
667
- var import_primitive5 = require("@radix-ui/primitive");
850
+ var import_primitive4 = require("@radix-ui/primitive");
668
851
  var import_react_compose_refs3 = require("@radix-ui/react-compose-refs");
669
852
  var import_react_slot = require("@radix-ui/react-slot");
670
- var import_react20 = require("react");
853
+ var import_react25 = require("react");
671
854
  var import_react_textarea_autosize = __toESM(require("react-textarea-autosize"));
672
- var import_jsx_runtime9 = require("react/jsx-runtime");
673
- var ComposerInput = (0, import_react20.forwardRef)(
855
+ var import_jsx_runtime8 = require("react/jsx-runtime");
856
+ var ComposerInput = (0, import_react25.forwardRef)(
674
857
  ({ autoFocus = false, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
675
858
  const { useThread } = useThreadContext();
676
859
  const { useComposer, type } = useComposerContext();
@@ -679,7 +862,7 @@ var ComposerInput = (0, import_react20.forwardRef)(
679
862
  return c.value;
680
863
  });
681
864
  const Component = asChild ? import_react_slot.Slot : import_react_textarea_autosize.default;
682
- const textareaRef = (0, import_react20.useRef)(null);
865
+ const textareaRef = (0, import_react25.useRef)(null);
683
866
  const ref = (0, import_react_compose_refs3.useComposedRefs)(forwardedRef, textareaRef);
684
867
  const handleKeyPress = (e) => {
685
868
  if (disabled) return;
@@ -697,23 +880,22 @@ var ComposerInput = (0, import_react20.forwardRef)(
697
880
  }
698
881
  };
699
882
  const autoFocusEnabled = autoFocus && !disabled;
700
- const focus = (0, import_react20.useCallback)(() => {
883
+ const focus = (0, import_react25.useCallback)(() => {
701
884
  const textarea = textareaRef.current;
702
885
  if (!textarea || !autoFocusEnabled) return;
703
- console.log("focus");
704
886
  textarea.focus();
705
887
  textarea.setSelectionRange(
706
888
  textareaRef.current.value.length,
707
889
  textareaRef.current.value.length
708
890
  );
709
891
  }, [autoFocusEnabled]);
710
- (0, import_react20.useEffect)(() => focus(), [focus]);
892
+ (0, import_react25.useEffect)(() => focus(), [focus]);
711
893
  useOnScrollToBottom(() => {
712
894
  if (type === "new") {
713
895
  focus();
714
896
  }
715
897
  });
716
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
898
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
717
899
  Component,
718
900
  {
719
901
  value,
@@ -721,12 +903,12 @@ var ComposerInput = (0, import_react20.forwardRef)(
721
903
  ref,
722
904
  autoFocus,
723
905
  disabled,
724
- onChange: (0, import_primitive5.composeEventHandlers)(onChange, (e) => {
906
+ onChange: (0, import_primitive4.composeEventHandlers)(onChange, (e) => {
725
907
  const composerState = useComposer.getState();
726
908
  if (!composerState.isEditing) return;
727
909
  return composerState.setValue(e.target.value);
728
910
  }),
729
- onKeyDown: (0, import_primitive5.composeEventHandlers)(onKeyDown, handleKeyPress)
911
+ onKeyDown: (0, import_primitive4.composeEventHandlers)(onKeyDown, handleKeyPress)
730
912
  }
731
913
  );
732
914
  }
@@ -734,47 +916,13 @@ var ComposerInput = (0, import_react20.forwardRef)(
734
916
  ComposerInput.displayName = "ComposerInput";
735
917
 
736
918
  // src/primitives/composer/ComposerSend.tsx
737
- var import_react_primitive6 = require("@radix-ui/react-primitive");
738
- var import_react21 = require("react");
739
- var import_jsx_runtime10 = require("react/jsx-runtime");
740
- var ComposerSend = (0, import_react21.forwardRef)(
741
- ({ disabled, ...rest }, ref) => {
742
- const { useComposer } = useComposerContext();
743
- const hasValue = useComposer((c) => c.isEditing && c.value.length > 0);
744
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
745
- import_react_primitive6.Primitive.button,
746
- {
747
- type: "submit",
748
- ...rest,
749
- ref,
750
- disabled: disabled || !hasValue
751
- }
752
- );
753
- }
754
- );
755
- ComposerSend.displayName = "ComposerSend";
919
+ var ComposerSend = createActionButton("ComposerSend", useComposerSend);
756
920
 
757
921
  // src/primitives/composer/ComposerCancel.tsx
758
- var import_primitive6 = require("@radix-ui/primitive");
759
- var import_react_primitive7 = require("@radix-ui/react-primitive");
760
- var import_react22 = require("react");
761
- var import_jsx_runtime11 = require("react/jsx-runtime");
762
- var ComposerCancel = (0, import_react22.forwardRef)(({ onClick, ...rest }, ref) => {
763
- const { useComposer } = useComposerContext();
764
- const handleCancel = () => {
765
- useComposer.getState().cancel();
766
- };
767
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
768
- import_react_primitive7.Primitive.button,
769
- {
770
- type: "button",
771
- ...rest,
772
- ref,
773
- onClick: (0, import_primitive6.composeEventHandlers)(onClick, handleCancel)
774
- }
775
- );
776
- });
777
- ComposerCancel.displayName = "ComposerCancel";
922
+ var ComposerCancel = createActionButton(
923
+ "ComposerCancel",
924
+ useComposerCancel
925
+ );
778
926
 
779
927
  // src/primitives/message/index.ts
780
928
  var message_exports = {};
@@ -786,27 +934,27 @@ __export(message_exports, {
786
934
  });
787
935
 
788
936
  // src/primitives/message/MessageRoot.tsx
789
- var import_primitive7 = require("@radix-ui/primitive");
790
- var import_react_primitive8 = require("@radix-ui/react-primitive");
791
- var import_react23 = require("react");
792
- var import_jsx_runtime12 = require("react/jsx-runtime");
793
- var MessageRoot = (0, import_react23.forwardRef)(
937
+ var import_primitive5 = require("@radix-ui/primitive");
938
+ var import_react_primitive5 = require("@radix-ui/react-primitive");
939
+ var import_react26 = require("react");
940
+ var import_jsx_runtime9 = require("react/jsx-runtime");
941
+ var MessageRoot = (0, import_react26.forwardRef)(
794
942
  ({ onMouseEnter, onMouseLeave, ...rest }, ref) => {
795
- const { useMessage } = useMessageContext();
796
- const setIsHovering = useMessage((s) => s.setIsHovering);
943
+ const { useMessageUtils } = useMessageContext();
944
+ const setIsHovering = useMessageUtils((s) => s.setIsHovering);
797
945
  const handleMouseEnter = () => {
798
946
  setIsHovering(true);
799
947
  };
800
948
  const handleMouseLeave = () => {
801
949
  setIsHovering(false);
802
950
  };
803
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
804
- import_react_primitive8.Primitive.div,
951
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
952
+ import_react_primitive5.Primitive.div,
805
953
  {
806
954
  ...rest,
807
955
  ref,
808
- onMouseEnter: (0, import_primitive7.composeEventHandlers)(onMouseEnter, handleMouseEnter),
809
- onMouseLeave: (0, import_primitive7.composeEventHandlers)(onMouseLeave, handleMouseLeave)
956
+ onMouseEnter: (0, import_primitive5.composeEventHandlers)(onMouseEnter, handleMouseEnter),
957
+ onMouseLeave: (0, import_primitive5.composeEventHandlers)(onMouseLeave, handleMouseLeave)
810
958
  }
811
959
  );
812
960
  }
@@ -814,40 +962,12 @@ var MessageRoot = (0, import_react23.forwardRef)(
814
962
  MessageRoot.displayName = "MessageRoot";
815
963
 
816
964
  // src/primitives/message/MessageContent.tsx
817
- var import_react28 = require("react");
818
-
819
- // src/context/AssistantContext.ts
820
- var import_react24 = require("react");
821
- var AssistantContext = (0, import_react24.createContext)(
822
- null
823
- );
824
- var useAssistantContext = () => {
825
- const context = (0, import_react24.useContext)(AssistantContext);
826
- if (!context)
827
- throw new Error(
828
- "This component must be used within an AssistantRuntimeProvider."
829
- );
830
- return context;
831
- };
832
-
833
- // src/context/ContentPartContext.ts
834
- var import_react25 = require("react");
835
- var ContentPartContext = (0, import_react25.createContext)(
836
- null
837
- );
838
- var useContentPartContext = () => {
839
- const context = (0, import_react25.useContext)(ContentPartContext);
840
- if (!context)
841
- throw new Error(
842
- "This component can only be used inside a component passed to <MessagePrimitive.Content components={...} >."
843
- );
844
- return context;
845
- };
965
+ var import_react29 = require("react");
846
966
 
847
967
  // src/context/providers/ContentPartProvider.tsx
848
- var import_react26 = require("react");
849
- var import_zustand3 = require("zustand");
850
- var import_jsx_runtime13 = require("react/jsx-runtime");
968
+ var import_react27 = require("react");
969
+ var import_zustand4 = require("zustand");
970
+ var import_jsx_runtime10 = require("react/jsx-runtime");
851
971
  var syncContentPart = ({ message }, useContentPart, partIndex) => {
852
972
  const part = message.content[partIndex];
853
973
  if (!part) return;
@@ -855,19 +975,24 @@ var syncContentPart = ({ message }, useContentPart, partIndex) => {
855
975
  const status = partIndex === message.content.length - 1 ? messageStatus : "done";
856
976
  const currentState = useContentPart.getState();
857
977
  if (currentState.part === part && currentState.status === status) return;
858
- useContentPart.setState({ part, status });
978
+ useContentPart.setState(
979
+ Object.freeze({
980
+ part,
981
+ status
982
+ })
983
+ );
859
984
  };
860
985
  var useContentPartContext2 = (partIndex) => {
861
986
  const { useMessage } = useMessageContext();
862
- const [context] = (0, import_react26.useState)(() => {
863
- const useContentPart = (0, import_zustand3.create)(() => ({
864
- part: { type: "text", text: "" },
865
- status: "done"
866
- }));
987
+ const [context] = (0, import_react27.useState)(() => {
988
+ const useContentPart = (0, import_zustand4.create)(
989
+ () => ({})
990
+ );
867
991
  syncContentPart(useMessage.getState(), useContentPart, partIndex);
868
992
  return { useContentPart };
869
993
  });
870
- (0, import_react26.useEffect)(() => {
994
+ (0, import_react27.useEffect)(() => {
995
+ syncContentPart(useMessage.getState(), context.useContentPart, partIndex);
871
996
  return useMessage.subscribe((message) => {
872
997
  syncContentPart(message, context.useContentPart, partIndex);
873
998
  });
@@ -879,65 +1004,46 @@ var ContentPartProvider = ({
879
1004
  children
880
1005
  }) => {
881
1006
  const context = useContentPartContext2(partIndex);
882
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ContentPartContext.Provider, { value: context, children });
1007
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ContentPartContext.Provider, { value: context, children });
883
1008
  };
884
1009
 
885
1010
  // src/primitives/contentPart/ContentPartDisplay.tsx
886
1011
  var ContentPartDisplay = () => {
887
- const { useContentPart } = useContentPartContext();
888
- const display = useContentPart((c) => {
889
- if (c.part.type !== "ui")
890
- throw new Error(
891
- "ContentPartDisplay can only be used inside ui content parts."
892
- );
893
- return c.part.display;
894
- });
1012
+ const display = useContentPartDisplay();
895
1013
  return display ?? null;
896
1014
  };
897
1015
 
898
1016
  // src/primitives/contentPart/ContentPartInProgressIndicator.tsx
899
1017
  var ContentPartInProgressIndicator = () => {
900
- const { useMessage } = useMessageContext();
901
- const { useContentPart } = useContentPartContext();
902
- const indicator = useCombinedStore(
903
- [useMessage, useContentPart],
904
- (m, c) => c.status === "in_progress" ? m.inProgressIndicator : null
905
- );
1018
+ const indicator = useContentPartInProgressIndicator();
906
1019
  return indicator;
907
1020
  };
908
1021
 
909
1022
  // src/primitives/contentPart/ContentPartText.tsx
910
- var import_react_primitive9 = require("@radix-ui/react-primitive");
911
- var import_react27 = require("react");
912
- var import_jsx_runtime14 = require("react/jsx-runtime");
913
- var ContentPartText = (0, import_react27.forwardRef)((props, forwardedRef) => {
914
- const { useContentPart } = useContentPartContext();
915
- const text = useContentPart((c) => {
916
- if (c.part.type !== "text")
917
- throw new Error(
918
- "ContentPartText can only be used inside text content parts."
919
- );
920
- return c.part.text;
921
- });
922
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_primitive9.Primitive.span, { ...props, ref: forwardedRef, children: text });
1023
+ var import_react_primitive6 = require("@radix-ui/react-primitive");
1024
+ var import_react28 = require("react");
1025
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1026
+ var ContentPartText = (0, import_react28.forwardRef)((props, forwardedRef) => {
1027
+ const text = useContentPartText();
1028
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_primitive6.Primitive.span, { ...props, ref: forwardedRef, children: text });
923
1029
  });
924
1030
  ContentPartText.displayName = "ContentPartText";
925
1031
 
926
1032
  // src/primitives/message/MessageContent.tsx
927
- var import_jsx_runtime15 = require("react/jsx-runtime");
1033
+ var import_jsx_runtime12 = require("react/jsx-runtime");
928
1034
  var defaultComponents = {
929
- Text: () => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
930
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ContentPartText, {}),
931
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ContentPartInProgressIndicator, {})
1035
+ Text: () => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1036
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ContentPartText, {}),
1037
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ContentPartInProgressIndicator, {})
932
1038
  ] }),
933
1039
  Image: () => null,
934
- UI: () => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ContentPartDisplay, {}),
1040
+ UI: () => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ContentPartDisplay, {}),
935
1041
  tools: {
936
1042
  Fallback: (props) => {
937
1043
  const { useToolUIs } = useAssistantContext();
938
1044
  const Render = useToolUIs((s) => s.getToolUI(props.part.toolName));
939
1045
  if (!Render) return null;
940
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Render, { ...props });
1046
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Render, { ...props });
941
1047
  }
942
1048
  }
943
1049
  };
@@ -949,22 +1055,22 @@ var MessageContentPartComponent = ({
949
1055
  tools: { by_name = {}, Fallback = defaultComponents.tools.Fallback } = {}
950
1056
  } = {}
951
1057
  }) => {
952
- const { useThread } = useThreadContext();
953
- const addToolResult = useThread((t) => t.addToolResult);
1058
+ const { useThreadActions } = useThreadContext();
1059
+ const addToolResult = useThreadActions((t) => t.addToolResult);
954
1060
  const { useContentPart } = useContentPartContext();
955
1061
  const { part, status } = useContentPart();
956
1062
  const type = part.type;
957
1063
  switch (type) {
958
1064
  case "text":
959
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { part, status });
1065
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { part, status });
960
1066
  case "image":
961
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Image, { part, status });
1067
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Image, { part, status });
962
1068
  case "ui":
963
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(UI, { part, status });
1069
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(UI, { part, status });
964
1070
  case "tool-call": {
965
1071
  const Tool = by_name[part.toolName] || Fallback;
966
1072
  const addResult = (result) => addToolResult(part.toolCallId, result);
967
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Tool, { part, status, addResult });
1073
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Tool, { part, status, addResult });
968
1074
  }
969
1075
  default:
970
1076
  throw new Error(`Unknown content part type: ${type}`);
@@ -974,9 +1080,9 @@ var MessageContentPartImpl = ({
974
1080
  partIndex,
975
1081
  components
976
1082
  }) => {
977
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ContentPartProvider, { partIndex, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(MessageContentPartComponent, { components }) });
1083
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ContentPartProvider, { partIndex, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(MessageContentPartComponent, { components }) });
978
1084
  };
979
- var MessageContentPart = (0, import_react28.memo)(
1085
+ var MessageContentPart = (0, import_react29.memo)(
980
1086
  MessageContentPartImpl,
981
1087
  (prev, next) => prev.partIndex === next.partIndex && prev.components?.Text === next.components?.Text && prev.components?.Image === next.components?.Image && prev.components?.UI === next.components?.UI && prev.components?.tools === next.components?.tools
982
1088
  );
@@ -985,7 +1091,7 @@ var MessageContent = ({ components }) => {
985
1091
  const contentLength = useMessage((s) => s.message.content.length);
986
1092
  return new Array(contentLength).fill(null).map((_, idx) => {
987
1093
  const partIndex = idx;
988
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1094
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
989
1095
  MessageContentPart,
990
1096
  {
991
1097
  partIndex,
@@ -997,14 +1103,14 @@ var MessageContent = ({ components }) => {
997
1103
  };
998
1104
 
999
1105
  // src/primitives/message/MessageInProgress.tsx
1000
- var import_react_primitive10 = require("@radix-ui/react-primitive");
1001
- var import_react29 = require("react");
1002
- var import_jsx_runtime16 = require("react/jsx-runtime");
1003
- var MessageInProgress = (0, import_react29.forwardRef)((props, ref) => {
1004
- const { useMessage } = useMessageContext();
1005
- (0, import_react29.useMemo)(() => {
1006
- useMessage.getState().setInProgressIndicator(/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_primitive10.Primitive.span, { ...props, ref }));
1007
- }, [useMessage, props, ref]);
1106
+ var import_react_primitive7 = require("@radix-ui/react-primitive");
1107
+ var import_react30 = require("react");
1108
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1109
+ var MessageInProgress = (0, import_react30.forwardRef)((props, ref) => {
1110
+ const { useMessageUtils } = useMessageContext();
1111
+ (0, import_react30.useMemo)(() => {
1112
+ useMessageUtils.getState().setInProgressIndicator(/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_primitive7.Primitive.span, { ...props, ref }));
1113
+ }, [useMessageUtils, props, ref]);
1008
1114
  return null;
1009
1115
  });
1010
1116
  MessageInProgress.displayName = "MessageInProgress";
@@ -1019,57 +1125,38 @@ __export(branchPicker_exports, {
1019
1125
  Root: () => BranchPickerRoot
1020
1126
  });
1021
1127
 
1022
- // src/utils/createActionButton.tsx
1023
- var import_primitive8 = require("@radix-ui/primitive");
1024
- var import_react_primitive11 = require("@radix-ui/react-primitive");
1025
- var import_react30 = require("react");
1026
- var import_jsx_runtime17 = require("react/jsx-runtime");
1027
- var createActionButton = (useActionButton) => {
1028
- const ActionButton = (0, import_react30.forwardRef)((props, forwardedRef) => {
1029
- const onClick = useActionButton(props);
1030
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1031
- import_react_primitive11.Primitive.button,
1032
- {
1033
- type: "button",
1034
- disabled: !onClick,
1035
- ...props,
1036
- ref: forwardedRef,
1037
- onClick: (0, import_primitive8.composeEventHandlers)(props.onClick, onClick ?? void 0)
1038
- }
1039
- );
1040
- });
1041
- ActionButton.displayName = "ActionButton";
1042
- return ActionButton;
1043
- };
1044
-
1045
1128
  // src/primitives/branchPicker/BranchPickerNext.tsx
1046
- var BranchPickerNext = createActionButton(useGoToNextBranch);
1129
+ var BranchPickerNext = createActionButton(
1130
+ "BranchPickerNext",
1131
+ useBranchPickerNext
1132
+ );
1047
1133
 
1048
1134
  // src/primitives/branchPicker/BranchPickerPrevious.tsx
1049
- var BranchPickerPrevious = createActionButton(useGoToPreviousBranch);
1135
+ var BranchPickerPrevious = createActionButton(
1136
+ "BranchPickerPrevious",
1137
+ useBranchPickerPrevious
1138
+ );
1050
1139
 
1051
1140
  // src/primitives/branchPicker/BranchPickerCount.tsx
1052
- var import_jsx_runtime18 = require("react/jsx-runtime");
1141
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1053
1142
  var BranchPickerCount = () => {
1054
- const { useMessage } = useMessageContext();
1055
- const branchCount = useMessage((s) => s.branches.length);
1056
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_jsx_runtime18.Fragment, { children: branchCount });
1143
+ const branchCount = useBranchPickerCount();
1144
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_jsx_runtime14.Fragment, { children: branchCount });
1057
1145
  };
1058
1146
 
1059
1147
  // src/primitives/branchPicker/BranchPickerNumber.tsx
1060
- var import_jsx_runtime19 = require("react/jsx-runtime");
1148
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1061
1149
  var BranchPickerNumber = () => {
1062
- const { useMessage } = useMessageContext();
1063
- const branchIdx = useMessage((s) => s.branches.indexOf(s.message.id));
1064
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_jsx_runtime19.Fragment, { children: branchIdx + 1 });
1150
+ const branchNumber = useBranchPickerNumber();
1151
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, { children: branchNumber });
1065
1152
  };
1066
1153
 
1067
1154
  // src/primitives/branchPicker/BranchPickerRoot.tsx
1068
- var import_react_primitive12 = require("@radix-ui/react-primitive");
1155
+ var import_react_primitive8 = require("@radix-ui/react-primitive");
1069
1156
  var import_react31 = require("react");
1070
- var import_jsx_runtime20 = require("react/jsx-runtime");
1157
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1071
1158
  var BranchPickerRoot = (0, import_react31.forwardRef)(({ hideWhenSingleBranch, ...rest }, ref) => {
1072
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_primitive12.Primitive.div, { ...rest, ref }) });
1159
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_primitive8.Primitive.div, { ...rest, ref }) });
1073
1160
  });
1074
1161
  BranchPickerRoot.displayName = "BranchPickerRoot";
1075
1162
 
@@ -1083,27 +1170,38 @@ __export(actionBar_exports, {
1083
1170
  });
1084
1171
 
1085
1172
  // src/primitives/actionBar/ActionBarRoot.tsx
1086
- var import_react_primitive13 = require("@radix-ui/react-primitive");
1173
+ var import_react_primitive9 = require("@radix-ui/react-primitive");
1087
1174
  var import_react32 = require("react");
1088
- var import_jsx_runtime21 = require("react/jsx-runtime");
1089
- var ActionBarRoot = (0, import_react32.forwardRef)(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
1175
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1176
+ var useActionBarFloatStatus = ({
1177
+ hideWhenRunning,
1178
+ autohide,
1179
+ autohideFloat
1180
+ }) => {
1090
1181
  const { useThread } = useThreadContext();
1091
- const { useMessage } = useMessageContext();
1092
- const hideAndfloatStatus = useCombinedStore(
1093
- [useThread, useMessage],
1094
- (t, m) => {
1182
+ const { useMessage, useMessageUtils } = useMessageContext();
1183
+ return useCombinedStore(
1184
+ [useThread, useMessage, useMessageUtils],
1185
+ (t, m, mu) => {
1095
1186
  if (hideWhenRunning && t.isRunning) return "hidden" /* Hidden */;
1096
1187
  const autohideEnabled = autohide === "always" || autohide === "not-last" && !m.isLast;
1097
1188
  if (!autohideEnabled) return "normal" /* Normal */;
1098
- if (!m.isHovering) return "hidden" /* Hidden */;
1189
+ if (!mu.isHovering) return "hidden" /* Hidden */;
1099
1190
  if (autohideFloat === "always" || autohideFloat === "single-branch" && m.branches.length <= 1)
1100
1191
  return "floating" /* Floating */;
1101
1192
  return "normal" /* Normal */;
1102
1193
  }
1103
1194
  );
1195
+ };
1196
+ var ActionBarRoot = (0, import_react32.forwardRef)(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
1197
+ const hideAndfloatStatus = useActionBarFloatStatus({
1198
+ hideWhenRunning,
1199
+ autohide,
1200
+ autohideFloat
1201
+ });
1104
1202
  if (hideAndfloatStatus === "hidden" /* Hidden */) return null;
1105
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1106
- import_react_primitive13.Primitive.div,
1203
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1204
+ import_react_primitive9.Primitive.div,
1107
1205
  {
1108
1206
  ...hideAndfloatStatus === "floating" /* Floating */ ? { "data-floating": "true" } : null,
1109
1207
  ...rest,
@@ -1114,13 +1212,22 @@ var ActionBarRoot = (0, import_react32.forwardRef)(({ hideWhenRunning, autohide,
1114
1212
  ActionBarRoot.displayName = "ActionBarRoot";
1115
1213
 
1116
1214
  // src/primitives/actionBar/ActionBarCopy.tsx
1117
- var ActionBarCopy = createActionButton(useCopyMessage);
1215
+ var ActionBarCopy = createActionButton(
1216
+ "ActionBarCopy",
1217
+ useActionBarCopy
1218
+ );
1118
1219
 
1119
1220
  // src/primitives/actionBar/ActionBarReload.tsx
1120
- var ActionBarReload = createActionButton(useReloadMessage);
1221
+ var ActionBarReload = createActionButton(
1222
+ "ActionBarReload",
1223
+ useActionBarReload
1224
+ );
1121
1225
 
1122
1226
  // src/primitives/actionBar/ActionBarEdit.tsx
1123
- var ActionBarEdit = createActionButton(useBeginMessageEdit);
1227
+ var ActionBarEdit = createActionButton(
1228
+ "ActionBarEdit",
1229
+ useActionBarEdit
1230
+ );
1124
1231
 
1125
1232
  // src/primitives/contentPart/index.ts
1126
1233
  var contentPart_exports = {};
@@ -1132,19 +1239,12 @@ __export(contentPart_exports, {
1132
1239
  });
1133
1240
 
1134
1241
  // src/primitives/contentPart/ContentPartImage.tsx
1135
- var import_react_primitive14 = require("@radix-ui/react-primitive");
1242
+ var import_react_primitive10 = require("@radix-ui/react-primitive");
1136
1243
  var import_react33 = require("react");
1137
- var import_jsx_runtime22 = require("react/jsx-runtime");
1244
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1138
1245
  var ContentPartImage = (0, import_react33.forwardRef)((props, forwardedRef) => {
1139
- const { useContentPart } = useContentPartContext();
1140
- const image = useContentPart((c) => {
1141
- if (c.part.type !== "image")
1142
- throw new Error(
1143
- "ContentPartImage can only be used inside image content parts."
1144
- );
1145
- return c.part.image;
1146
- });
1147
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_primitive14.Primitive.img, { src: image, ...props, ref: forwardedRef });
1246
+ const image = useContentPartImage();
1247
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_primitive10.Primitive.img, { src: image, ...props, ref: forwardedRef });
1148
1248
  });
1149
1249
  ContentPartImage.displayName = "ContentPartImage";
1150
1250
 
@@ -1449,7 +1549,7 @@ var import_react37 = require("react");
1449
1549
  var import_react36 = require("react");
1450
1550
 
1451
1551
  // src/context/stores/AssistantModelConfig.ts
1452
- var import_zustand4 = require("zustand");
1552
+ var import_zustand5 = require("zustand");
1453
1553
 
1454
1554
  // src/utils/ProxyConfigProvider.ts
1455
1555
  var ProxyConfigProvider = class {
@@ -1466,23 +1566,23 @@ var ProxyConfigProvider = class {
1466
1566
  };
1467
1567
 
1468
1568
  // src/context/stores/AssistantModelConfig.ts
1469
- var makeAssistantModelConfigStore = () => (0, import_zustand4.create)(() => {
1569
+ var makeAssistantModelConfigStore = () => (0, import_zustand5.create)(() => {
1470
1570
  const proxy = new ProxyConfigProvider();
1471
- return {
1571
+ return Object.freeze({
1472
1572
  getModelConfig: () => {
1473
1573
  return proxy.getModelConfig();
1474
1574
  },
1475
1575
  registerModelConfigProvider: (provider) => {
1476
1576
  return proxy.registerModelConfigProvider(provider);
1477
1577
  }
1478
- };
1578
+ });
1479
1579
  });
1480
1580
 
1481
1581
  // src/context/stores/AssistantToolUIs.ts
1482
- var import_zustand5 = require("zustand");
1483
- var makeAssistantToolUIsStore = () => (0, import_zustand5.create)((set) => {
1582
+ var import_zustand6 = require("zustand");
1583
+ var makeAssistantToolUIsStore = () => (0, import_zustand6.create)((set) => {
1484
1584
  const renderers = /* @__PURE__ */ new Map();
1485
- return {
1585
+ return Object.freeze({
1486
1586
  getToolUI: (name) => {
1487
1587
  const arr = renderers.get(name);
1488
1588
  const last = arr?.at(-1);
@@ -1502,25 +1602,27 @@ var makeAssistantToolUIsStore = () => (0, import_zustand5.create)((set) => {
1502
1602
  if (index !== -1) {
1503
1603
  arr.splice(index, 1);
1504
1604
  }
1505
- set({});
1605
+ if (index === arr.length) {
1606
+ set({});
1607
+ }
1506
1608
  };
1507
1609
  }
1508
- };
1610
+ });
1509
1611
  });
1510
1612
 
1511
1613
  // src/context/providers/ThreadProvider.tsx
1512
1614
  var import_react35 = require("react");
1513
1615
 
1514
1616
  // src/context/stores/Composer.ts
1515
- var import_zustand6 = require("zustand");
1516
- var makeComposerStore = (useThread) => (0, import_zustand6.create)()((set, get, store) => {
1617
+ var import_zustand7 = require("zustand");
1618
+ var makeComposerStore = (useThread, useThreadActions) => (0, import_zustand7.create)()((set, get, store) => {
1517
1619
  return {
1518
1620
  ...makeBaseComposer(set, get, store),
1519
1621
  isEditing: true,
1520
1622
  send: () => {
1521
1623
  const { setValue, value } = get();
1522
1624
  setValue("");
1523
- useThread.getState().append({
1625
+ useThreadActions.getState().append({
1524
1626
  parentId: useThread.getState().messages.at(-1)?.id ?? null,
1525
1627
  content: [{ type: "text", text: value }]
1526
1628
  });
@@ -1528,42 +1630,26 @@ var makeComposerStore = (useThread) => (0, import_zustand6.create)()((set, get,
1528
1630
  cancel: () => {
1529
1631
  const thread = useThread.getState();
1530
1632
  if (!thread.isRunning) return false;
1531
- useThread.getState().cancelRun();
1633
+ useThreadActions.getState().cancelRun();
1532
1634
  return true;
1533
1635
  }
1534
1636
  };
1535
1637
  });
1536
1638
 
1537
1639
  // src/context/stores/Thread.ts
1538
- var import_zustand7 = require("zustand");
1640
+ var import_zustand8 = require("zustand");
1539
1641
  var makeThreadStore = (runtimeRef) => {
1540
- const useThread = (0, import_zustand7.create)(() => ({
1642
+ return (0, import_zustand8.create)(() => ({
1541
1643
  messages: runtimeRef.current.messages,
1542
- isRunning: runtimeRef.current.isRunning,
1543
- getBranches: (messageId) => runtimeRef.current.getBranches(messageId),
1544
- switchToBranch: (branchId) => runtimeRef.current.switchToBranch(branchId),
1545
- startRun: (parentId) => runtimeRef.current.startRun(parentId),
1546
- append: (message) => runtimeRef.current.append(message),
1547
- cancelRun: () => runtimeRef.current.cancelRun(),
1548
- addToolResult: (toolCallId, result) => runtimeRef.current.addToolResult(toolCallId, result)
1644
+ isRunning: runtimeRef.current.isRunning
1549
1645
  }));
1550
- const onRuntimeUpdate = () => {
1551
- useThread.setState({
1552
- messages: runtimeRef.current.messages,
1553
- isRunning: runtimeRef.current.isRunning
1554
- });
1555
- };
1556
- return {
1557
- useThread,
1558
- onRuntimeUpdate
1559
- };
1560
1646
  };
1561
1647
 
1562
1648
  // src/context/stores/ThreadViewport.tsx
1563
- var import_zustand8 = require("zustand");
1649
+ var import_zustand9 = require("zustand");
1564
1650
  var makeThreadViewportStore = () => {
1565
1651
  const scrollToBottomListeners = /* @__PURE__ */ new Set();
1566
- return (0, import_zustand8.create)(() => ({
1652
+ return (0, import_zustand9.create)(() => ({
1567
1653
  isAtBottom: true,
1568
1654
  scrollToBottom: () => {
1569
1655
  for (const listener of scrollToBottomListeners) {
@@ -1579,8 +1665,23 @@ var makeThreadViewportStore = () => {
1579
1665
  }));
1580
1666
  };
1581
1667
 
1668
+ // src/context/stores/ThreadActions.ts
1669
+ var import_zustand10 = require("zustand");
1670
+ var makeThreadActionStore = (runtimeRef) => {
1671
+ return (0, import_zustand10.create)(
1672
+ () => Object.freeze({
1673
+ getBranches: (messageId) => runtimeRef.current.getBranches(messageId),
1674
+ switchToBranch: (branchId) => runtimeRef.current.switchToBranch(branchId),
1675
+ startRun: (parentId) => runtimeRef.current.startRun(parentId),
1676
+ append: (message) => runtimeRef.current.append(message),
1677
+ cancelRun: () => runtimeRef.current.cancelRun(),
1678
+ addToolResult: (toolCallId, result) => runtimeRef.current.addToolResult(toolCallId, result)
1679
+ })
1680
+ );
1681
+ };
1682
+
1582
1683
  // src/context/providers/ThreadProvider.tsx
1583
- var import_jsx_runtime23 = require("react/jsx-runtime");
1684
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1584
1685
  var ThreadProvider = ({
1585
1686
  children,
1586
1687
  runtime
@@ -1589,32 +1690,40 @@ var ThreadProvider = ({
1589
1690
  (0, import_react35.useInsertionEffect)(() => {
1590
1691
  runtimeRef.current = runtime;
1591
1692
  });
1592
- const [{ context, onRuntimeUpdate }] = (0, import_react35.useState)(() => {
1593
- const { useThread, onRuntimeUpdate: onRuntimeUpdate2 } = makeThreadStore(runtimeRef);
1693
+ const [context] = (0, import_react35.useState)(() => {
1694
+ const useThread = makeThreadStore(runtimeRef);
1695
+ const useThreadActions = makeThreadActionStore(runtimeRef);
1594
1696
  const useViewport = makeThreadViewportStore();
1595
- const useComposer = makeComposerStore(useThread);
1697
+ const useComposer = makeComposerStore(useThread, useThreadActions);
1596
1698
  return {
1597
- context: {
1598
- useViewport,
1599
- useThread,
1600
- useComposer
1601
- },
1602
- onRuntimeUpdate: onRuntimeUpdate2
1699
+ useThread,
1700
+ useThreadActions,
1701
+ useComposer,
1702
+ useViewport
1603
1703
  };
1604
1704
  });
1605
1705
  (0, import_react35.useEffect)(() => {
1706
+ const onRuntimeUpdate = () => {
1707
+ context.useThread.setState(
1708
+ Object.freeze({
1709
+ messages: runtimeRef.current.messages,
1710
+ isRunning: runtimeRef.current.isRunning
1711
+ }),
1712
+ true
1713
+ );
1714
+ };
1606
1715
  onRuntimeUpdate();
1607
1716
  return runtime.subscribe(onRuntimeUpdate);
1608
- }, [onRuntimeUpdate, runtime]);
1717
+ }, [context, runtime]);
1609
1718
  const RuntimeSynchronizer = runtime.unstable_synchronizer;
1610
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(ThreadContext.Provider, { value: context, children: [
1611
- RuntimeSynchronizer && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(RuntimeSynchronizer, {}),
1719
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(ThreadContext.Provider, { value: context, children: [
1720
+ RuntimeSynchronizer && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(RuntimeSynchronizer, {}),
1612
1721
  children
1613
1722
  ] });
1614
1723
  };
1615
1724
 
1616
1725
  // src/context/providers/AssistantProvider.tsx
1617
- var import_jsx_runtime24 = require("react/jsx-runtime");
1726
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1618
1727
  var AssistantProvider = ({ children, runtime }) => {
1619
1728
  const runtimeRef = (0, import_react36.useRef)(runtime);
1620
1729
  (0, import_react36.useInsertionEffect)(() => {
@@ -1629,13 +1738,13 @@ var AssistantProvider = ({ children, runtime }) => {
1629
1738
  (0, import_react36.useEffect)(() => {
1630
1739
  return runtime.registerModelConfigProvider(getModelCOnfig);
1631
1740
  }, [runtime, getModelCOnfig]);
1632
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(AssistantContext.Provider, { value: context, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ThreadProvider, { runtime, children }) });
1741
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(AssistantContext.Provider, { value: context, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ThreadProvider, { runtime, children }) });
1633
1742
  };
1634
1743
 
1635
1744
  // src/context/providers/AssistantRuntimeProvider.tsx
1636
- var import_jsx_runtime25 = require("react/jsx-runtime");
1745
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1637
1746
  var AssistantRuntimeProviderImpl = ({ children, runtime }) => {
1638
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AssistantProvider, { runtime, children });
1747
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(AssistantProvider, { runtime, children });
1639
1748
  };
1640
1749
  var AssistantRuntimeProvider = (0, import_react37.memo)(AssistantRuntimeProviderImpl);
1641
1750
 
@@ -1655,11 +1764,25 @@ __export(internal_exports, {
1655
1764
  INTERNAL,
1656
1765
  MessagePrimitive,
1657
1766
  ThreadPrimitive,
1658
- useBeginMessageEdit,
1659
- useCopyMessage,
1660
- useGoToNextBranch,
1661
- useGoToPreviousBranch,
1767
+ useActionBarCopy,
1768
+ useActionBarEdit,
1769
+ useActionBarReload,
1770
+ useBranchPickerCount,
1771
+ useBranchPickerNext,
1772
+ useBranchPickerNumber,
1773
+ useBranchPickerPrevious,
1774
+ useComposerCancel,
1775
+ useComposerIf,
1776
+ useComposerSend,
1777
+ useContentPartDisplay,
1778
+ useContentPartImage,
1779
+ useContentPartInProgressIndicator,
1780
+ useContentPartText,
1662
1781
  useLocalRuntime,
1663
- useReloadMessage
1782
+ useMessageIf,
1783
+ useThreadEmpty,
1784
+ useThreadIf,
1785
+ useThreadScrollToBottom,
1786
+ useThreadSuggestion
1664
1787
  });
1665
1788
  //# sourceMappingURL=index.js.map