@assistant-ui/react 0.2.0 → 0.2.3

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