@assistant-ui/react 0.1.8 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.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