@assistant-ui/react 0.2.0 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.mjs CHANGED
@@ -4,179 +4,6 @@ var __export = (target, all) => {
4
4
  __defProp(target, name, { get: all[name], enumerable: true });
5
5
  };
6
6
 
7
- // src/primitive-hooks/actionBar/useActionBarCopy.tsx
8
- import { useCallback } from "react";
9
-
10
- // src/context/react/MessageContext.ts
11
- import { createContext, useContext } from "react";
12
- var MessageContext = createContext(null);
13
- var useMessageContext = () => {
14
- const context = useContext(MessageContext);
15
- if (!context)
16
- throw new Error(
17
- "This component can only be used inside a component passed to <ThreadPrimitive.Messages components={...} />."
18
- );
19
- return context;
20
- };
21
-
22
- // src/utils/combined/useCombinedStore.ts
23
- import { useMemo } from "react";
24
-
25
- // src/utils/combined/createCombinedStore.ts
26
- import { useSyncExternalStore } from "react";
27
- var createCombinedStore = (stores) => {
28
- const subscribe = (callback) => {
29
- const unsubscribes = stores.map((store) => store.subscribe(callback));
30
- return () => {
31
- for (const unsub of unsubscribes) {
32
- unsub();
33
- }
34
- };
35
- };
36
- return (selector) => {
37
- const getSnapshot = () => selector(...stores.map((store) => store.getState()));
38
- return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
39
- };
40
- };
41
-
42
- // src/utils/combined/useCombinedStore.ts
43
- var useCombinedStore = (stores, selector) => {
44
- const useCombined = useMemo(() => createCombinedStore(stores), stores);
45
- return useCombined(selector);
46
- };
47
-
48
- // src/utils/getMessageText.tsx
49
- var getMessageText = (message) => {
50
- const textParts = message.content.filter(
51
- (part) => part.type === "text"
52
- );
53
- return textParts.map((part) => part.text).join("\n\n");
54
- };
55
-
56
- // src/primitive-hooks/actionBar/useActionBarCopy.tsx
57
- var useActionBarCopy = ({
58
- copiedDuration = 3e3
59
- } = {}) => {
60
- const { useMessage, useMessageUtils, useEditComposer } = useMessageContext();
61
- const hasCopyableContent = useCombinedStore(
62
- [useMessage, useEditComposer],
63
- (m, c) => {
64
- return !c.isEditing && m.message.content.some((c2) => c2.type === "text");
65
- }
66
- );
67
- const callback = useCallback(() => {
68
- const { message } = useMessage.getState();
69
- const { setIsCopied } = useMessageUtils.getState();
70
- const { isEditing, value: composerValue } = useEditComposer.getState();
71
- const valueToCopy = isEditing ? composerValue : getMessageText(message);
72
- navigator.clipboard.writeText(valueToCopy);
73
- setIsCopied(true);
74
- setTimeout(() => setIsCopied(false), copiedDuration);
75
- }, [useMessage, useMessageUtils, useEditComposer, copiedDuration]);
76
- if (!hasCopyableContent) return null;
77
- return callback;
78
- };
79
-
80
- // src/primitive-hooks/actionBar/useActionBarEdit.tsx
81
- import { useCallback as useCallback2 } from "react";
82
- var useActionBarEdit = () => {
83
- const { useMessage, useEditComposer } = useMessageContext();
84
- const disabled = useCombinedStore(
85
- [useMessage, useEditComposer],
86
- (m, c) => m.message.role !== "user" || c.isEditing
87
- );
88
- const callback = useCallback2(() => {
89
- const { edit } = useEditComposer.getState();
90
- edit();
91
- }, [useEditComposer]);
92
- if (disabled) return null;
93
- return callback;
94
- };
95
-
96
- // src/primitive-hooks/actionBar/useActionBarReload.tsx
97
- import { useCallback as useCallback3 } from "react";
98
-
99
- // src/context/react/ThreadContext.ts
100
- import { createContext as createContext2, useContext as useContext2 } from "react";
101
- var ThreadContext = createContext2(null);
102
- var useThreadContext = () => {
103
- const context = useContext2(ThreadContext);
104
- if (!context)
105
- throw new Error(
106
- "This component must be used within an AssistantRuntimeProvider."
107
- );
108
- return context;
109
- };
110
-
111
- // src/primitive-hooks/actionBar/useActionBarReload.tsx
112
- var useActionBarReload = () => {
113
- const { useThread, useThreadActions, useComposer, useViewport } = useThreadContext();
114
- const { useMessage } = useMessageContext();
115
- const disabled = useCombinedStore(
116
- [useThread, useMessage],
117
- (t, m) => t.isRunning || m.message.role !== "assistant"
118
- );
119
- const callback = useCallback3(() => {
120
- const { parentId } = useMessage.getState();
121
- useThreadActions.getState().startRun(parentId);
122
- useViewport.getState().scrollToBottom();
123
- useComposer.getState().focus();
124
- }, [useThreadActions, useComposer, useViewport, useMessage]);
125
- if (disabled) return null;
126
- return callback;
127
- };
128
-
129
- // src/primitive-hooks/branchPicker/useBranchPickerCount.tsx
130
- var useBranchPickerCount = () => {
131
- const { useMessage } = useMessageContext();
132
- const branchCount = useMessage((s) => s.branches.length);
133
- return branchCount;
134
- };
135
-
136
- // src/primitive-hooks/branchPicker/useBranchPickerNext.tsx
137
- import { useCallback as useCallback4 } from "react";
138
- var useBranchPickerNext = () => {
139
- const { useThreadActions } = useThreadContext();
140
- const { useMessage, useEditComposer } = useMessageContext();
141
- const disabled = useCombinedStore(
142
- [useMessage, useEditComposer],
143
- (m, c) => c.isEditing || m.branches.indexOf(m.message.id) + 1 >= m.branches.length
144
- );
145
- const callback = useCallback4(() => {
146
- const { message, branches } = useMessage.getState();
147
- useThreadActions.getState().switchToBranch(branches[branches.indexOf(message.id) + 1]);
148
- }, [useThreadActions, useMessage]);
149
- if (disabled) return null;
150
- return callback;
151
- };
152
-
153
- // src/primitive-hooks/branchPicker/useBranchPickerNumber.tsx
154
- var useBranchPickerNumber = () => {
155
- const { useMessage } = useMessageContext();
156
- const branchIdx = useMessage((s) => s.branches.indexOf(s.message.id));
157
- return branchIdx + 1;
158
- };
159
-
160
- // src/primitive-hooks/branchPicker/useBranchPickerPrevious.tsx
161
- import { useCallback as useCallback5 } from "react";
162
- var useBranchPickerPrevious = () => {
163
- const { useThreadActions } = useThreadContext();
164
- const { useMessage, useEditComposer } = useMessageContext();
165
- const disabled = useCombinedStore(
166
- [useMessage, useEditComposer],
167
- (m, c) => c.isEditing || m.branches.indexOf(m.message.id) <= 0
168
- );
169
- const callback = useCallback5(() => {
170
- const { message, branches } = useMessage.getState();
171
- useThreadActions.getState().switchToBranch(branches[branches.indexOf(message.id) - 1]);
172
- }, [useThreadActions, useMessage]);
173
- if (disabled) return null;
174
- return callback;
175
- };
176
-
177
- // src/primitive-hooks/composer/useComposerCancel.tsx
178
- import { useCallback as useCallback6 } from "react";
179
-
180
7
  // src/context/providers/AssistantRuntimeProvider.tsx
181
8
  import { memo } from "react";
182
9
 
@@ -184,12 +11,12 @@ import { memo } from "react";
184
11
  import { useEffect as useEffect2, useInsertionEffect as useInsertionEffect2, useRef as useRef2, useState as useState2 } from "react";
185
12
 
186
13
  // src/context/react/AssistantContext.ts
187
- import { createContext as createContext3, useContext as useContext3 } from "react";
188
- var AssistantContext = createContext3(
14
+ import { createContext, useContext } from "react";
15
+ var AssistantContext = createContext(
189
16
  null
190
17
  );
191
18
  var useAssistantContext = () => {
192
- const context = useContext3(AssistantContext);
19
+ const context = useContext(AssistantContext);
193
20
  if (!context)
194
21
  throw new Error(
195
22
  "This component must be used within an AssistantRuntimeProvider."
@@ -288,7 +115,26 @@ var makeAssistantToolUIsStore = () => create2((set) => {
288
115
  });
289
116
 
290
117
  // src/context/providers/ThreadProvider.tsx
291
- import { useEffect, useInsertionEffect, useRef, useState } from "react";
118
+ import {
119
+ useCallback,
120
+ useEffect,
121
+ useInsertionEffect,
122
+ useRef,
123
+ useState,
124
+ useSyncExternalStore
125
+ } from "react";
126
+
127
+ // src/context/react/ThreadContext.ts
128
+ import { createContext as createContext2, useContext as useContext2 } from "react";
129
+ var ThreadContext = createContext2(null);
130
+ var useThreadContext = () => {
131
+ const context = useContext2(ThreadContext);
132
+ if (!context)
133
+ throw new Error(
134
+ "This component must be used within an AssistantRuntimeProvider."
135
+ );
136
+ return context;
137
+ };
292
138
 
293
139
  // src/context/stores/Composer.ts
294
140
  import { create as create3 } from "zustand";
@@ -302,7 +148,7 @@ var makeBaseComposer = (set) => ({
302
148
  });
303
149
 
304
150
  // src/context/stores/Composer.ts
305
- var makeComposerStore = (useThread, useThreadActions) => {
151
+ var makeComposerStore = (useThread, useThreadMessages, useThreadActions) => {
306
152
  const focusListeners = /* @__PURE__ */ new Set();
307
153
  return create3()((set, get, store) => {
308
154
  return {
@@ -312,7 +158,7 @@ var makeComposerStore = (useThread, useThreadActions) => {
312
158
  const { setValue, value } = get();
313
159
  setValue("");
314
160
  useThreadActions.getState().append({
315
- parentId: useThread.getState().messages.at(-1)?.id ?? null,
161
+ parentId: useThreadMessages.getState().at(-1)?.id ?? null,
316
162
  role: "user",
317
163
  content: [{ type: "text", text: value }]
318
164
  });
@@ -342,7 +188,6 @@ var makeComposerStore = (useThread, useThreadActions) => {
342
188
  import { create as create4 } from "zustand";
343
189
  var makeThreadStore = (runtimeRef) => {
344
190
  return create4(() => ({
345
- messages: runtimeRef.current.messages,
346
191
  isRunning: runtimeRef.current.isRunning
347
192
  }));
348
193
  };
@@ -382,6 +227,12 @@ var makeThreadActionStore = (runtimeRef) => {
382
227
  );
383
228
  };
384
229
 
230
+ // src/context/stores/ThreadMessages.ts
231
+ import { create as create7 } from "zustand";
232
+ var makeThreadMessagesStore = (runtimeRef) => {
233
+ return create7(() => runtimeRef.current.messages);
234
+ };
235
+
385
236
  // src/context/providers/ThreadProvider.tsx
386
237
  import { jsx, jsxs } from "react/jsx-runtime";
387
238
  var ThreadProvider = ({
@@ -394,11 +245,17 @@ var ThreadProvider = ({
394
245
  });
395
246
  const [context] = useState(() => {
396
247
  const useThread = makeThreadStore(runtimeRef);
248
+ const useThreadMessages = makeThreadMessagesStore(runtimeRef);
397
249
  const useThreadActions = makeThreadActionStore(runtimeRef);
398
250
  const useViewport = makeThreadViewportStore();
399
- const useComposer = makeComposerStore(useThread, useThreadActions);
251
+ const useComposer = makeComposerStore(
252
+ useThread,
253
+ useThreadMessages,
254
+ useThreadActions
255
+ );
400
256
  return {
401
257
  useThread,
258
+ useThreadMessages,
402
259
  useThreadActions,
403
260
  useComposer,
404
261
  useViewport
@@ -408,22 +265,38 @@ var ThreadProvider = ({
408
265
  const onRuntimeUpdate = () => {
409
266
  context.useThread.setState(
410
267
  Object.freeze({
411
- messages: runtimeRef.current.messages,
412
268
  isRunning: runtimeRef.current.isRunning
413
269
  }),
414
270
  true
415
271
  );
272
+ context.useThreadMessages.setState(Object.freeze(runtimeRef.current.messages), true);
416
273
  };
417
274
  onRuntimeUpdate();
418
275
  return runtime.subscribe(onRuntimeUpdate);
419
276
  }, [context, runtime]);
420
- const RuntimeSynchronizer = runtime.unstable_synchronizer;
277
+ const subscribe = useCallback(
278
+ (c) => runtime.subscribe(c),
279
+ [runtime]
280
+ );
281
+ const RuntimeSynchronizer = useSyncExternalStore(
282
+ subscribe,
283
+ () => runtime.unstable_synchronizer,
284
+ () => void 0
285
+ );
421
286
  return /* @__PURE__ */ jsxs(ThreadContext.Provider, { value: context, children: [
422
287
  RuntimeSynchronizer && /* @__PURE__ */ jsx(RuntimeSynchronizer, {}),
423
288
  children
424
289
  ] });
425
290
  };
426
291
 
292
+ // src/context/stores/AssistantActions.tsx
293
+ import { create as create8 } from "zustand";
294
+ var makeAssistantActionsStore = (runtimeRef) => create8(
295
+ () => Object.freeze({
296
+ switchToThread: () => runtimeRef.current.switchToThread(null)
297
+ })
298
+ );
299
+
427
300
  // src/context/providers/AssistantProvider.tsx
428
301
  import { jsx as jsx2 } from "react/jsx-runtime";
429
302
  var AssistantProvider = ({ children, runtime }) => {
@@ -434,7 +307,8 @@ var AssistantProvider = ({ children, runtime }) => {
434
307
  const [context] = useState2(() => {
435
308
  const useModelConfig = makeAssistantModelConfigStore();
436
309
  const useToolUIs = makeAssistantToolUIsStore();
437
- return { useModelConfig, useToolUIs };
310
+ const useAssistantActions = makeAssistantActionsStore(runtimeRef);
311
+ return { useModelConfig, useToolUIs, useAssistantActions };
438
312
  });
439
313
  const getModelCOnfig = context.useModelConfig((c) => c.getModelConfig);
440
314
  useEffect2(() => {
@@ -451,11 +325,25 @@ var AssistantRuntimeProviderImpl = ({ children, runtime }) => {
451
325
  var AssistantRuntimeProvider = memo(AssistantRuntimeProviderImpl);
452
326
 
453
327
  // src/context/react/ComposerContext.ts
454
- import { useContext as useContext4, useMemo as useMemo2 } from "react";
328
+ import { useContext as useContext4, useMemo } from "react";
329
+
330
+ // src/context/react/MessageContext.ts
331
+ import { createContext as createContext3, useContext as useContext3 } from "react";
332
+ var MessageContext = createContext3(null);
333
+ var useMessageContext = () => {
334
+ const context = useContext3(MessageContext);
335
+ if (!context)
336
+ throw new Error(
337
+ "This component can only be used inside a component passed to <ThreadPrimitive.Messages components={...} />."
338
+ );
339
+ return context;
340
+ };
341
+
342
+ // src/context/react/ComposerContext.ts
455
343
  var useComposerContext = () => {
456
344
  const { useComposer } = useThreadContext();
457
345
  const { useEditComposer } = useContext4(MessageContext) ?? {};
458
- return useMemo2(
346
+ return useMemo(
459
347
  () => ({
460
348
  useComposer: useEditComposer ?? useComposer,
461
349
  type: useEditComposer ? "edit" : "new"
@@ -478,11 +366,267 @@ var useContentPartContext = () => {
478
366
  return context;
479
367
  };
480
368
 
369
+ // src/hooks/useAppendMessage.tsx
370
+ import { useCallback as useCallback2 } from "react";
371
+ var toAppendMessage = (useThreadMessages, message) => {
372
+ if (typeof message === "string") {
373
+ return {
374
+ parentId: useThreadMessages.getState().at(-1)?.id ?? null,
375
+ role: "user",
376
+ content: [{ type: "text", text: message }]
377
+ };
378
+ }
379
+ return {
380
+ parentId: message.parentId ?? useThreadMessages.getState().at(-1)?.id ?? null,
381
+ role: message.role ?? "user",
382
+ content: message.content
383
+ };
384
+ };
385
+ var useAppendMessage = () => {
386
+ const { useThreadMessages, useThreadActions, useViewport, useComposer } = useThreadContext();
387
+ const append = useCallback2(
388
+ (message) => {
389
+ const appendMessage = toAppendMessage(useThreadMessages, message);
390
+ useThreadActions.getState().append(appendMessage);
391
+ useViewport.getState().scrollToBottom();
392
+ useComposer.getState().focus();
393
+ },
394
+ [useThreadMessages, useThreadActions, useViewport, useComposer]
395
+ );
396
+ return append;
397
+ };
398
+
399
+ // src/hooks/useSwitchToNewThread.tsx
400
+ import { useCallback as useCallback3 } from "react";
401
+ var useSwitchToNewThread = () => {
402
+ const { useAssistantActions } = useAssistantContext();
403
+ const { useComposer } = useThreadContext();
404
+ const switchToNewThread = useCallback3(() => {
405
+ useAssistantActions.getState().switchToThread(null);
406
+ useComposer.getState().focus();
407
+ }, [useAssistantActions, useComposer]);
408
+ return switchToNewThread;
409
+ };
410
+
411
+ // src/model-config/useAssistantTool.tsx
412
+ import { useEffect as useEffect3 } from "react";
413
+ var useAssistantTool = (tool) => {
414
+ const { useModelConfig, useToolUIs } = useAssistantContext();
415
+ const registerModelConfigProvider = useModelConfig(
416
+ (s) => s.registerModelConfigProvider
417
+ );
418
+ const setToolUI = useToolUIs((s) => s.setToolUI);
419
+ useEffect3(() => {
420
+ const { toolName, render, ...rest } = tool;
421
+ const config = {
422
+ tools: {
423
+ [tool.toolName]: rest
424
+ }
425
+ };
426
+ const unsub1 = registerModelConfigProvider(() => config);
427
+ const unsub2 = render ? setToolUI(toolName, render) : void 0;
428
+ return () => {
429
+ unsub1();
430
+ unsub2?.();
431
+ };
432
+ }, [registerModelConfigProvider, setToolUI, tool]);
433
+ };
434
+
435
+ // src/model-config/makeAssistantTool.tsx
436
+ var makeAssistantTool = (tool) => {
437
+ const Tool = () => {
438
+ useAssistantTool(tool);
439
+ return null;
440
+ };
441
+ return Tool;
442
+ };
443
+
444
+ // src/model-config/useAssistantToolUI.tsx
445
+ import { useEffect as useEffect4 } from "react";
446
+ var useAssistantToolUI = (tool) => {
447
+ const { useToolUIs } = useAssistantContext();
448
+ const setToolUI = useToolUIs((s) => s.setToolUI);
449
+ useEffect4(() => {
450
+ if (!tool) return;
451
+ const { toolName, render } = tool;
452
+ return setToolUI(toolName, render);
453
+ }, [setToolUI, tool]);
454
+ };
455
+
456
+ // src/model-config/makeAssistantToolUI.tsx
457
+ var makeAssistantToolUI = (tool) => {
458
+ const ToolUI = () => {
459
+ useAssistantToolUI(tool);
460
+ return null;
461
+ };
462
+ return ToolUI;
463
+ };
464
+
465
+ // src/model-config/useAssistantInstructions.tsx
466
+ import { useEffect as useEffect5 } from "react";
467
+ var useAssistantInstructions = (instruction) => {
468
+ const { useModelConfig } = useAssistantContext();
469
+ const registerModelConfigProvider = useModelConfig(
470
+ (s) => s.registerModelConfigProvider
471
+ );
472
+ useEffect5(() => {
473
+ const config = {
474
+ system: instruction
475
+ };
476
+ return registerModelConfigProvider(() => config);
477
+ }, [registerModelConfigProvider, instruction]);
478
+ };
479
+
480
+ // src/primitive-hooks/actionBar/useActionBarCopy.tsx
481
+ import { useCallback as useCallback4 } from "react";
482
+
483
+ // src/utils/combined/useCombinedStore.ts
484
+ import { useMemo as useMemo2 } from "react";
485
+
486
+ // src/utils/combined/createCombinedStore.ts
487
+ import { useSyncExternalStore as useSyncExternalStore2 } from "react";
488
+ var createCombinedStore = (stores) => {
489
+ const subscribe = (callback) => {
490
+ const unsubscribes = stores.map((store) => store.subscribe(callback));
491
+ return () => {
492
+ for (const unsub of unsubscribes) {
493
+ unsub();
494
+ }
495
+ };
496
+ };
497
+ return (selector) => {
498
+ const getSnapshot = () => selector(...stores.map((store) => store.getState()));
499
+ return useSyncExternalStore2(subscribe, getSnapshot, getSnapshot);
500
+ };
501
+ };
502
+
503
+ // src/utils/combined/useCombinedStore.ts
504
+ var useCombinedStore = (stores, selector) => {
505
+ const useCombined = useMemo2(() => createCombinedStore(stores), stores);
506
+ return useCombined(selector);
507
+ };
508
+
509
+ // src/utils/getMessageText.tsx
510
+ var getMessageText = (message) => {
511
+ const textParts = message.content.filter(
512
+ (part) => part.type === "text"
513
+ );
514
+ return textParts.map((part) => part.text).join("\n\n");
515
+ };
516
+
517
+ // src/primitive-hooks/actionBar/useActionBarCopy.tsx
518
+ var useActionBarCopy = ({
519
+ copiedDuration = 3e3
520
+ } = {}) => {
521
+ const { useMessage, useMessageUtils, useEditComposer } = useMessageContext();
522
+ const hasCopyableContent = useCombinedStore(
523
+ [useMessage, useEditComposer],
524
+ (m, c) => {
525
+ return !c.isEditing && m.message.content.some((c2) => c2.type === "text");
526
+ }
527
+ );
528
+ const callback = useCallback4(() => {
529
+ const { message } = useMessage.getState();
530
+ const { setIsCopied } = useMessageUtils.getState();
531
+ const { isEditing, value: composerValue } = useEditComposer.getState();
532
+ const valueToCopy = isEditing ? composerValue : getMessageText(message);
533
+ navigator.clipboard.writeText(valueToCopy);
534
+ setIsCopied(true);
535
+ setTimeout(() => setIsCopied(false), copiedDuration);
536
+ }, [useMessage, useMessageUtils, useEditComposer, copiedDuration]);
537
+ if (!hasCopyableContent) return null;
538
+ return callback;
539
+ };
540
+
541
+ // src/primitive-hooks/actionBar/useActionBarEdit.tsx
542
+ import { useCallback as useCallback5 } from "react";
543
+ var useActionBarEdit = () => {
544
+ const { useMessage, useEditComposer } = useMessageContext();
545
+ const disabled = useCombinedStore(
546
+ [useMessage, useEditComposer],
547
+ (m, c) => m.message.role !== "user" || c.isEditing
548
+ );
549
+ const callback = useCallback5(() => {
550
+ const { edit } = useEditComposer.getState();
551
+ edit();
552
+ }, [useEditComposer]);
553
+ if (disabled) return null;
554
+ return callback;
555
+ };
556
+
557
+ // src/primitive-hooks/actionBar/useActionBarReload.tsx
558
+ import { useCallback as useCallback6 } from "react";
559
+ var useActionBarReload = () => {
560
+ const { useThread, useThreadActions, useComposer, useViewport } = useThreadContext();
561
+ const { useMessage } = useMessageContext();
562
+ const disabled = useCombinedStore(
563
+ [useThread, useMessage],
564
+ (t, m) => t.isRunning || m.message.role !== "assistant"
565
+ );
566
+ const callback = useCallback6(() => {
567
+ const { parentId } = useMessage.getState();
568
+ useThreadActions.getState().startRun(parentId);
569
+ useViewport.getState().scrollToBottom();
570
+ useComposer.getState().focus();
571
+ }, [useThreadActions, useComposer, useViewport, useMessage]);
572
+ if (disabled) return null;
573
+ return callback;
574
+ };
575
+
576
+ // src/primitive-hooks/branchPicker/useBranchPickerCount.tsx
577
+ var useBranchPickerCount = () => {
578
+ const { useMessage } = useMessageContext();
579
+ const branchCount = useMessage((s) => s.branches.length);
580
+ return branchCount;
581
+ };
582
+
583
+ // src/primitive-hooks/branchPicker/useBranchPickerNext.tsx
584
+ import { useCallback as useCallback7 } from "react";
585
+ var useBranchPickerNext = () => {
586
+ const { useThreadActions } = useThreadContext();
587
+ const { useMessage, useEditComposer } = useMessageContext();
588
+ const disabled = useCombinedStore(
589
+ [useMessage, useEditComposer],
590
+ (m, c) => c.isEditing || m.branches.indexOf(m.message.id) + 1 >= m.branches.length
591
+ );
592
+ const callback = useCallback7(() => {
593
+ const { message, branches } = useMessage.getState();
594
+ useThreadActions.getState().switchToBranch(branches[branches.indexOf(message.id) + 1]);
595
+ }, [useThreadActions, useMessage]);
596
+ if (disabled) return null;
597
+ return callback;
598
+ };
599
+
600
+ // src/primitive-hooks/branchPicker/useBranchPickerNumber.tsx
601
+ var useBranchPickerNumber = () => {
602
+ const { useMessage } = useMessageContext();
603
+ const branchIdx = useMessage((s) => s.branches.indexOf(s.message.id));
604
+ return branchIdx + 1;
605
+ };
606
+
607
+ // src/primitive-hooks/branchPicker/useBranchPickerPrevious.tsx
608
+ import { useCallback as useCallback8 } from "react";
609
+ var useBranchPickerPrevious = () => {
610
+ const { useThreadActions } = useThreadContext();
611
+ const { useMessage, useEditComposer } = useMessageContext();
612
+ const disabled = useCombinedStore(
613
+ [useMessage, useEditComposer],
614
+ (m, c) => c.isEditing || m.branches.indexOf(m.message.id) <= 0
615
+ );
616
+ const callback = useCallback8(() => {
617
+ const { message, branches } = useMessage.getState();
618
+ useThreadActions.getState().switchToBranch(branches[branches.indexOf(message.id) - 1]);
619
+ }, [useThreadActions, useMessage]);
620
+ if (disabled) return null;
621
+ return callback;
622
+ };
623
+
481
624
  // src/primitive-hooks/composer/useComposerCancel.tsx
625
+ import { useCallback as useCallback9 } from "react";
482
626
  var useComposerCancel = () => {
483
627
  const { useComposer } = useComposerContext();
484
628
  const disabled = useComposer((c) => !c.isEditing);
485
- const callback = useCallback6(() => {
629
+ const callback = useCallback9(() => {
486
630
  const { cancel } = useComposer.getState();
487
631
  cancel();
488
632
  }, [useComposer]);
@@ -501,12 +645,12 @@ var useComposerIf = (props) => {
501
645
  };
502
646
 
503
647
  // src/primitive-hooks/composer/useComposerSend.tsx
504
- import { useCallback as useCallback7 } from "react";
648
+ import { useCallback as useCallback10 } from "react";
505
649
  var useComposerSend = () => {
506
650
  const { useViewport, useComposer: useNewComposer } = useThreadContext();
507
651
  const { useComposer } = useComposerContext();
508
652
  const disabled = useComposer((c) => !c.isEditing || c.value.length === 0);
509
- const callback = useCallback7(() => {
653
+ const callback = useCallback10(() => {
510
654
  const composerState = useComposer.getState();
511
655
  if (!composerState.isEditing) return;
512
656
  composerState.send();
@@ -543,17 +687,6 @@ var useContentPartImage = () => {
543
687
  return image;
544
688
  };
545
689
 
546
- // src/primitive-hooks/contentPart/useContentPartInProgressIndicator.tsx
547
- var useContentPartInProgressIndicator = () => {
548
- const { useMessageUtils } = useMessageContext();
549
- const { useContentPart } = useContentPartContext();
550
- const indicator = useCombinedStore(
551
- [useMessageUtils, useContentPart],
552
- (m, c) => c.status === "in_progress" ? m.inProgressIndicator : null
553
- );
554
- return indicator;
555
- };
556
-
557
690
  // src/primitive-hooks/contentPart/useContentPartText.tsx
558
691
  var useContentPartText = () => {
559
692
  const { useContentPart } = useContentPartContext();
@@ -586,14 +719,17 @@ var useMessageIf = (props) => {
586
719
 
587
720
  // src/primitive-hooks/thread/useThreadIf.tsx
588
721
  var useThreadIf = (props) => {
589
- const { useThread } = useThreadContext();
590
- return useThread((thread) => {
591
- if (props.empty === true && thread.messages.length !== 0) return false;
592
- if (props.empty === false && thread.messages.length === 0) return false;
593
- if (props.running === true && !thread.isRunning) return false;
594
- if (props.running === false && thread.isRunning) return false;
595
- return true;
596
- });
722
+ const { useThread, useThreadMessages } = useThreadContext();
723
+ return useCombinedStore(
724
+ [useThread, useThreadMessages],
725
+ (thread, messages) => {
726
+ if (props.empty === true && messages.length !== 0) return false;
727
+ if (props.empty === false && messages.length === 0) return false;
728
+ if (props.running === true && !thread.isRunning) return false;
729
+ if (props.running === false && thread.isRunning) return false;
730
+ return true;
731
+ }
732
+ );
597
733
  };
598
734
 
599
735
  // src/primitive-hooks/thread/useThreadEmpty.tsx
@@ -602,11 +738,11 @@ var useThreadEmpty = () => {
602
738
  };
603
739
 
604
740
  // src/primitive-hooks/thread/useThreadScrollToBottom.tsx
605
- import { useCallback as useCallback8 } from "react";
741
+ import { useCallback as useCallback11 } from "react";
606
742
  var useThreadScrollToBottom = () => {
607
743
  const { useComposer, useViewport } = useThreadContext();
608
744
  const isAtBottom = useViewport((s) => s.isAtBottom);
609
- const handleScrollToBottom = useCallback8(() => {
745
+ const handleScrollToBottom = useCallback11(() => {
610
746
  useViewport.getState().scrollToBottom();
611
747
  useComposer.getState().focus();
612
748
  }, [useViewport, useComposer]);
@@ -615,14 +751,14 @@ var useThreadScrollToBottom = () => {
615
751
  };
616
752
 
617
753
  // src/primitive-hooks/thread/useThreadSuggestion.tsx
618
- import { useCallback as useCallback9 } from "react";
754
+ import { useCallback as useCallback12 } from "react";
619
755
  var useThreadSuggestion = ({
620
756
  prompt,
621
757
  autoSend
622
758
  }) => {
623
759
  const { useThread, useComposer } = useThreadContext();
624
760
  const disabled = useThread((t) => t.isRunning);
625
- const callback = useCallback9(() => {
761
+ const callback = useCallback12(() => {
626
762
  const thread = useThread.getState();
627
763
  const composer = useComposer.getState();
628
764
  composer.setValue(prompt);
@@ -637,16 +773,17 @@ var useThreadSuggestion = ({
637
773
  // src/primitives/actionBar/index.ts
638
774
  var actionBar_exports = {};
639
775
  __export(actionBar_exports, {
640
- Copy: () => ActionBarCopy,
641
- Edit: () => ActionBarEdit,
642
- Reload: () => ActionBarReload,
643
- Root: () => ActionBarRoot
776
+ Copy: () => ActionBarPrimitiveCopy,
777
+ Edit: () => ActionBarPrimitiveEdit,
778
+ Reload: () => ActionBarPrimitiveReload,
779
+ Root: () => ActionBarPrimitiveRoot
644
780
  });
645
781
 
646
782
  // src/primitives/actionBar/ActionBarRoot.tsx
647
783
  import { Primitive } from "@radix-ui/react-primitive";
648
784
  import { forwardRef } from "react";
649
- import { jsx as jsx4 } from "react/jsx-runtime";
785
+
786
+ // src/primitives/actionBar/useActionBarFloatStatus.tsx
650
787
  var useActionBarFloatStatus = ({
651
788
  hideWhenRunning,
652
789
  autohide,
@@ -667,7 +804,10 @@ var useActionBarFloatStatus = ({
667
804
  }
668
805
  );
669
806
  };
670
- var ActionBarRoot = forwardRef(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
807
+
808
+ // src/primitives/actionBar/ActionBarRoot.tsx
809
+ import { jsx as jsx4 } from "react/jsx-runtime";
810
+ var ActionBarPrimitiveRoot = forwardRef(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
671
811
  const hideAndfloatStatus = useActionBarFloatStatus({
672
812
  hideWhenRunning,
673
813
  autohide,
@@ -683,7 +823,7 @@ var ActionBarRoot = forwardRef(({ hideWhenRunning, autohide, autohideFloat, ...r
683
823
  }
684
824
  );
685
825
  });
686
- ActionBarRoot.displayName = "ActionBarRoot";
826
+ ActionBarPrimitiveRoot.displayName = "ActionBarPrimitive.Root";
687
827
 
688
828
  // src/utils/createActionButton.tsx
689
829
  import { composeEventHandlers } from "@radix-ui/primitive";
@@ -711,52 +851,55 @@ var createActionButton = (displayName, useActionButton) => {
711
851
  };
712
852
 
713
853
  // src/primitives/actionBar/ActionBarCopy.tsx
714
- var ActionBarCopy = createActionButton(
715
- "ActionBarCopy",
854
+ var ActionBarPrimitiveCopy = createActionButton(
855
+ "ActionBarPrimitive.Copy",
716
856
  useActionBarCopy
717
857
  );
718
858
 
719
859
  // src/primitives/actionBar/ActionBarReload.tsx
720
- var ActionBarReload = createActionButton(
721
- "ActionBarReload",
860
+ var ActionBarPrimitiveReload = createActionButton(
861
+ "ActionBarPrimitive.Reload",
722
862
  useActionBarReload
723
863
  );
724
864
 
725
865
  // src/primitives/actionBar/ActionBarEdit.tsx
726
- var ActionBarEdit = createActionButton(
727
- "ActionBarEdit",
866
+ var ActionBarPrimitiveEdit = createActionButton(
867
+ "ActionBarPrimitive.Edit",
728
868
  useActionBarEdit
729
869
  );
730
870
 
731
871
  // src/primitives/assistantModal/index.ts
732
872
  var assistantModal_exports = {};
733
873
  __export(assistantModal_exports, {
734
- Content: () => AssistantModalContent,
735
- Root: () => AssistantModalRoot,
736
- Trigger: () => AssistantModalTrigger
874
+ Content: () => AssistantModalPrimitiveContent,
875
+ Root: () => AssistantModalPrimitiveRoot,
876
+ Trigger: () => AssistantModalPrimitiveTrigger
737
877
  });
738
878
 
739
879
  // src/primitives/assistantModal/AssistantModalRoot.tsx
740
880
  import { useState as useState3 } from "react";
741
- import * as PopoverPrimitive from "@radix-ui/react-popover";
881
+ import * as PopoverPrimitive2 from "@radix-ui/react-popover";
742
882
  import { composeEventHandlers as composeEventHandlers2 } from "@radix-ui/primitive";
743
883
 
744
884
  // src/utils/hooks/useOnComposerFocus.tsx
745
885
  import { useCallbackRef } from "@radix-ui/react-use-callback-ref";
746
- import { useEffect as useEffect3 } from "react";
886
+ import { useEffect as useEffect6 } from "react";
747
887
  var useOnComposerFocus = (callback) => {
748
888
  const callbackRef = useCallbackRef(callback);
749
889
  const { useComposer } = useThreadContext();
750
- useEffect3(() => {
890
+ useEffect6(() => {
751
891
  return useComposer.getState().onFocus(() => {
752
892
  callbackRef();
753
893
  });
754
894
  }, [useComposer, callbackRef]);
755
895
  };
756
896
 
897
+ // src/primitives/assistantModal/scope.tsx
898
+ import * as PopoverPrimitive from "@radix-ui/react-popover";
899
+ var usePopoverScope = PopoverPrimitive.createPopoverScope();
900
+
757
901
  // src/primitives/assistantModal/AssistantModalRoot.tsx
758
902
  import { jsx as jsx6 } from "react/jsx-runtime";
759
- var usePopoverScope = PopoverPrimitive.createPopoverScope();
760
903
  var useAssistantModalOpenState = (defaultOpen = false) => {
761
904
  const state = useState3(defaultOpen);
762
905
  const [, setOpen] = state;
@@ -765,7 +908,7 @@ var useAssistantModalOpenState = (defaultOpen = false) => {
765
908
  });
766
909
  return state;
767
910
  };
768
- var AssistantModalRoot = ({
911
+ var AssistantModalPrimitiveRoot = ({
769
912
  __scopeAssistantModal,
770
913
  defaultOpen,
771
914
  open,
@@ -775,7 +918,7 @@ var AssistantModalRoot = ({
775
918
  const scope = usePopoverScope(__scopeAssistantModal);
776
919
  const [modalOpen, setOpen] = useAssistantModalOpenState(defaultOpen);
777
920
  return /* @__PURE__ */ jsx6(
778
- PopoverPrimitive.Root,
921
+ PopoverPrimitive2.Root,
779
922
  {
780
923
  ...scope,
781
924
  open: open === void 0 ? modalOpen : open,
@@ -784,26 +927,29 @@ var AssistantModalRoot = ({
784
927
  }
785
928
  );
786
929
  };
787
- AssistantModalRoot.displayName = "AssistantModalRoot";
930
+ AssistantModalPrimitiveRoot.displayName = "AssistantModalPrimitive.Root";
788
931
 
789
932
  // src/primitives/assistantModal/AssistantModalTrigger.tsx
790
933
  import { forwardRef as forwardRef3 } from "react";
791
- import * as PopoverPrimitive2 from "@radix-ui/react-popover";
934
+ import * as PopoverPrimitive3 from "@radix-ui/react-popover";
792
935
  import { jsx as jsx7 } from "react/jsx-runtime";
793
- var AssistantModalTrigger = forwardRef3(
794
- ({ __scopeAssistantModal, ...rest }, ref) => {
936
+ var AssistantModalPrimitiveTrigger = forwardRef3(
937
+ ({
938
+ __scopeAssistantModal,
939
+ ...rest
940
+ }, ref) => {
795
941
  const scope = usePopoverScope(__scopeAssistantModal);
796
- return /* @__PURE__ */ jsx7(PopoverPrimitive2.Trigger, { ...scope, ...rest, ref });
942
+ return /* @__PURE__ */ jsx7(PopoverPrimitive3.Trigger, { ...scope, ...rest, ref });
797
943
  }
798
944
  );
799
- AssistantModalTrigger.displayName = "AssistantModalTrigger";
945
+ AssistantModalPrimitiveTrigger.displayName = "AssistantModalPrimitive.Trigger";
800
946
 
801
947
  // src/primitives/assistantModal/AssistantModalContent.tsx
802
948
  import { forwardRef as forwardRef4 } from "react";
803
- import * as PopoverPrimitive3 from "@radix-ui/react-popover";
949
+ import * as PopoverPrimitive4 from "@radix-ui/react-popover";
804
950
  import { composeEventHandlers as composeEventHandlers3 } from "@radix-ui/primitive";
805
951
  import { jsx as jsx8 } from "react/jsx-runtime";
806
- var AssistantModalContent = forwardRef4(
952
+ var AssistantModalPrimitiveContent = forwardRef4(
807
953
  ({
808
954
  __scopeAssistantModal,
809
955
  side,
@@ -813,8 +959,8 @@ var AssistantModalContent = forwardRef4(
813
959
  ...props
814
960
  }, forwardedRef) => {
815
961
  const scope = usePopoverScope(__scopeAssistantModal);
816
- return /* @__PURE__ */ jsx8(PopoverPrimitive3.Portal, { ...scope, children: /* @__PURE__ */ jsx8(
817
- PopoverPrimitive3.Content,
962
+ return /* @__PURE__ */ jsx8(PopoverPrimitive4.Portal, { ...scope, children: /* @__PURE__ */ jsx8(
963
+ PopoverPrimitive4.Content,
818
964
  {
819
965
  ...scope,
820
966
  ...props,
@@ -829,43 +975,45 @@ var AssistantModalContent = forwardRef4(
829
975
  ) });
830
976
  }
831
977
  );
832
- AssistantModalContent.displayName = "AssistantModalContent";
978
+ AssistantModalPrimitiveContent.displayName = "AssistantModalPrimitive.Content";
833
979
 
834
980
  // src/primitives/branchPicker/index.ts
835
981
  var branchPicker_exports = {};
836
982
  __export(branchPicker_exports, {
837
- Count: () => BranchPickerCount,
838
- Next: () => BranchPickerNext,
839
- Number: () => BranchPickerNumber,
983
+ Count: () => BranchPickerPrimitiveCount,
984
+ Next: () => BranchPickerPrimitiveNext,
985
+ Number: () => BranchPickerPrimitiveNumber,
840
986
  Previous: () => BranchPickerPrevious,
841
- Root: () => BranchPickerRoot
987
+ Root: () => BranchPickerPrimitiveRoot
842
988
  });
843
989
 
844
990
  // src/primitives/branchPicker/BranchPickerNext.tsx
845
- var BranchPickerNext = createActionButton(
846
- "BranchPickerNext",
991
+ var BranchPickerPrimitiveNext = createActionButton(
992
+ "BranchPickerPrimitive.Next",
847
993
  useBranchPickerNext
848
994
  );
849
995
 
850
996
  // src/primitives/branchPicker/BranchPickerPrevious.tsx
851
997
  var BranchPickerPrevious = createActionButton(
852
- "BranchPickerPrevious",
998
+ "BranchPickerPrimitive.Previous",
853
999
  useBranchPickerPrevious
854
1000
  );
855
1001
 
856
1002
  // src/primitives/branchPicker/BranchPickerCount.tsx
857
1003
  import { Fragment, jsx as jsx9 } from "react/jsx-runtime";
858
- var BranchPickerCount = () => {
1004
+ var BranchPickerPrimitiveCount = () => {
859
1005
  const branchCount = useBranchPickerCount();
860
1006
  return /* @__PURE__ */ jsx9(Fragment, { children: branchCount });
861
1007
  };
1008
+ BranchPickerPrimitiveCount.displayName = "BranchPickerPrimitive.Count";
862
1009
 
863
1010
  // src/primitives/branchPicker/BranchPickerNumber.tsx
864
1011
  import { Fragment as Fragment2, jsx as jsx10 } from "react/jsx-runtime";
865
- var BranchPickerNumber = () => {
1012
+ var BranchPickerPrimitiveNumber = () => {
866
1013
  const branchNumber = useBranchPickerNumber();
867
1014
  return /* @__PURE__ */ jsx10(Fragment2, { children: branchNumber });
868
1015
  };
1016
+ BranchPickerPrimitiveNumber.displayName = "BranchPickerPrimitive.Number";
869
1017
 
870
1018
  // src/primitives/branchPicker/BranchPickerRoot.tsx
871
1019
  import { Primitive as Primitive6 } from "@radix-ui/react-primitive";
@@ -874,10 +1022,10 @@ import { forwardRef as forwardRef8 } from "react";
874
1022
  // src/primitives/message/index.ts
875
1023
  var message_exports = {};
876
1024
  __export(message_exports, {
877
- Content: () => MessageContent,
878
- If: () => MessageIf,
879
- InProgress: () => MessageInProgress,
880
- Root: () => MessageRoot
1025
+ Content: () => MessagePrimitiveContent,
1026
+ If: () => MessagePrimitiveIf,
1027
+ InProgress: () => MessagePrimitiveInProgress,
1028
+ Root: () => MessagePrimitiveRoot
881
1029
  });
882
1030
 
883
1031
  // src/primitives/message/MessageRoot.tsx
@@ -885,41 +1033,43 @@ import { composeEventHandlers as composeEventHandlers4 } from "@radix-ui/primiti
885
1033
  import { Primitive as Primitive3 } from "@radix-ui/react-primitive";
886
1034
  import { forwardRef as forwardRef5 } from "react";
887
1035
  import { jsx as jsx11 } from "react/jsx-runtime";
888
- var MessageRoot = forwardRef5(
889
- ({ onMouseEnter, onMouseLeave, ...rest }, ref) => {
890
- const { useMessageUtils } = useMessageContext();
891
- const setIsHovering = useMessageUtils((s) => s.setIsHovering);
892
- const handleMouseEnter = () => {
893
- setIsHovering(true);
894
- };
895
- const handleMouseLeave = () => {
896
- setIsHovering(false);
897
- };
898
- return /* @__PURE__ */ jsx11(
899
- Primitive3.div,
900
- {
901
- ...rest,
902
- ref,
903
- onMouseEnter: composeEventHandlers4(onMouseEnter, handleMouseEnter),
904
- onMouseLeave: composeEventHandlers4(onMouseLeave, handleMouseLeave)
905
- }
906
- );
907
- }
908
- );
909
- MessageRoot.displayName = "MessageRoot";
1036
+ var MessagePrimitiveRoot = forwardRef5(({ onMouseEnter, onMouseLeave, ...rest }, ref) => {
1037
+ const { useMessageUtils } = useMessageContext();
1038
+ const setIsHovering = useMessageUtils((s) => s.setIsHovering);
1039
+ const handleMouseEnter = () => {
1040
+ setIsHovering(true);
1041
+ };
1042
+ const handleMouseLeave = () => {
1043
+ setIsHovering(false);
1044
+ };
1045
+ return /* @__PURE__ */ jsx11(
1046
+ Primitive3.div,
1047
+ {
1048
+ ...rest,
1049
+ ref,
1050
+ onMouseEnter: composeEventHandlers4(onMouseEnter, handleMouseEnter),
1051
+ onMouseLeave: composeEventHandlers4(onMouseLeave, handleMouseLeave)
1052
+ }
1053
+ );
1054
+ });
1055
+ MessagePrimitiveRoot.displayName = "MessagePrimitive.Root";
910
1056
 
911
1057
  // src/primitives/message/MessageIf.tsx
912
- var MessageIf = ({ children, ...query }) => {
1058
+ var MessagePrimitiveIf = ({
1059
+ children,
1060
+ ...query
1061
+ }) => {
913
1062
  const result = useMessageIf(query);
914
1063
  return result ? children : null;
915
1064
  };
1065
+ MessagePrimitiveIf.displayName = "MessagePrimitive.If";
916
1066
 
917
1067
  // src/primitives/message/MessageContent.tsx
918
1068
  import { memo as memo2 } from "react";
919
1069
 
920
1070
  // src/context/providers/ContentPartProvider.tsx
921
- import { useEffect as useEffect4, useState as useState4 } from "react";
922
- import { create as create7 } from "zustand";
1071
+ import { useEffect as useEffect7, useState as useState4 } from "react";
1072
+ import { create as create9 } from "zustand";
923
1073
  import { jsx as jsx12 } from "react/jsx-runtime";
924
1074
  var syncContentPart = ({ message }, useContentPart, partIndex) => {
925
1075
  const part = message.content[partIndex];
@@ -938,13 +1088,13 @@ var syncContentPart = ({ message }, useContentPart, partIndex) => {
938
1088
  var useContentPartContext2 = (partIndex) => {
939
1089
  const { useMessage } = useMessageContext();
940
1090
  const [context] = useState4(() => {
941
- const useContentPart = create7(
1091
+ const useContentPart = create9(
942
1092
  () => ({})
943
1093
  );
944
1094
  syncContentPart(useMessage.getState(), useContentPart, partIndex);
945
1095
  return { useContentPart };
946
1096
  });
947
- useEffect4(() => {
1097
+ useEffect7(() => {
948
1098
  syncContentPart(useMessage.getState(), context.useContentPart, partIndex);
949
1099
  return useMessage.subscribe((message) => {
950
1100
  syncContentPart(message, context.useContentPart, partIndex);
@@ -961,42 +1111,67 @@ var ContentPartProvider = ({
961
1111
  };
962
1112
 
963
1113
  // src/primitives/contentPart/ContentPartDisplay.tsx
964
- var ContentPartDisplay = () => {
1114
+ var ContentPartPrimitiveDisplay = () => {
965
1115
  const display = useContentPartDisplay();
966
1116
  return display ?? null;
967
1117
  };
1118
+ ContentPartPrimitiveDisplay.displayName = "ContentPartPrimitive.Display";
1119
+
1120
+ // src/utils/OutPortal.tsx
1121
+ import { useLayoutEffect, useRef as useRef3 } from "react";
1122
+ import { jsx as jsx13 } from "react/jsx-runtime";
1123
+ var OutPortal = ({ node }) => {
1124
+ const parentRef = useRef3(null);
1125
+ useLayoutEffect(() => {
1126
+ const parent = parentRef.current;
1127
+ if (!parent || !node) return;
1128
+ parent.appendChild(node);
1129
+ return () => {
1130
+ parent.removeChild(node);
1131
+ };
1132
+ }, [node]);
1133
+ if (!node) return null;
1134
+ return /* @__PURE__ */ jsx13("span", { ref: parentRef });
1135
+ };
968
1136
 
969
1137
  // src/primitives/contentPart/ContentPartInProgressIndicator.tsx
970
- var ContentPartInProgressIndicator = () => {
971
- const indicator = useContentPartInProgressIndicator();
972
- return indicator;
1138
+ import { jsx as jsx14 } from "react/jsx-runtime";
1139
+ var ContentPartPrimitiveInProgressIndicator = () => {
1140
+ const { useMessageUtils } = useMessageContext();
1141
+ const { useContentPart } = useContentPartContext();
1142
+ const indicator = useCombinedStore(
1143
+ [useMessageUtils, useContentPart],
1144
+ (m, c) => c.status === "in_progress" ? m.inProgressIndicator : null
1145
+ );
1146
+ return /* @__PURE__ */ jsx14(OutPortal, { node: indicator });
973
1147
  };
1148
+ ContentPartPrimitiveInProgressIndicator.displayName = "ContentPartPrimitive.InProgressIndicator";
974
1149
 
975
1150
  // src/primitives/contentPart/ContentPartText.tsx
976
1151
  import { Primitive as Primitive4 } from "@radix-ui/react-primitive";
977
1152
  import { forwardRef as forwardRef6 } from "react";
978
- import { jsx as jsx13 } from "react/jsx-runtime";
979
- var ContentPartText = forwardRef6((props, forwardedRef) => {
1153
+ import { jsx as jsx15 } from "react/jsx-runtime";
1154
+ var ContentPartPrimitiveText = forwardRef6((props, forwardedRef) => {
980
1155
  const text = useContentPartText();
981
- return /* @__PURE__ */ jsx13(Primitive4.p, { ...props, ref: forwardedRef, children: text });
1156
+ return /* @__PURE__ */ jsx15(Primitive4.span, { ...props, ref: forwardedRef, children: text });
982
1157
  });
983
- ContentPartText.displayName = "ContentPartText";
1158
+ ContentPartPrimitiveText.displayName = "ContentPartPrimitive.Text";
984
1159
 
985
1160
  // src/primitives/message/MessageContent.tsx
986
- import { Fragment as Fragment3, jsx as jsx14, jsxs as jsxs2 } from "react/jsx-runtime";
1161
+ import { jsx as jsx16, jsxs as jsxs2 } from "react/jsx-runtime";
987
1162
  var defaultComponents = {
988
- Text: () => /* @__PURE__ */ jsxs2(Fragment3, { children: [
989
- /* @__PURE__ */ jsx14(ContentPartText, { style: { whiteSpace: "pre-line" } }),
990
- /* @__PURE__ */ jsx14(ContentPartInProgressIndicator, {})
1163
+ Text: () => /* @__PURE__ */ jsxs2("p", { style: { whiteSpace: "pre-line" }, children: [
1164
+ /* @__PURE__ */ jsx16(ContentPartPrimitiveText, {}),
1165
+ /* @__PURE__ */ jsx16(ContentPartPrimitiveInProgressIndicator, {})
991
1166
  ] }),
992
1167
  Image: () => null,
993
- UI: () => /* @__PURE__ */ jsx14(ContentPartDisplay, {}),
1168
+ UI: () => /* @__PURE__ */ jsx16(ContentPartPrimitiveDisplay, {}),
994
1169
  tools: {
995
1170
  Fallback: (props) => {
996
1171
  const { useToolUIs } = useAssistantContext();
997
1172
  const Render = useToolUIs((s) => s.getToolUI(props.part.toolName));
998
1173
  if (!Render) return null;
999
- return /* @__PURE__ */ jsx14(Render, { ...props });
1174
+ return /* @__PURE__ */ jsx16(Render, { ...props });
1000
1175
  }
1001
1176
  }
1002
1177
  };
@@ -1015,15 +1190,15 @@ var MessageContentPartComponent = ({
1015
1190
  const type = part.type;
1016
1191
  switch (type) {
1017
1192
  case "text":
1018
- return /* @__PURE__ */ jsx14(Text, { part, status });
1193
+ return /* @__PURE__ */ jsx16(Text, { part, status });
1019
1194
  case "image":
1020
- return /* @__PURE__ */ jsx14(Image, { part, status });
1195
+ return /* @__PURE__ */ jsx16(Image, { part, status });
1021
1196
  case "ui":
1022
- return /* @__PURE__ */ jsx14(UI, { part, status });
1197
+ return /* @__PURE__ */ jsx16(UI, { part, status });
1023
1198
  case "tool-call": {
1024
1199
  const Tool = by_name[part.toolName] || Fallback;
1025
1200
  const addResult = (result) => addToolResult(part.toolCallId, result);
1026
- return /* @__PURE__ */ jsx14(Tool, { part, status, addResult });
1201
+ return /* @__PURE__ */ jsx16(Tool, { part, status, addResult });
1027
1202
  }
1028
1203
  default:
1029
1204
  throw new Error(`Unknown content part type: ${type}`);
@@ -1033,18 +1208,20 @@ var MessageContentPartImpl = ({
1033
1208
  partIndex,
1034
1209
  components
1035
1210
  }) => {
1036
- return /* @__PURE__ */ jsx14(ContentPartProvider, { partIndex, children: /* @__PURE__ */ jsx14(MessageContentPartComponent, { components }) });
1211
+ return /* @__PURE__ */ jsx16(ContentPartProvider, { partIndex, children: /* @__PURE__ */ jsx16(MessageContentPartComponent, { components }) });
1037
1212
  };
1038
1213
  var MessageContentPart = memo2(
1039
1214
  MessageContentPartImpl,
1040
1215
  (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
1041
1216
  );
1042
- var MessageContent = ({ components }) => {
1217
+ var MessagePrimitiveContent = ({
1218
+ components
1219
+ }) => {
1043
1220
  const { useMessage } = useMessageContext();
1044
1221
  const contentLength = useMessage((s) => s.message.content.length);
1045
1222
  return new Array(contentLength).fill(null).map((_, idx) => {
1046
1223
  const partIndex = idx;
1047
- return /* @__PURE__ */ jsx14(
1224
+ return /* @__PURE__ */ jsx16(
1048
1225
  MessageContentPart,
1049
1226
  {
1050
1227
  partIndex,
@@ -1054,38 +1231,35 @@ var MessageContent = ({ components }) => {
1054
1231
  );
1055
1232
  });
1056
1233
  };
1234
+ MessagePrimitiveContent.displayName = "MessagePrimitive.Content";
1057
1235
 
1058
1236
  // src/primitives/message/MessageInProgress.tsx
1237
+ import { createPortal } from "react-dom";
1059
1238
  import { Primitive as Primitive5 } from "@radix-ui/react-primitive";
1060
- import {
1061
- forwardRef as forwardRef7,
1062
- useMemo as useMemo3
1063
- } from "react";
1064
- import { jsx as jsx15 } from "react/jsx-runtime";
1065
- var MessageInProgress = forwardRef7((props, ref) => {
1239
+ import { forwardRef as forwardRef7 } from "react";
1240
+ import { jsx as jsx17 } from "react/jsx-runtime";
1241
+ var MessagePrimitiveInProgress = forwardRef7((props, ref) => {
1066
1242
  const { useMessageUtils } = useMessageContext();
1067
- useMemo3(() => {
1068
- useMessageUtils.getState().setInProgressIndicator(/* @__PURE__ */ jsx15(Primitive5.span, { ...props, ref }));
1069
- }, [useMessageUtils, props, ref]);
1070
- return null;
1243
+ const portalNode = useMessageUtils((s) => s.inProgressIndicator);
1244
+ return createPortal(/* @__PURE__ */ jsx17(Primitive5.span, { ...props, ref }), portalNode);
1071
1245
  });
1072
- MessageInProgress.displayName = "MessageInProgress";
1246
+ MessagePrimitiveInProgress.displayName = "MessagePrimitive.InProgress";
1073
1247
 
1074
1248
  // src/primitives/branchPicker/BranchPickerRoot.tsx
1075
- import { jsx as jsx16 } from "react/jsx-runtime";
1076
- var BranchPickerRoot = forwardRef8(({ hideWhenSingleBranch, ...rest }, ref) => {
1077
- return /* @__PURE__ */ jsx16(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0, children: /* @__PURE__ */ jsx16(Primitive6.div, { ...rest, ref }) });
1249
+ import { jsx as jsx18 } from "react/jsx-runtime";
1250
+ var BranchPickerPrimitiveRoot = forwardRef8(({ hideWhenSingleBranch, ...rest }, ref) => {
1251
+ return /* @__PURE__ */ jsx18(MessagePrimitiveIf, { hasBranches: hideWhenSingleBranch ? true : void 0, children: /* @__PURE__ */ jsx18(Primitive6.div, { ...rest, ref }) });
1078
1252
  });
1079
- BranchPickerRoot.displayName = "BranchPickerRoot";
1253
+ BranchPickerPrimitiveRoot.displayName = "BranchPickerPrimitive.Root";
1080
1254
 
1081
1255
  // src/primitives/composer/index.ts
1082
1256
  var composer_exports = {};
1083
1257
  __export(composer_exports, {
1084
- Cancel: () => ComposerCancel,
1085
- If: () => ComposerIf,
1086
- Input: () => ComposerInput,
1087
- Root: () => ComposerRoot,
1088
- Send: () => ComposerSend
1258
+ Cancel: () => ComposerPrimitiveCancel,
1259
+ If: () => ComposerPrimitiveIf,
1260
+ Input: () => ComposerPrimitiveInput,
1261
+ Root: () => ComposerPrimitiveRoot,
1262
+ Send: () => ComposerPrimitiveSend
1089
1263
  });
1090
1264
 
1091
1265
  // src/primitives/composer/ComposerRoot.tsx
@@ -1094,26 +1268,24 @@ import { Primitive as Primitive7 } from "@radix-ui/react-primitive";
1094
1268
  import {
1095
1269
  forwardRef as forwardRef9
1096
1270
  } from "react";
1097
- import { jsx as jsx17 } from "react/jsx-runtime";
1098
- var ComposerRoot = forwardRef9(
1099
- ({ onSubmit, ...rest }, forwardedRef) => {
1100
- const send = useComposerSend();
1101
- const handleSubmit = (e) => {
1102
- if (!send) return;
1103
- e.preventDefault();
1104
- send();
1105
- };
1106
- return /* @__PURE__ */ jsx17(
1107
- Primitive7.form,
1108
- {
1109
- ...rest,
1110
- ref: forwardedRef,
1111
- onSubmit: composeEventHandlers5(onSubmit, handleSubmit)
1112
- }
1113
- );
1114
- }
1115
- );
1116
- ComposerRoot.displayName = "ComposerRoot";
1271
+ import { jsx as jsx19 } from "react/jsx-runtime";
1272
+ var ComposerPrimitiveRoot = forwardRef9(({ onSubmit, ...rest }, forwardedRef) => {
1273
+ const send = useComposerSend();
1274
+ const handleSubmit = (e) => {
1275
+ e.preventDefault();
1276
+ if (!send) return;
1277
+ send();
1278
+ };
1279
+ return /* @__PURE__ */ jsx19(
1280
+ Primitive7.form,
1281
+ {
1282
+ ...rest,
1283
+ ref: forwardedRef,
1284
+ onSubmit: composeEventHandlers5(onSubmit, handleSubmit)
1285
+ }
1286
+ );
1287
+ });
1288
+ ComposerPrimitiveRoot.displayName = "ComposerPrimitive.Root";
1117
1289
 
1118
1290
  // src/primitives/composer/ComposerInput.tsx
1119
1291
  import { composeEventHandlers as composeEventHandlers6 } from "@radix-ui/primitive";
@@ -1121,14 +1293,14 @@ import { useComposedRefs } from "@radix-ui/react-compose-refs";
1121
1293
  import { Slot } from "@radix-ui/react-slot";
1122
1294
  import {
1123
1295
  forwardRef as forwardRef10,
1124
- useCallback as useCallback10,
1125
- useEffect as useEffect5,
1126
- useRef as useRef3
1296
+ useCallback as useCallback13,
1297
+ useEffect as useEffect8,
1298
+ useRef as useRef4
1127
1299
  } from "react";
1128
1300
  import TextareaAutosize from "react-textarea-autosize";
1129
1301
  import { useEscapeKeydown } from "@radix-ui/react-use-escape-keydown";
1130
- import { jsx as jsx18 } from "react/jsx-runtime";
1131
- var ComposerInput = forwardRef10(
1302
+ import { jsx as jsx20 } from "react/jsx-runtime";
1303
+ var ComposerPrimitiveInput = forwardRef10(
1132
1304
  ({ autoFocus = false, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
1133
1305
  const { useThread } = useThreadContext();
1134
1306
  const { useComposer, type } = useComposerContext();
@@ -1137,7 +1309,7 @@ var ComposerInput = forwardRef10(
1137
1309
  return c.value;
1138
1310
  });
1139
1311
  const Component = asChild ? Slot : TextareaAutosize;
1140
- const textareaRef = useRef3(null);
1312
+ const textareaRef = useRef4(null);
1141
1313
  const ref = useComposedRefs(forwardedRef, textareaRef);
1142
1314
  useEscapeKeydown((e) => {
1143
1315
  const composer = useComposer.getState();
@@ -1156,7 +1328,7 @@ var ComposerInput = forwardRef10(
1156
1328
  }
1157
1329
  };
1158
1330
  const autoFocusEnabled = autoFocus && !disabled;
1159
- const focus = useCallback10(() => {
1331
+ const focus = useCallback13(() => {
1160
1332
  const textarea = textareaRef.current;
1161
1333
  if (!textarea || !autoFocusEnabled) return;
1162
1334
  textarea.focus({ preventScroll: true });
@@ -1165,13 +1337,13 @@ var ComposerInput = forwardRef10(
1165
1337
  textareaRef.current.value.length
1166
1338
  );
1167
1339
  }, [autoFocusEnabled]);
1168
- useEffect5(() => focus(), [focus]);
1340
+ useEffect8(() => focus(), [focus]);
1169
1341
  useOnComposerFocus(() => {
1170
1342
  if (type === "new") {
1171
1343
  focus();
1172
1344
  }
1173
1345
  });
1174
- return /* @__PURE__ */ jsx18(
1346
+ return /* @__PURE__ */ jsx20(
1175
1347
  Component,
1176
1348
  {
1177
1349
  value,
@@ -1188,94 +1360,101 @@ var ComposerInput = forwardRef10(
1188
1360
  );
1189
1361
  }
1190
1362
  );
1191
- ComposerInput.displayName = "ComposerInput";
1363
+ ComposerPrimitiveInput.displayName = "ComposerPrimitive.Input";
1192
1364
 
1193
1365
  // src/primitives/composer/ComposerSend.tsx
1194
1366
  import { forwardRef as forwardRef11 } from "react";
1195
1367
  import { Primitive as Primitive8 } from "@radix-ui/react-primitive";
1196
- import { jsx as jsx19 } from "react/jsx-runtime";
1197
- var ComposerSend = forwardRef11(
1198
- ({ disabled, ...rest }, ref) => {
1199
- const { useComposer } = useComposerContext();
1200
- const hasValue = useComposer((c) => c.isEditing && c.value.length > 0);
1201
- return /* @__PURE__ */ jsx19(
1202
- Primitive8.button,
1203
- {
1204
- type: "submit",
1205
- ...rest,
1206
- ref,
1207
- disabled: disabled || !hasValue
1208
- }
1209
- );
1210
- }
1211
- );
1212
- ComposerSend.displayName = "ComposerSend";
1368
+ import { jsx as jsx21 } from "react/jsx-runtime";
1369
+ var ComposerPrimitiveSend = forwardRef11(({ disabled, ...rest }, ref) => {
1370
+ const { useComposer } = useComposerContext();
1371
+ const hasValue = useComposer((c) => c.isEditing && c.value.length > 0);
1372
+ return /* @__PURE__ */ jsx21(
1373
+ Primitive8.button,
1374
+ {
1375
+ type: "submit",
1376
+ ...rest,
1377
+ ref,
1378
+ disabled: disabled || !hasValue
1379
+ }
1380
+ );
1381
+ });
1382
+ ComposerPrimitiveSend.displayName = "ComposerPrimitive.Send";
1213
1383
 
1214
1384
  // src/primitives/composer/ComposerCancel.tsx
1215
- var ComposerCancel = createActionButton(
1216
- "ComposerCancel",
1385
+ var ComposerPrimitiveCancel = createActionButton(
1386
+ "ComposerPrimitive.Cancel",
1217
1387
  useComposerCancel
1218
1388
  );
1219
1389
 
1220
1390
  // src/primitives/composer/ComposerIf.tsx
1221
- var ComposerIf = ({ children, ...query }) => {
1391
+ var ComposerPrimitiveIf = ({
1392
+ children,
1393
+ ...query
1394
+ }) => {
1222
1395
  const result = useComposerIf(query);
1223
1396
  return result ? children : null;
1224
1397
  };
1398
+ ComposerPrimitiveIf.displayName = "ComposerPrimitive.If";
1225
1399
 
1226
1400
  // src/primitives/contentPart/index.ts
1227
1401
  var contentPart_exports = {};
1228
1402
  __export(contentPart_exports, {
1229
- Display: () => ContentPartDisplay,
1230
- Image: () => ContentPartImage,
1231
- InProgressIndicator: () => ContentPartInProgressIndicator,
1232
- Text: () => ContentPartText
1403
+ Display: () => ContentPartPrimitiveDisplay,
1404
+ Image: () => ContentPartPrimitiveImage,
1405
+ InProgressIndicator: () => ContentPartPrimitiveInProgressIndicator,
1406
+ Text: () => ContentPartPrimitiveText
1233
1407
  });
1234
1408
 
1235
1409
  // src/primitives/contentPart/ContentPartImage.tsx
1236
1410
  import { Primitive as Primitive9 } from "@radix-ui/react-primitive";
1237
1411
  import { forwardRef as forwardRef12 } from "react";
1238
- import { jsx as jsx20 } from "react/jsx-runtime";
1239
- var ContentPartImage = forwardRef12((props, forwardedRef) => {
1412
+ import { jsx as jsx22 } from "react/jsx-runtime";
1413
+ var ContentPartPrimitiveImage = forwardRef12((props, forwardedRef) => {
1240
1414
  const image = useContentPartImage();
1241
- return /* @__PURE__ */ jsx20(Primitive9.img, { src: image, ...props, ref: forwardedRef });
1415
+ return /* @__PURE__ */ jsx22(Primitive9.img, { src: image, ...props, ref: forwardedRef });
1242
1416
  });
1243
- ContentPartImage.displayName = "ContentPartImage";
1417
+ ContentPartPrimitiveImage.displayName = "ContentPartPrimitive.Image";
1244
1418
 
1245
1419
  // src/primitives/thread/index.ts
1246
1420
  var thread_exports = {};
1247
1421
  __export(thread_exports, {
1248
- Empty: () => ThreadEmpty,
1249
- If: () => ThreadIf,
1250
- Messages: () => ThreadMessages,
1251
- Root: () => ThreadRoot,
1252
- ScrollToBottom: () => ThreadScrollToBottom,
1253
- Suggestion: () => ThreadSuggestion,
1254
- Viewport: () => ThreadViewport
1422
+ Empty: () => ThreadPrimitiveEmpty,
1423
+ If: () => ThreadPrimitiveIf,
1424
+ Messages: () => ThreadPrimitiveMessages,
1425
+ Root: () => ThreadPrimitiveRoot,
1426
+ ScrollToBottom: () => ThreadPrimitiveScrollToBottom,
1427
+ Suggestion: () => ThreadPrimitiveSuggestion,
1428
+ Viewport: () => ThreadPrimitiveViewport
1255
1429
  });
1256
1430
 
1257
1431
  // src/primitives/thread/ThreadRoot.tsx
1258
1432
  import { Primitive as Primitive10 } from "@radix-ui/react-primitive";
1259
1433
  import { forwardRef as forwardRef13 } from "react";
1260
- import { jsx as jsx21 } from "react/jsx-runtime";
1261
- var ThreadRoot = forwardRef13(
1262
- (props, ref) => {
1263
- return /* @__PURE__ */ jsx21(Primitive10.div, { ...props, ref });
1264
- }
1265
- );
1266
- ThreadRoot.displayName = "ThreadRoot";
1434
+ import { jsx as jsx23 } from "react/jsx-runtime";
1435
+ var ThreadPrimitiveRoot = forwardRef13((props, ref) => {
1436
+ return /* @__PURE__ */ jsx23(Primitive10.div, { ...props, ref });
1437
+ });
1438
+ ThreadPrimitiveRoot.displayName = "ThreadPrimitive.Root";
1267
1439
 
1268
1440
  // src/primitives/thread/ThreadEmpty.tsx
1269
- var ThreadEmpty = ({ children }) => {
1441
+ var ThreadPrimitiveEmpty = ({
1442
+ children
1443
+ }) => {
1270
1444
  const empty = useThreadEmpty();
1271
1445
  return empty ? children : null;
1272
1446
  };
1447
+ ThreadPrimitiveEmpty.displayName = "ThreadPrimitive.Empty";
1273
1448
 
1274
1449
  // src/primitives/thread/ThreadIf.tsx
1275
- var ThreadIf = ({ children, ...query }) => {
1450
+ var ThreadPrimitiveIf = ({
1451
+ children,
1452
+ ...query
1453
+ }) => {
1276
1454
  const result = useThreadIf(query);
1277
1455
  return result ? children : null;
1278
1456
  };
1457
+ ThreadPrimitiveIf.displayName = "ThreadPrimitive.If";
1279
1458
 
1280
1459
  // src/primitives/thread/ThreadViewport.tsx
1281
1460
  import { useComposedRefs as useComposedRefs3 } from "@radix-ui/react-compose-refs";
@@ -1284,17 +1463,17 @@ import { forwardRef as forwardRef14 } from "react";
1284
1463
 
1285
1464
  // src/primitive-hooks/thread/useThreadViewportAutoScroll.tsx
1286
1465
  import { useComposedRefs as useComposedRefs2 } from "@radix-ui/react-compose-refs";
1287
- import { useRef as useRef5 } from "react";
1466
+ import { useRef as useRef6 } from "react";
1288
1467
 
1289
1468
  // src/utils/hooks/useOnResizeContent.tsx
1290
1469
  import { useCallbackRef as useCallbackRef2 } from "@radix-ui/react-use-callback-ref";
1291
- import { useCallback as useCallback12 } from "react";
1470
+ import { useCallback as useCallback15 } from "react";
1292
1471
 
1293
1472
  // src/utils/hooks/useManagedRef.ts
1294
- import { useCallback as useCallback11, useRef as useRef4 } from "react";
1473
+ import { useCallback as useCallback14, useRef as useRef5 } from "react";
1295
1474
  var useManagedRef = (callback) => {
1296
- const cleanupRef = useRef4();
1297
- const ref = useCallback11(
1475
+ const cleanupRef = useRef5();
1476
+ const ref = useCallback14(
1298
1477
  (el) => {
1299
1478
  if (cleanupRef.current) {
1300
1479
  cleanupRef.current();
@@ -1311,7 +1490,7 @@ var useManagedRef = (callback) => {
1311
1490
  // src/utils/hooks/useOnResizeContent.tsx
1312
1491
  var useOnResizeContent = (callback) => {
1313
1492
  const callbackRef = useCallbackRef2(callback);
1314
- const refCallback = useCallback12(
1493
+ const refCallback = useCallback15(
1315
1494
  (el) => {
1316
1495
  const resizeObserver = new ResizeObserver(() => {
1317
1496
  callbackRef();
@@ -1348,11 +1527,11 @@ var useOnResizeContent = (callback) => {
1348
1527
 
1349
1528
  // src/utils/hooks/useOnScrollToBottom.tsx
1350
1529
  import { useCallbackRef as useCallbackRef3 } from "@radix-ui/react-use-callback-ref";
1351
- import { useEffect as useEffect6 } from "react";
1530
+ import { useEffect as useEffect9 } from "react";
1352
1531
  var useOnScrollToBottom = (callback) => {
1353
1532
  const callbackRef = useCallbackRef3(callback);
1354
1533
  const { useViewport } = useThreadContext();
1355
- useEffect6(() => {
1534
+ useEffect9(() => {
1356
1535
  return useViewport.getState().onScrollToBottom(() => {
1357
1536
  callbackRef();
1358
1537
  });
@@ -1363,11 +1542,11 @@ var useOnScrollToBottom = (callback) => {
1363
1542
  var useThreadViewportAutoScroll = ({
1364
1543
  autoScroll = true
1365
1544
  }) => {
1366
- const divRef = useRef5(null);
1545
+ const divRef = useRef6(null);
1367
1546
  const { useViewport } = useThreadContext();
1368
- const firstRenderRef = useRef5(true);
1369
- const lastScrollTop = useRef5(0);
1370
- const isScrollingToBottomRef = useRef5(false);
1547
+ const firstRenderRef = useRef6(true);
1548
+ const lastScrollTop = useRef6(0);
1549
+ const isScrollingToBottomRef = useRef6(false);
1371
1550
  const scrollToBottom = () => {
1372
1551
  const div = divRef.current;
1373
1552
  if (!div || !autoScroll) return;
@@ -1413,29 +1592,29 @@ var useThreadViewportAutoScroll = ({
1413
1592
  };
1414
1593
 
1415
1594
  // src/primitives/thread/ThreadViewport.tsx
1416
- import { jsx as jsx22 } from "react/jsx-runtime";
1417
- var ThreadViewport = forwardRef14(({ autoScroll, onScroll, children, ...rest }, forwardedRef) => {
1595
+ import { jsx as jsx24 } from "react/jsx-runtime";
1596
+ var ThreadPrimitiveViewport = forwardRef14(({ autoScroll, onScroll, children, ...rest }, forwardedRef) => {
1418
1597
  const autoScrollRef = useThreadViewportAutoScroll({
1419
1598
  autoScroll
1420
1599
  });
1421
1600
  const ref = useComposedRefs3(forwardedRef, autoScrollRef);
1422
- return /* @__PURE__ */ jsx22(Primitive11.div, { ...rest, ref, children });
1601
+ return /* @__PURE__ */ jsx24(Primitive11.div, { ...rest, ref, children });
1423
1602
  });
1424
- ThreadViewport.displayName = "ThreadViewport";
1603
+ ThreadPrimitiveViewport.displayName = "ThreadPrimitive.Viewport";
1425
1604
 
1426
1605
  // src/primitives/thread/ThreadMessages.tsx
1427
1606
  import { memo as memo3 } from "react";
1428
1607
 
1429
1608
  // src/context/providers/MessageProvider.tsx
1430
- import { useEffect as useEffect7, useState as useState5 } from "react";
1431
- import { create as create10 } from "zustand";
1609
+ import { useEffect as useEffect10, useState as useState5 } from "react";
1610
+ import { create as create12 } from "zustand";
1432
1611
 
1433
1612
  // src/context/stores/EditComposer.ts
1434
- import { create as create8 } from "zustand";
1613
+ import { create as create10 } from "zustand";
1435
1614
  var makeEditComposerStore = ({
1436
1615
  onEdit,
1437
1616
  onSend
1438
- }) => create8()((set, get, store) => ({
1617
+ }) => create10()((set, get, store) => ({
1439
1618
  ...makeBaseComposer(set, get, store),
1440
1619
  isEditing: false,
1441
1620
  edit: () => {
@@ -1455,12 +1634,9 @@ var makeEditComposerStore = ({
1455
1634
  }));
1456
1635
 
1457
1636
  // src/context/stores/MessageUtils.ts
1458
- import { create as create9 } from "zustand";
1459
- var makeMessageUtilsStore = () => create9((set) => ({
1460
- inProgressIndicator: null,
1461
- setInProgressIndicator: (value) => {
1462
- set({ inProgressIndicator: value });
1463
- },
1637
+ import { create as create11 } from "zustand";
1638
+ var makeMessageUtilsStore = () => create11((set) => ({
1639
+ inProgressIndicator: document.createElement("span"),
1464
1640
  isCopied: false,
1465
1641
  setIsCopied: (value) => {
1466
1642
  set({ isCopied: value });
@@ -1472,15 +1648,15 @@ var makeMessageUtilsStore = () => create9((set) => ({
1472
1648
  }));
1473
1649
 
1474
1650
  // src/context/providers/MessageProvider.tsx
1475
- import { jsx as jsx23 } from "react/jsx-runtime";
1476
- var getIsLast = (thread, message) => {
1477
- return thread.messages[thread.messages.length - 1]?.id === message.id;
1651
+ import { jsx as jsx25 } from "react/jsx-runtime";
1652
+ var getIsLast = (messages, message) => {
1653
+ return messages[messages.length - 1]?.id === message.id;
1478
1654
  };
1479
- var syncMessage = (thread, getBranches, useMessage, messageIndex) => {
1480
- const parentId = thread.messages[messageIndex - 1]?.id ?? null;
1481
- const message = thread.messages[messageIndex];
1655
+ var syncMessage = (messages, getBranches, useMessage, messageIndex) => {
1656
+ const parentId = messages[messageIndex - 1]?.id ?? null;
1657
+ const message = messages[messageIndex];
1482
1658
  if (!message) return;
1483
- const isLast = getIsLast(thread, message);
1659
+ const isLast = getIsLast(messages, message);
1484
1660
  const branches = getBranches(message.id);
1485
1661
  const currentState = useMessage.getState();
1486
1662
  if (currentState.message === message && currentState.parentId === parentId && currentState.branches === branches && currentState.isLast === isLast)
@@ -1493,9 +1669,9 @@ var syncMessage = (thread, getBranches, useMessage, messageIndex) => {
1493
1669
  });
1494
1670
  };
1495
1671
  var useMessageContext2 = (messageIndex) => {
1496
- const { useThread, useThreadActions } = useThreadContext();
1672
+ const { useThreadMessages, useThreadActions } = useThreadContext();
1497
1673
  const [context] = useState5(() => {
1498
- const useMessage = create10(() => ({}));
1674
+ const useMessage = create12(() => ({}));
1499
1675
  const useMessageUtils = makeMessageUtilsStore();
1500
1676
  const useEditComposer = makeEditComposerStore({
1501
1677
  onEdit: () => {
@@ -1524,15 +1700,15 @@ var useMessageContext2 = (messageIndex) => {
1524
1700
  }
1525
1701
  });
1526
1702
  syncMessage(
1527
- useThread.getState(),
1703
+ useThreadMessages.getState(),
1528
1704
  useThreadActions.getState().getBranches,
1529
1705
  useMessage,
1530
1706
  messageIndex
1531
1707
  );
1532
1708
  return { useMessage, useMessageUtils, useEditComposer };
1533
1709
  });
1534
- useEffect7(() => {
1535
- return useThread.subscribe((thread) => {
1710
+ useEffect10(() => {
1711
+ return useThreadMessages.subscribe((thread) => {
1536
1712
  syncMessage(
1537
1713
  thread,
1538
1714
  useThreadActions.getState().getBranches,
@@ -1540,7 +1716,7 @@ var useMessageContext2 = (messageIndex) => {
1540
1716
  messageIndex
1541
1717
  );
1542
1718
  });
1543
- }, [useThread, useThreadActions, context, messageIndex]);
1719
+ }, [useThreadMessages, useThreadActions, context, messageIndex]);
1544
1720
  return context;
1545
1721
  };
1546
1722
  var MessageProvider = ({
@@ -1548,11 +1724,11 @@ var MessageProvider = ({
1548
1724
  children
1549
1725
  }) => {
1550
1726
  const context = useMessageContext2(messageIndex);
1551
- return /* @__PURE__ */ jsx23(MessageContext.Provider, { value: context, children });
1727
+ return /* @__PURE__ */ jsx25(MessageContext.Provider, { value: context, children });
1552
1728
  };
1553
1729
 
1554
1730
  // src/primitives/thread/ThreadMessages.tsx
1555
- import { jsx as jsx24, jsxs as jsxs3 } from "react/jsx-runtime";
1731
+ import { jsx as jsx26, jsxs as jsxs3 } from "react/jsx-runtime";
1556
1732
  var getComponents = (components) => {
1557
1733
  return {
1558
1734
  EditComposer: components.EditComposer ?? components.UserMessage ?? components.Message,
@@ -1566,24 +1742,26 @@ var ThreadMessageImpl = ({
1566
1742
  }) => {
1567
1743
  const { UserMessage, EditComposer, AssistantMessage } = getComponents(components);
1568
1744
  return /* @__PURE__ */ jsxs3(MessageProvider, { messageIndex, children: [
1569
- /* @__PURE__ */ jsxs3(MessageIf, { user: true, children: [
1570
- /* @__PURE__ */ jsx24(ComposerIf, { editing: false, children: /* @__PURE__ */ jsx24(UserMessage, {}) }),
1571
- /* @__PURE__ */ jsx24(ComposerIf, { editing: true, children: /* @__PURE__ */ jsx24(EditComposer, {}) })
1745
+ /* @__PURE__ */ jsxs3(MessagePrimitiveIf, { user: true, children: [
1746
+ /* @__PURE__ */ jsx26(ComposerPrimitiveIf, { editing: false, children: /* @__PURE__ */ jsx26(UserMessage, {}) }),
1747
+ /* @__PURE__ */ jsx26(ComposerPrimitiveIf, { editing: true, children: /* @__PURE__ */ jsx26(EditComposer, {}) })
1572
1748
  ] }),
1573
- /* @__PURE__ */ jsx24(MessageIf, { assistant: true, children: /* @__PURE__ */ jsx24(AssistantMessage, {}) })
1749
+ /* @__PURE__ */ jsx26(MessagePrimitiveIf, { assistant: true, children: /* @__PURE__ */ jsx26(AssistantMessage, {}) })
1574
1750
  ] });
1575
1751
  };
1576
1752
  var ThreadMessage = memo3(
1577
1753
  ThreadMessageImpl,
1578
1754
  (prev, next) => prev.messageIndex === next.messageIndex && prev.components.UserMessage === next.components.UserMessage && prev.components.EditComposer === next.components.EditComposer && prev.components.AssistantMessage === next.components.AssistantMessage
1579
1755
  );
1580
- var ThreadMessages = ({ components }) => {
1581
- const { useThread } = useThreadContext();
1582
- const messagesLength = useThread((t) => t.messages.length);
1756
+ var ThreadPrimitiveMessages = ({
1757
+ components
1758
+ }) => {
1759
+ const { useThreadMessages } = useThreadContext();
1760
+ const messagesLength = useThreadMessages((t) => t.length);
1583
1761
  if (messagesLength === 0) return null;
1584
1762
  return new Array(messagesLength).fill(null).map((_, idx) => {
1585
1763
  const messageIndex = idx;
1586
- return /* @__PURE__ */ jsx24(
1764
+ return /* @__PURE__ */ jsx26(
1587
1765
  ThreadMessage,
1588
1766
  {
1589
1767
  messageIndex,
@@ -1593,16 +1771,17 @@ var ThreadMessages = ({ components }) => {
1593
1771
  );
1594
1772
  });
1595
1773
  };
1774
+ ThreadPrimitiveMessages.displayName = "ThreadPrimitive.Messages";
1596
1775
 
1597
1776
  // src/primitives/thread/ThreadScrollToBottom.tsx
1598
- var ThreadScrollToBottom = createActionButton(
1599
- "ThreadScrollToBottom",
1777
+ var ThreadPrimitiveScrollToBottom = createActionButton(
1778
+ "ThreadPrimitive.ScrollToBottom",
1600
1779
  useThreadScrollToBottom
1601
1780
  );
1602
1781
 
1603
1782
  // src/primitives/thread/ThreadSuggestion.tsx
1604
- var ThreadSuggestion = createActionButton(
1605
- "ThreadSuggestion",
1783
+ var ThreadPrimitiveSuggestion = createActionButton(
1784
+ "ThreadPrimitive.Suggestion",
1606
1785
  useThreadSuggestion
1607
1786
  );
1608
1787
 
@@ -1769,13 +1948,91 @@ var MessageRepository = class {
1769
1948
  }
1770
1949
  };
1771
1950
 
1951
+ // src/runtime/core/BaseAssistantRuntime.tsx
1952
+ var BaseAssistantRuntime = class {
1953
+ constructor(_thread) {
1954
+ this._thread = _thread;
1955
+ this._thread = _thread;
1956
+ this._unsubscribe = this._thread.subscribe(this.subscriptionHandler);
1957
+ }
1958
+ _unsubscribe;
1959
+ get thread() {
1960
+ return this._thread;
1961
+ }
1962
+ set thread(thread) {
1963
+ this._unsubscribe();
1964
+ this._thread = thread;
1965
+ this._unsubscribe = this._thread.subscribe(this.subscriptionHandler);
1966
+ this.subscriptionHandler();
1967
+ }
1968
+ get messages() {
1969
+ return this.thread.messages;
1970
+ }
1971
+ get isRunning() {
1972
+ return this.thread.isRunning;
1973
+ }
1974
+ getBranches(messageId) {
1975
+ return this.thread.getBranches(messageId);
1976
+ }
1977
+ switchToBranch(branchId) {
1978
+ return this.thread.switchToBranch(branchId);
1979
+ }
1980
+ append(message) {
1981
+ return this.thread.append(message);
1982
+ }
1983
+ startRun(parentId) {
1984
+ return this.thread.startRun(parentId);
1985
+ }
1986
+ cancelRun() {
1987
+ return this.thread.cancelRun();
1988
+ }
1989
+ addToolResult(toolCallId, result) {
1990
+ return this.thread.addToolResult(toolCallId, result);
1991
+ }
1992
+ _subscriptions = /* @__PURE__ */ new Set();
1993
+ subscribe(callback) {
1994
+ this._subscriptions.add(callback);
1995
+ return () => this._subscriptions.delete(callback);
1996
+ }
1997
+ subscriptionHandler = () => {
1998
+ for (const callback of this._subscriptions) callback();
1999
+ };
2000
+ get unstable_synchronizer() {
2001
+ return this.thread.unstable_synchronizer;
2002
+ }
2003
+ };
2004
+
1772
2005
  // src/runtime/local/LocalRuntime.tsx
1773
- var LocalRuntime = class {
2006
+ var LocalRuntime = class extends BaseAssistantRuntime {
2007
+ _configProviders;
1774
2008
  constructor(adapter) {
2009
+ const configProviders = /* @__PURE__ */ new Set();
2010
+ super(new LocalThreadRuntime(configProviders, adapter));
2011
+ this._configProviders = configProviders;
2012
+ }
2013
+ set adapter(adapter) {
2014
+ this.thread.adapter = adapter;
2015
+ }
2016
+ registerModelConfigProvider(provider) {
2017
+ this._configProviders.add(provider);
2018
+ return () => this._configProviders.delete(provider);
2019
+ }
2020
+ switchToThread(threadId) {
2021
+ if (threadId) {
2022
+ throw new Error("LocalRuntime does not yet support switching threads");
2023
+ }
2024
+ return this.thread = new LocalThreadRuntime(
2025
+ this._configProviders,
2026
+ this.thread.adapter
2027
+ );
2028
+ }
2029
+ };
2030
+ var LocalThreadRuntime = class {
2031
+ constructor(_configProviders, adapter) {
2032
+ this._configProviders = _configProviders;
1775
2033
  this.adapter = adapter;
1776
2034
  }
1777
2035
  _subscriptions = /* @__PURE__ */ new Set();
1778
- _configProviders = /* @__PURE__ */ new Set();
1779
2036
  abortController = null;
1780
2037
  repository = new MessageRepository();
1781
2038
  get messages() {
@@ -1854,12 +2111,8 @@ var LocalRuntime = class {
1854
2111
  this._subscriptions.add(callback);
1855
2112
  return () => this._subscriptions.delete(callback);
1856
2113
  }
1857
- registerModelConfigProvider(provider) {
1858
- this._configProviders.add(provider);
1859
- return () => this._configProviders.delete(provider);
1860
- }
1861
2114
  addToolResult() {
1862
- throw new Error("LocalRuntime does not yet support tool results");
2115
+ throw new Error("LocalRuntime does not yet support adding tool results");
1863
2116
  }
1864
2117
  };
1865
2118
 
@@ -1872,78 +2125,10 @@ var useLocalRuntime = (adapter) => {
1872
2125
  return runtime;
1873
2126
  };
1874
2127
 
1875
- // src/model-config/useAssistantTool.tsx
1876
- import { useEffect as useEffect8 } from "react";
1877
- var useAssistantTool = (tool) => {
1878
- const { useModelConfig, useToolUIs } = useAssistantContext();
1879
- const registerModelConfigProvider = useModelConfig(
1880
- (s) => s.registerModelConfigProvider
1881
- );
1882
- const setToolUI = useToolUIs((s) => s.setToolUI);
1883
- useEffect8(() => {
1884
- const { toolName, render, ...rest } = tool;
1885
- const config = {
1886
- tools: {
1887
- [tool.toolName]: rest
1888
- }
1889
- };
1890
- const unsub1 = registerModelConfigProvider(() => config);
1891
- const unsub2 = render ? setToolUI(toolName, render) : void 0;
1892
- return () => {
1893
- unsub1();
1894
- unsub2?.();
1895
- };
1896
- }, [registerModelConfigProvider, setToolUI, tool]);
1897
- };
1898
-
1899
- // src/model-config/makeAssistantTool.tsx
1900
- var makeAssistantTool = (tool) => {
1901
- const Tool = () => {
1902
- useAssistantTool(tool);
1903
- return null;
1904
- };
1905
- return Tool;
1906
- };
1907
-
1908
- // src/model-config/useAssistantToolUI.tsx
1909
- import { useEffect as useEffect9 } from "react";
1910
- var useAssistantToolUI = (tool) => {
1911
- const { useToolUIs } = useAssistantContext();
1912
- const setToolUI = useToolUIs((s) => s.setToolUI);
1913
- useEffect9(() => {
1914
- if (!tool) return;
1915
- const { toolName, render } = tool;
1916
- return setToolUI(toolName, render);
1917
- }, [setToolUI, tool]);
1918
- };
1919
-
1920
- // src/model-config/makeAssistantToolUI.tsx
1921
- var makeAssistantToolUI = (tool) => {
1922
- const ToolUI = () => {
1923
- useAssistantToolUI(tool);
1924
- return null;
1925
- };
1926
- return ToolUI;
1927
- };
1928
-
1929
- // src/model-config/useAssistantInstructions.tsx
1930
- import { useEffect as useEffect10 } from "react";
1931
- var useAssistantInstructions = (instruction) => {
1932
- const { useModelConfig } = useAssistantContext();
1933
- const registerModelConfigProvider = useModelConfig(
1934
- (s) => s.registerModelConfigProvider
1935
- );
1936
- useEffect10(() => {
1937
- const config = {
1938
- system: instruction
1939
- };
1940
- return registerModelConfigProvider(() => config);
1941
- }, [registerModelConfigProvider, instruction]);
1942
- };
1943
-
1944
2128
  // src/internal.ts
1945
2129
  var internal_exports = {};
1946
2130
  __export(internal_exports, {
2131
+ BaseAssistantRuntime: () => BaseAssistantRuntime,
1947
2132
  MessageRepository: () => MessageRepository,
1948
2133
  ProxyConfigProvider: () => ProxyConfigProvider
1949
2134
  });
@@ -1962,6 +2147,7 @@ export {
1962
2147
  useActionBarCopy,
1963
2148
  useActionBarEdit,
1964
2149
  useActionBarReload,
2150
+ useAppendMessage,
1965
2151
  useAssistantContext,
1966
2152
  useAssistantInstructions,
1967
2153
  useAssistantTool,
@@ -1977,11 +2163,11 @@ export {
1977
2163
  useContentPartContext,
1978
2164
  useContentPartDisplay,
1979
2165
  useContentPartImage,
1980
- useContentPartInProgressIndicator,
1981
2166
  useContentPartText,
1982
2167
  useLocalRuntime,
1983
2168
  useMessageContext,
1984
2169
  useMessageIf,
2170
+ useSwitchToNewThread,
1985
2171
  useThreadContext,
1986
2172
  useThreadEmpty,
1987
2173
  useThreadIf,