@assistant-ui/react 0.5.52 → 0.5.55

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
@@ -10,7 +10,7 @@ import {
10
10
  toLanguageModelMessages,
11
11
  toLanguageModelTools,
12
12
  toolResultStream
13
- } from "./chunk-ZQNZLTZL.mjs";
13
+ } from "./chunk-33TPUWEZ.mjs";
14
14
  import {
15
15
  __export
16
16
  } from "./chunk-BJPOCE4O.mjs";
@@ -22,52 +22,72 @@ import { memo } from "react";
22
22
  import { useEffect as useEffect4, useInsertionEffect as useInsertionEffect3, useRef as useRef2, useState as useState8 } from "react";
23
23
 
24
24
  // src/context/react/AssistantContext.ts
25
- import { createContext, useContext } from "react";
26
- var AssistantContext = createContext(
27
- null
28
- );
29
- function useAssistantContext(options) {
30
- const context = useContext(AssistantContext);
31
- if (!options?.optional && !context)
32
- throw new Error(
33
- "This component must be used within an AssistantRuntimeProvider."
34
- );
35
- return context;
25
+ import { createContext } from "react";
26
+
27
+ // src/context/react/utils/createContextHook.ts
28
+ import { useContext } from "react";
29
+ function createContextHook(context, providerName) {
30
+ function useContextHook(options) {
31
+ const contextValue = useContext(context);
32
+ if (!options?.optional && !contextValue) {
33
+ throw new Error(`This component must be used within ${providerName}.`);
34
+ }
35
+ return contextValue;
36
+ }
37
+ return useContextHook;
36
38
  }
37
39
 
38
- // src/context/stores/AssistantModelConfig.ts
39
- import { create } from "zustand";
40
-
41
- // src/utils/ProxyConfigProvider.ts
42
- var ProxyConfigProvider = class {
43
- _providers = /* @__PURE__ */ new Set();
44
- getModelConfig() {
45
- return mergeModelConfigs(this._providers);
40
+ // src/context/react/utils/createContextStoreHook.ts
41
+ function createContextStoreHook(contextHook, contextKey) {
42
+ function useStoreStoreHook(options) {
43
+ const context = contextHook(options);
44
+ if (!context) {
45
+ if (!options?.optional) {
46
+ throw new Error(`This component must be used within a ${contextKey}.`);
47
+ }
48
+ return null;
49
+ }
50
+ return context[contextKey];
46
51
  }
47
- registerModelConfigProvider(provider) {
48
- this._providers.add(provider);
49
- return () => {
50
- this._providers.delete(provider);
51
- };
52
+ function useStoreHook(param) {
53
+ let optional = false;
54
+ let selector;
55
+ if (typeof param === "function") {
56
+ selector = param;
57
+ } else if (param && typeof param === "object") {
58
+ optional = !!param.optional;
59
+ selector = param.selector;
60
+ }
61
+ const store = useStoreStoreHook({
62
+ optional
63
+ });
64
+ if (!store) return null;
65
+ return selector ? store(selector) : store();
52
66
  }
53
- };
67
+ return {
68
+ [contextKey]: useStoreHook,
69
+ [`${contextKey}Store`]: useStoreStoreHook
70
+ };
71
+ }
54
72
 
55
- // src/context/stores/AssistantModelConfig.ts
56
- var makeAssistantModelConfigStore = () => create(() => {
57
- const proxy = new ProxyConfigProvider();
58
- return Object.freeze({
59
- getModelConfig: () => {
60
- return proxy.getModelConfig();
61
- },
62
- registerModelConfigProvider: (provider) => {
63
- return proxy.registerModelConfigProvider(provider);
64
- }
65
- });
66
- });
73
+ // src/context/react/AssistantContext.ts
74
+ var AssistantContext = createContext(
75
+ null
76
+ );
77
+ var useAssistantContext = createContextHook(
78
+ AssistantContext,
79
+ "AssistantRuntimeProvider"
80
+ );
81
+ var { useAssistantRuntime, useAssistantRuntimeStore } = createContextStoreHook(useAssistantContext, "useAssistantRuntime");
82
+ var { useToolUIs, useToolUIsStore } = createContextStoreHook(
83
+ useAssistantContext,
84
+ "useToolUIs"
85
+ );
86
+ var { useAssistantActions, useAssistantActionsStore } = createContextStoreHook(useAssistantContext, "useAssistantActions");
67
87
 
68
88
  // src/context/stores/AssistantToolUIs.ts
69
- import { create as create2 } from "zustand";
70
- var makeAssistantToolUIsStore = () => create2((set) => {
89
+ import { create } from "zustand";
90
+ var makeAssistantToolUIsStore = () => create((set) => {
71
91
  const renderers = /* @__PURE__ */ new Map();
72
92
  return Object.freeze({
73
93
  getToolUI: (name) => {
@@ -101,24 +121,36 @@ var makeAssistantToolUIsStore = () => create2((set) => {
101
121
  import { useEffect as useEffect3, useInsertionEffect as useInsertionEffect2, useState as useState7 } from "react";
102
122
 
103
123
  // src/context/react/ThreadContext.ts
104
- import { createContext as createContext2, useContext as useContext2 } from "react";
124
+ import { createContext as createContext2 } from "react";
105
125
  var ThreadContext = createContext2(null);
106
- function useThreadContext(options) {
107
- const context = useContext2(ThreadContext);
108
- if (!options?.optional && !context)
109
- throw new Error(
110
- "This component must be used within an AssistantRuntimeProvider."
111
- );
112
- return context;
113
- }
114
-
115
- // src/context/stores/Composer.ts
116
- import { create as create3 } from "zustand";
117
- var makeComposerStore = (useThreadRuntime) => {
126
+ var useThreadContext = createContextHook(
127
+ ThreadContext,
128
+ "AssistantRuntimeProvider"
129
+ );
130
+ var { useThreadRuntime, useThreadRuntimeStore } = createContextStoreHook(useThreadContext, "useThreadRuntime");
131
+ var { useThread, useThreadStore } = createContextStoreHook(
132
+ useThreadContext,
133
+ "useThread"
134
+ );
135
+ var { useThreadMessages, useThreadMessagesStore } = createContextStoreHook(useThreadContext, "useThreadMessages");
136
+ var { useThreadActions, useThreadActionsStore } = createContextStoreHook(useThreadContext, "useThreadActions");
137
+ var {
138
+ useComposer: useThreadComposer,
139
+ useComposerStore: useThreadComposerStore
140
+ } = createContextStoreHook(useThreadContext, "useComposer");
141
+ var {
142
+ useViewport: useThreadViewport,
143
+ useViewportStore: useThreadViewportStore
144
+ } = createContextStoreHook(useThreadContext, "useViewport");
145
+
146
+ // src/context/stores/ThreadComposer.ts
147
+ import { create as create2 } from "zustand";
148
+ var makeThreadComposerStore = (useThreadRuntime2) => {
118
149
  const focusListeners = /* @__PURE__ */ new Set();
119
- return create3()((_, get) => {
120
- const runtime = useThreadRuntime.getState();
150
+ return create2()((_, get) => {
151
+ const runtime = useThreadRuntime2.getState();
121
152
  return {
153
+ type: "thread",
122
154
  get value() {
123
155
  return get().text;
124
156
  },
@@ -127,27 +159,27 @@ var makeComposerStore = (useThreadRuntime) => {
127
159
  },
128
160
  attachments: runtime.composer.attachments,
129
161
  addAttachment: (file) => {
130
- useThreadRuntime.getState().composer.addAttachment(file);
162
+ useThreadRuntime2.getState().composer.addAttachment(file);
131
163
  },
132
164
  removeAttachment: (attachmentId) => {
133
- useThreadRuntime.getState().composer.removeAttachment(attachmentId);
165
+ useThreadRuntime2.getState().composer.removeAttachment(attachmentId);
134
166
  },
135
167
  reset: () => {
136
- useThreadRuntime.getState().composer.reset();
168
+ useThreadRuntime2.getState().composer.reset();
137
169
  },
138
170
  text: runtime.composer.text,
139
171
  setText: (text) => {
140
- useThreadRuntime.getState().composer.setText(text);
172
+ useThreadRuntime2.getState().composer.setText(text);
141
173
  },
142
174
  canCancel: runtime.capabilities.cancel,
143
175
  isEditing: true,
144
176
  isEmpty: runtime.composer.isEmpty,
145
177
  send: () => {
146
- const runtime2 = useThreadRuntime.getState();
178
+ const runtime2 = useThreadRuntime2.getState();
147
179
  runtime2.composer.send();
148
180
  },
149
181
  cancel: () => {
150
- useThreadRuntime.getState().cancelRun();
182
+ useThreadRuntime2.getState().cancelRun();
151
183
  },
152
184
  focus: () => {
153
185
  for (const listener of focusListeners) {
@@ -165,7 +197,7 @@ var makeComposerStore = (useThreadRuntime) => {
165
197
  };
166
198
 
167
199
  // src/context/stores/Thread.ts
168
- import { create as create4 } from "zustand";
200
+ import { create as create3 } from "zustand";
169
201
  var getThreadStateFromRuntime = (runtime) => {
170
202
  const lastMessage = runtime.messages.at(-1);
171
203
  return Object.freeze({
@@ -177,14 +209,14 @@ var getThreadStateFromRuntime = (runtime) => {
177
209
  };
178
210
  var makeThreadStore = (runtimeRef) => {
179
211
  const runtime = runtimeRef.getState();
180
- return create4(() => getThreadStateFromRuntime(runtime));
212
+ return create3(() => getThreadStateFromRuntime(runtime));
181
213
  };
182
214
 
183
215
  // src/context/stores/ThreadViewport.tsx
184
- import { create as create5 } from "zustand";
216
+ import { create as create4 } from "zustand";
185
217
  var makeThreadViewportStore = () => {
186
218
  const scrollToBottomListeners = /* @__PURE__ */ new Set();
187
- return create5(() => ({
219
+ return create4(() => ({
188
220
  isAtBottom: true,
189
221
  scrollToBottom: () => {
190
222
  for (const listener of scrollToBottomListeners) {
@@ -201,9 +233,9 @@ var makeThreadViewportStore = () => {
201
233
  };
202
234
 
203
235
  // src/context/stores/ThreadActions.ts
204
- import { create as create6 } from "zustand";
236
+ import { create as create5 } from "zustand";
205
237
  var makeThreadActionStore = (runtimeStore) => {
206
- return create6(
238
+ return create5(
207
239
  () => Object.freeze({
208
240
  getBranches: (messageId) => runtimeStore.getState().getBranches(messageId),
209
241
  switchToBranch: (branchId) => runtimeStore.getState().switchToBranch(branchId),
@@ -217,15 +249,15 @@ var makeThreadActionStore = (runtimeStore) => {
217
249
  };
218
250
 
219
251
  // src/context/stores/ThreadMessages.ts
220
- import { create as create7 } from "zustand";
252
+ import { create as create6 } from "zustand";
221
253
  var makeThreadMessagesStore = (runtimeRef) => {
222
- return create7(() => runtimeRef.getState().messages);
254
+ return create6(() => runtimeRef.getState().messages);
223
255
  };
224
256
 
225
257
  // src/context/stores/ThreadRuntime.tsx
226
- import { create as create8 } from "zustand";
258
+ import { create as create7 } from "zustand";
227
259
  var makeThreadRuntimeStore = (runtime) => {
228
- return create8(() => runtime);
260
+ return create7(() => runtime);
229
261
  };
230
262
 
231
263
  // src/runtimes/core/subscribeToMainThread.ts
@@ -358,6 +390,20 @@ var ThreadRuntimeComposer = class {
358
390
  }
359
391
  };
360
392
 
393
+ // src/utils/ProxyConfigProvider.ts
394
+ var ProxyConfigProvider = class {
395
+ _providers = /* @__PURE__ */ new Set();
396
+ getModelConfig() {
397
+ return mergeModelConfigs(this._providers);
398
+ }
399
+ registerModelConfigProvider(provider) {
400
+ this._providers.add(provider);
401
+ return () => {
402
+ this._providers.delete(provider);
403
+ };
404
+ }
405
+ };
406
+
361
407
  // src/utils/idUtils.tsx
362
408
  import { customAlphabet } from "nanoid/non-secure";
363
409
  var generateId = customAlphabet(
@@ -373,7 +419,8 @@ var fromCoreMessages = (message) => {
373
419
  };
374
420
  var fromCoreMessage = (message, {
375
421
  id = generateId(),
376
- status = { type: "complete", reason: "unknown" }
422
+ status = { type: "complete", reason: "unknown" },
423
+ attachments = []
377
424
  } = {}) => {
378
425
  const commonProps = {
379
426
  id,
@@ -401,7 +448,7 @@ var fromCoreMessage = (message, {
401
448
  ...commonProps,
402
449
  role,
403
450
  content: message.content,
404
- attachments: []
451
+ attachments
405
452
  };
406
453
  case "system":
407
454
  return {
@@ -608,26 +655,43 @@ var MessageRepository = class {
608
655
 
609
656
  // src/utils/smooth/useSmooth.tsx
610
657
  import { useEffect, useMemo, useRef, useState as useState2 } from "react";
658
+ import { useCallbackRef } from "@radix-ui/react-use-callback-ref";
611
659
 
612
660
  // src/utils/smooth/SmoothContext.tsx
613
661
  import {
614
- createContext as createContext3,
662
+ createContext as createContext4,
615
663
  forwardRef,
616
- useContext as useContext3,
664
+ useContext as useContext2,
617
665
  useState
618
666
  } from "react";
619
- import { create as create9 } from "zustand";
667
+ import { create as create8 } from "zustand";
668
+
669
+ // src/context/react/ContentPartContext.ts
670
+ import { createContext as createContext3 } from "react";
671
+ var ContentPartContext = createContext3(
672
+ null
673
+ );
674
+ var useContentPartContext = createContextHook(
675
+ ContentPartContext,
676
+ "a component passed to <MessagePrimitive.Content components={...}>"
677
+ );
678
+ var { useContentPart, useContentPartStore } = createContextStoreHook(
679
+ useContentPartContext,
680
+ "useContentPart"
681
+ );
682
+
683
+ // src/utils/smooth/SmoothContext.tsx
620
684
  import { jsx } from "react/jsx-runtime";
621
- var SmoothContext = createContext3(null);
685
+ var SmoothContext = createContext4(null);
622
686
  var makeSmoothContext = (initialState) => {
623
- const useSmoothStatus2 = create9(() => initialState);
687
+ const useSmoothStatus2 = create8(() => initialState);
624
688
  return { useSmoothStatus: useSmoothStatus2 };
625
689
  };
626
690
  var SmoothContextProvider = ({ children }) => {
627
691
  const outer = useSmoothContext({ optional: true });
628
- const { useContentPart } = useContentPartContext();
692
+ const contentPartStore = useContentPartStore();
629
693
  const [context] = useState(
630
- () => makeSmoothContext(useContentPart.getState().status)
694
+ () => makeSmoothContext(contentPartStore.getState().status)
631
695
  );
632
696
  if (outer) return children;
633
697
  return /* @__PURE__ */ jsx(SmoothContext.Provider, { value: context, children });
@@ -640,20 +704,24 @@ var withSmoothContextProvider = (Component) => {
640
704
  return Wrapped;
641
705
  };
642
706
  function useSmoothContext(options) {
643
- const context = useContext3(SmoothContext);
707
+ const context = useContext2(SmoothContext);
644
708
  if (!options?.optional && !context)
645
709
  throw new Error(
646
710
  "This component must be used within a SmoothContextProvider."
647
711
  );
648
712
  return context;
649
713
  }
650
- var useSmoothStatus = () => {
651
- const { useSmoothStatus: useSmoothStatus2 } = useSmoothContext();
652
- return useSmoothStatus2();
714
+ var { useSmoothStatus, useSmoothStatusStore } = createContextStoreHook(
715
+ useSmoothContext,
716
+ "useSmoothStatus"
717
+ );
718
+
719
+ // src/context/ReadonlyStore.ts
720
+ var writableStore = (store) => {
721
+ return store;
653
722
  };
654
723
 
655
724
  // src/utils/smooth/useSmooth.tsx
656
- import { useCallbackRef } from "@radix-ui/react-use-callback-ref";
657
725
  var TextStreamAnimator = class {
658
726
  constructor(currentText, setText) {
659
727
  this.currentText = currentText;
@@ -702,21 +770,28 @@ var SMOOTH_STATUS = Object.freeze({
702
770
  type: "running"
703
771
  });
704
772
  var useSmooth = (state, smooth = false) => {
705
- const { useSmoothStatus: useSmoothStatus2 } = useSmoothContext({ optional: true }) ?? {};
706
773
  const {
707
774
  part: { text }
708
775
  } = state;
709
- const { useMessage } = useMessageContext();
710
776
  const id = useMessage((m) => m.message.id);
711
777
  const idRef = useRef(id);
712
778
  const [displayedText, setDisplayedText] = useState2(text);
779
+ const smoothStatusStore = useSmoothStatusStore({ optional: true });
713
780
  const setText = useCallbackRef((text2) => {
714
781
  setDisplayedText(text2);
715
- useSmoothStatus2?.setState(text2 !== state.part.text ? SMOOTH_STATUS : state.status);
782
+ if (smoothStatusStore) {
783
+ writableStore(smoothStatusStore).setState(
784
+ text2 !== state.part.text ? SMOOTH_STATUS : state.status
785
+ );
786
+ }
716
787
  });
717
788
  useEffect(() => {
718
- useSmoothStatus2?.setState(text !== displayedText ? SMOOTH_STATUS : state.status);
719
- }, [useSmoothStatus2, text, displayedText, state.status]);
789
+ if (smoothStatusStore) {
790
+ writableStore(smoothStatusStore).setState(
791
+ text !== state.part.text ? SMOOTH_STATUS : state.status
792
+ );
793
+ }
794
+ }, [smoothStatusStore, text, displayedText, state.status, state.part.text]);
720
795
  const [animatorRef] = useState2(
721
796
  new TextStreamAnimator(text, setText)
722
797
  );
@@ -1218,20 +1293,16 @@ var LocalThreadRuntime = class {
1218
1293
  this.notifySubscribers();
1219
1294
  }
1220
1295
  async append(message) {
1221
- if (message.role !== "user")
1222
- throw new Error(
1223
- "Only appending user messages are supported in LocalRuntime. This is likely an internal bug in assistant-ui."
1224
- );
1225
- const userMessageId = generateId();
1226
- const userMessage = {
1227
- id: userMessageId,
1228
- role: "user",
1229
- content: message.content,
1230
- attachments: message.attachments ?? [],
1231
- createdAt: /* @__PURE__ */ new Date()
1232
- };
1233
- this.repository.addOrUpdateMessage(message.parentId, userMessage);
1234
- await this.startRun(userMessageId);
1296
+ const newMessage = fromCoreMessage(message, {
1297
+ attachments: message.attachments
1298
+ });
1299
+ this.repository.addOrUpdateMessage(message.parentId, newMessage);
1300
+ if (message.role === "user") {
1301
+ await this.startRun(newMessage.id);
1302
+ } else {
1303
+ this.repository.resetHead(newMessage.id);
1304
+ this.notifySubscribers();
1305
+ }
1235
1306
  }
1236
1307
  async startRun(parentId) {
1237
1308
  this.repository.resetHead(parentId);
@@ -1353,7 +1424,9 @@ var LocalThreadRuntime = class {
1353
1424
  toolCallId,
1354
1425
  result
1355
1426
  }) {
1356
- let { parentId, message } = this.repository.getMessage(messageId);
1427
+ const messageData = this.repository.getMessage(messageId);
1428
+ const { parentId } = messageData;
1429
+ let { message } = messageData;
1357
1430
  if (message.role !== "assistant")
1358
1431
  throw new Error("Tried to add tool result to non-assistant message");
1359
1432
  let added = false;
@@ -1424,10 +1497,7 @@ var LocalRuntime = class extends BaseAssistantRuntime {
1424
1497
  registerModelConfigProvider(provider) {
1425
1498
  return this._proxyConfigProvider.registerModelConfigProvider(provider);
1426
1499
  }
1427
- switchToThread(threadId) {
1428
- if (threadId) {
1429
- throw new Error("LocalRuntime does not yet support switching threads");
1430
- }
1500
+ switchToNewThread() {
1431
1501
  const { initialMessages, ...options } = this.thread.options;
1432
1502
  return this.thread = new LocalThreadRuntime(
1433
1503
  this._proxyConfigProvider,
@@ -1435,6 +1505,12 @@ var LocalRuntime = class extends BaseAssistantRuntime {
1435
1505
  options
1436
1506
  );
1437
1507
  }
1508
+ switchToThread(threadId) {
1509
+ if (threadId !== null) {
1510
+ throw new Error("LocalRuntime does not yet support switching threads");
1511
+ }
1512
+ this.switchToNewThread();
1513
+ }
1438
1514
  reset({
1439
1515
  initialMessages
1440
1516
  } = {}) {
@@ -1758,8 +1834,17 @@ var ExternalStoreRuntime = class extends BaseAssistantRuntime {
1758
1834
  registerModelConfigProvider(provider) {
1759
1835
  return this._proxyConfigProvider.registerModelConfigProvider(provider);
1760
1836
  }
1837
+ async switchToNewThread() {
1838
+ if (!this.store.onNewThread)
1839
+ throw new Error("Runtime does not support switching to new threads.");
1840
+ this.thread = new ExternalStoreThreadRuntime({
1841
+ messages: [],
1842
+ onNew: this.store.onNew
1843
+ });
1844
+ await this.store.onNewThread();
1845
+ }
1761
1846
  async switchToThread(threadId) {
1762
- if (threadId) {
1847
+ if (threadId !== null) {
1763
1848
  if (!this.store.onSwitchThread)
1764
1849
  throw new Error("Runtime does not support switching threads.");
1765
1850
  this.thread = new ExternalStoreThreadRuntime({
@@ -1768,13 +1853,7 @@ var ExternalStoreRuntime = class extends BaseAssistantRuntime {
1768
1853
  });
1769
1854
  this.store.onSwitchThread(threadId);
1770
1855
  } else {
1771
- if (!this.store.onNewThread)
1772
- throw new Error("Runtime does not support switching to new threads.");
1773
- this.thread = new ExternalStoreThreadRuntime({
1774
- messages: [],
1775
- onNew: this.store.onNew
1776
- });
1777
- await this.store.onNewThread();
1856
+ this.switchToNewThread();
1778
1857
  }
1779
1858
  }
1780
1859
  };
@@ -2149,11 +2228,6 @@ var CompositeAttachmentAdapter = class {
2149
2228
  }
2150
2229
  };
2151
2230
 
2152
- // src/context/ReadonlyStore.ts
2153
- var writableStore = (store) => {
2154
- return store;
2155
- };
2156
-
2157
2231
  // src/context/providers/ThreadProvider.tsx
2158
2232
  import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
2159
2233
  var ThreadProvider = ({
@@ -2161,18 +2235,18 @@ var ThreadProvider = ({
2161
2235
  provider
2162
2236
  }) => {
2163
2237
  const [context] = useState7(() => {
2164
- const useThreadRuntime = makeThreadRuntimeStore(provider.thread);
2165
- const useThread = makeThreadStore(useThreadRuntime);
2166
- const useThreadMessages = makeThreadMessagesStore(useThreadRuntime);
2167
- const useThreadActions = makeThreadActionStore(useThreadRuntime);
2238
+ const useThreadRuntime2 = makeThreadRuntimeStore(provider.thread);
2239
+ const useThread2 = makeThreadStore(useThreadRuntime2);
2240
+ const useThreadMessages2 = makeThreadMessagesStore(useThreadRuntime2);
2241
+ const useThreadActions2 = makeThreadActionStore(useThreadRuntime2);
2168
2242
  const useViewport = makeThreadViewportStore();
2169
- const useComposer = makeComposerStore(useThreadRuntime);
2243
+ const useComposer2 = makeThreadComposerStore(useThreadRuntime2);
2170
2244
  return {
2171
- useThread,
2172
- useThreadRuntime,
2173
- useThreadMessages,
2174
- useThreadActions,
2175
- useComposer,
2245
+ useThread: useThread2,
2246
+ useThreadRuntime: useThreadRuntime2,
2247
+ useThreadMessages: useThreadMessages2,
2248
+ useThreadActions: useThreadActions2,
2249
+ useComposer: useComposer2,
2176
2250
  useViewport
2177
2251
  };
2178
2252
  });
@@ -2220,18 +2294,19 @@ var ThreadProvider = ({
2220
2294
  };
2221
2295
 
2222
2296
  // src/context/stores/AssistantActions.tsx
2223
- import { create as create10 } from "zustand";
2224
- var makeAssistantActionsStore = (runtimeRef) => create10(
2297
+ import { create as create9 } from "zustand";
2298
+ var makeAssistantActionsStore = (runtimeRef) => create9(
2225
2299
  () => Object.freeze({
2226
2300
  switchToThread: () => runtimeRef.current.switchToThread(null),
2301
+ registerModelConfigProvider: (provider) => runtimeRef.current.registerModelConfigProvider(provider),
2227
2302
  getRuntime: () => runtimeRef.current
2228
2303
  })
2229
2304
  );
2230
2305
 
2231
2306
  // src/context/stores/AssistantRuntime.tsx
2232
- import { create as create11 } from "zustand";
2307
+ import { create as create10 } from "zustand";
2233
2308
  var makeAssistantRuntimeStore = (runtime) => {
2234
- return create11(() => runtime);
2309
+ return create10(() => runtime);
2235
2310
  };
2236
2311
 
2237
2312
  // src/context/providers/AssistantProvider.tsx
@@ -2242,21 +2317,15 @@ var AssistantProvider = ({ children, runtime }) => {
2242
2317
  runtimeRef.current = runtime;
2243
2318
  });
2244
2319
  const [context] = useState8(() => {
2245
- const useAssistantRuntime = makeAssistantRuntimeStore(runtime);
2246
- const useModelConfig = makeAssistantModelConfigStore();
2247
- const useToolUIs = makeAssistantToolUIsStore();
2248
- const useAssistantActions = makeAssistantActionsStore(runtimeRef);
2320
+ const useAssistantRuntime2 = makeAssistantRuntimeStore(runtime);
2321
+ const useToolUIs2 = makeAssistantToolUIsStore();
2322
+ const useAssistantActions2 = makeAssistantActionsStore(runtimeRef);
2249
2323
  return {
2250
- useModelConfig,
2251
- useToolUIs,
2252
- useAssistantRuntime,
2253
- useAssistantActions
2324
+ useToolUIs: useToolUIs2,
2325
+ useAssistantRuntime: useAssistantRuntime2,
2326
+ useAssistantActions: useAssistantActions2
2254
2327
  };
2255
2328
  });
2256
- const getModelConfig = context.useModelConfig();
2257
- useEffect4(() => {
2258
- return runtime.registerModelConfigProvider(getModelConfig);
2259
- }, [runtime, getModelConfig]);
2260
2329
  useEffect4(
2261
2330
  () => writableStore(context.useAssistantRuntime).setState(runtime, true),
2262
2331
  [runtime, context]
@@ -2273,93 +2342,95 @@ var AssistantRuntimeProvider = memo(AssistantRuntimeProviderImpl);
2273
2342
 
2274
2343
  // src/context/providers/TextContentPartProvider.tsx
2275
2344
  import { useState as useState9 } from "react";
2276
- import { create as create12 } from "zustand";
2277
-
2278
- // src/context/react/ContentPartContext.ts
2279
- import { createContext as createContext4, useContext as useContext4 } from "react";
2280
- var ContentPartContext = createContext4(
2281
- null
2282
- );
2283
- function useContentPartContext(options) {
2284
- const context = useContext4(ContentPartContext);
2285
- if (!options?.optional && !context)
2286
- throw new Error(
2287
- "This component can only be used inside a component passed to <MessagePrimitive.Content components={...} >."
2288
- );
2289
- return context;
2290
- }
2291
-
2292
- // src/context/providers/TextContentPartProvider.tsx
2345
+ import { create as create11 } from "zustand";
2293
2346
  import { jsx as jsx9 } from "react/jsx-runtime";
2294
2347
  var TextContentPartProvider = ({ children, text }) => {
2295
2348
  const [context] = useState9(() => {
2296
- const useContentPart = create12(() => ({
2349
+ const useContentPart2 = create11(() => ({
2297
2350
  status: { type: "complete" },
2298
2351
  part: { type: "text", text }
2299
2352
  }));
2300
2353
  return {
2301
- useContentPart
2354
+ useContentPart: useContentPart2
2302
2355
  };
2303
2356
  });
2304
2357
  return /* @__PURE__ */ jsx9(ContentPartContext.Provider, { value: context, children });
2305
2358
  };
2306
2359
 
2307
- // src/context/react/ComposerContext.ts
2308
- import { useMemo as useMemo3 } from "react";
2309
-
2310
2360
  // src/context/react/MessageContext.ts
2311
- import { createContext as createContext5, useContext as useContext5 } from "react";
2361
+ import { createContext as createContext5 } from "react";
2312
2362
  var MessageContext = createContext5(null);
2313
- function useMessageContext(options) {
2314
- const context = useContext5(MessageContext);
2315
- if (!options?.optional && !context)
2316
- throw new Error(
2317
- "This component can only be used inside a component passed to <ThreadPrimitive.Messages components={...} />."
2318
- );
2319
- return context;
2320
- }
2363
+ var useMessageContext = createContextHook(
2364
+ MessageContext,
2365
+ "a component passed to <ThreadPrimitive.Messages components={...} />"
2366
+ );
2367
+ var { useMessage, useMessageStore } = createContextStoreHook(
2368
+ useMessageContext,
2369
+ "useMessage"
2370
+ );
2371
+ var { useMessageUtils, useMessageUtilsStore } = createContextStoreHook(
2372
+ useMessageContext,
2373
+ "useMessageUtils"
2374
+ );
2375
+ var { useEditComposer, useEditComposerStore } = createContextStoreHook(
2376
+ useMessageContext,
2377
+ "useEditComposer"
2378
+ );
2321
2379
 
2322
2380
  // src/context/react/ComposerContext.ts
2381
+ import { useMemo as useMemo3 } from "react";
2323
2382
  var useComposerContext = () => {
2324
- const { useComposer } = useThreadContext();
2325
- const { useEditComposer } = useMessageContext({ optional: true }) ?? {};
2383
+ const { useComposer: useComposer2 } = useThreadContext();
2384
+ const { useEditComposer: useEditComposer2 } = useMessageContext({ optional: true }) ?? {};
2326
2385
  return useMemo3(
2327
2386
  () => ({
2328
- useComposer: useEditComposer ?? useComposer,
2329
- type: useEditComposer ? "edit" : "new"
2387
+ useComposer: useEditComposer2 ?? useComposer2,
2388
+ type: useEditComposer2 ? "edit" : "new"
2330
2389
  }),
2331
- [useEditComposer, useComposer]
2390
+ [useEditComposer2, useComposer2]
2332
2391
  );
2333
2392
  };
2393
+ var { useComposer, useComposerStore } = createContextStoreHook(
2394
+ useComposerContext,
2395
+ "useComposer"
2396
+ );
2334
2397
 
2335
2398
  // src/hooks/useAppendMessage.tsx
2336
2399
  import { useCallback } from "react";
2337
- var toAppendMessage = (useThreadMessages, message) => {
2400
+ var toAppendMessage = (useThreadMessages2, message) => {
2338
2401
  if (typeof message === "string") {
2339
2402
  return {
2340
- parentId: useThreadMessages.getState().at(-1)?.id ?? null,
2403
+ parentId: useThreadMessages2.getState().at(-1)?.id ?? null,
2341
2404
  role: "user",
2342
2405
  content: [{ type: "text", text: message }],
2343
2406
  attachments: []
2344
2407
  };
2345
2408
  }
2346
2409
  return {
2347
- parentId: message.parentId ?? useThreadMessages.getState().at(-1)?.id ?? null,
2410
+ parentId: message.parentId ?? useThreadMessages2.getState().at(-1)?.id ?? null,
2348
2411
  role: message.role ?? "user",
2349
2412
  content: message.content,
2350
2413
  attachments: message.attachments ?? []
2351
2414
  };
2352
2415
  };
2353
2416
  var useAppendMessage = () => {
2354
- const { useThreadMessages, useThreadActions, useViewport, useComposer } = useThreadContext();
2417
+ const threadMessagesStore = useThreadMessagesStore();
2418
+ const threadActionsStore = useThreadActionsStore();
2419
+ const threadViewportStore = useThreadViewportStore();
2420
+ const threadComposerStore = useThreadComposerStore();
2355
2421
  const append = useCallback(
2356
2422
  (message) => {
2357
- const appendMessage = toAppendMessage(useThreadMessages, message);
2358
- useThreadActions.getState().append(appendMessage);
2359
- useViewport.getState().scrollToBottom();
2360
- useComposer.getState().focus();
2423
+ const appendMessage = toAppendMessage(threadMessagesStore, message);
2424
+ threadActionsStore.getState().append(appendMessage);
2425
+ threadViewportStore.getState().scrollToBottom();
2426
+ threadComposerStore.getState().focus();
2361
2427
  },
2362
- [useThreadMessages, useThreadActions, useViewport, useComposer]
2428
+ [
2429
+ threadMessagesStore,
2430
+ threadActionsStore,
2431
+ threadViewportStore,
2432
+ threadComposerStore
2433
+ ]
2363
2434
  );
2364
2435
  return append;
2365
2436
  };
@@ -2367,23 +2438,20 @@ var useAppendMessage = () => {
2367
2438
  // src/hooks/useSwitchToNewThread.tsx
2368
2439
  import { useCallback as useCallback2 } from "react";
2369
2440
  var useSwitchToNewThread = () => {
2370
- const { useAssistantActions } = useAssistantContext();
2371
- const { useComposer } = useThreadContext();
2441
+ const assistantActionsStore = useAssistantActionsStore();
2442
+ const threadComposerStore = useThreadComposerStore();
2372
2443
  const switchToNewThread = useCallback2(() => {
2373
- useAssistantActions.getState().switchToThread(null);
2374
- useComposer.getState().focus();
2375
- }, [useAssistantActions, useComposer]);
2444
+ assistantActionsStore.getState().switchToThread(null);
2445
+ threadComposerStore.getState().focus();
2446
+ }, [assistantActionsStore, threadComposerStore]);
2376
2447
  return switchToNewThread;
2377
2448
  };
2378
2449
 
2379
2450
  // src/model-config/useAssistantTool.tsx
2380
2451
  import { useEffect as useEffect5 } from "react";
2381
2452
  var useAssistantTool = (tool) => {
2382
- const { useModelConfig, useToolUIs } = useAssistantContext();
2383
- const registerModelConfigProvider = useModelConfig(
2384
- (s) => s.registerModelConfigProvider
2385
- );
2386
- const setToolUI = useToolUIs((s) => s.setToolUI);
2453
+ const assistantActionsStore = useAssistantActionsStore();
2454
+ const toolUIsStore = useToolUIsStore();
2387
2455
  useEffect5(() => {
2388
2456
  const { toolName, render, ...rest } = tool;
2389
2457
  const config = {
@@ -2391,15 +2459,15 @@ var useAssistantTool = (tool) => {
2391
2459
  [tool.toolName]: rest
2392
2460
  }
2393
2461
  };
2394
- const unsub1 = registerModelConfigProvider({
2462
+ const unsub1 = assistantActionsStore.getState().registerModelConfigProvider({
2395
2463
  getModelConfig: () => config
2396
2464
  });
2397
- const unsub2 = render ? setToolUI(toolName, render) : void 0;
2465
+ const unsub2 = render ? toolUIsStore.getState().setToolUI(toolName, render) : void 0;
2398
2466
  return () => {
2399
2467
  unsub1();
2400
2468
  unsub2?.();
2401
2469
  };
2402
- }, [registerModelConfigProvider, setToolUI, tool]);
2470
+ }, [assistantActionsStore, toolUIsStore, tool]);
2403
2471
  };
2404
2472
 
2405
2473
  // src/model-config/makeAssistantTool.tsx
@@ -2415,13 +2483,12 @@ var makeAssistantTool = (tool) => {
2415
2483
  // src/model-config/useAssistantToolUI.tsx
2416
2484
  import { useEffect as useEffect6 } from "react";
2417
2485
  var useAssistantToolUI = (tool) => {
2418
- const { useToolUIs } = useAssistantContext();
2419
- const setToolUI = useToolUIs((s) => s.setToolUI);
2486
+ const toolUIsStore = useToolUIsStore();
2420
2487
  useEffect6(() => {
2421
2488
  if (!tool) return;
2422
2489
  const { toolName, render } = tool;
2423
- return setToolUI(toolName, render);
2424
- }, [setToolUI, tool]);
2490
+ return toolUIsStore.getState().setToolUI(toolName, render);
2491
+ }, [toolUIsStore, tool]);
2425
2492
  };
2426
2493
 
2427
2494
  // src/model-config/makeAssistantToolUI.tsx
@@ -2437,16 +2504,13 @@ var makeAssistantToolUI = (tool) => {
2437
2504
  // src/model-config/useAssistantInstructions.tsx
2438
2505
  import { useEffect as useEffect7 } from "react";
2439
2506
  var useAssistantInstructions = (instruction) => {
2440
- const { useModelConfig } = useAssistantContext();
2441
- const registerModelConfigProvider = useModelConfig(
2442
- (s) => s.registerModelConfigProvider
2443
- );
2507
+ const runtimeStore = useAssistantRuntimeStore();
2444
2508
  useEffect7(() => {
2445
2509
  const config = {
2446
2510
  system: instruction
2447
2511
  };
2448
- return registerModelConfigProvider({ getModelConfig: () => config });
2449
- }, [registerModelConfigProvider, instruction]);
2512
+ return runtimeStore.getState().registerModelConfigProvider({ getModelConfig: () => config });
2513
+ }, [runtimeStore, instruction]);
2450
2514
  };
2451
2515
 
2452
2516
  // src/primitive-hooks/actionBar/useActionBarCopy.tsx
@@ -2482,23 +2546,25 @@ var useCombinedStore = (stores, selector) => {
2482
2546
  var useActionBarCopy = ({
2483
2547
  copiedDuration = 3e3
2484
2548
  } = {}) => {
2485
- const { useMessage, useMessageUtils, useEditComposer } = useMessageContext();
2549
+ const messageStore = useMessageStore();
2550
+ const messageUtilsStore = useMessageUtilsStore();
2551
+ const editComposerStore = useEditComposerStore();
2486
2552
  const hasCopyableContent = useCombinedStore(
2487
- [useMessage, useEditComposer],
2553
+ [messageStore, editComposerStore],
2488
2554
  ({ message }, c) => {
2489
2555
  return !c.isEditing && (message.role !== "assistant" || message.status.type !== "running") && message.content.some((c2) => c2.type === "text" && c2.text.length > 0);
2490
2556
  }
2491
2557
  );
2492
2558
  const callback = useCallback3(() => {
2493
- const { message } = useMessage.getState();
2494
- const { setIsCopied } = useMessageUtils.getState();
2495
- const { isEditing, text: composerValue } = useEditComposer.getState();
2559
+ const { message } = messageStore.getState();
2560
+ const { setIsCopied } = messageUtilsStore.getState();
2561
+ const { isEditing, text: composerValue } = editComposerStore.getState();
2496
2562
  const valueToCopy = isEditing ? composerValue : getThreadMessageText(message);
2497
2563
  navigator.clipboard.writeText(valueToCopy).then(() => {
2498
2564
  setIsCopied(true);
2499
2565
  setTimeout(() => setIsCopied(false), copiedDuration);
2500
2566
  });
2501
- }, [useMessage, useMessageUtils, useEditComposer, copiedDuration]);
2567
+ }, [messageStore, messageUtilsStore, editComposerStore, copiedDuration]);
2502
2568
  if (!hasCopyableContent) return null;
2503
2569
  return callback;
2504
2570
  };
@@ -2506,15 +2572,12 @@ var useActionBarCopy = ({
2506
2572
  // src/primitive-hooks/actionBar/useActionBarEdit.tsx
2507
2573
  import { useCallback as useCallback4 } from "react";
2508
2574
  var useActionBarEdit = () => {
2509
- const { useMessage, useEditComposer } = useMessageContext();
2510
- const disabled = useCombinedStore(
2511
- [useMessage, useEditComposer],
2512
- (m, c) => m.message.role !== "user" || c.isEditing
2513
- );
2575
+ const editComposerStore = useEditComposerStore();
2576
+ const disabled = useEditComposer((c) => c.isEditing);
2514
2577
  const callback = useCallback4(() => {
2515
- const { edit } = useEditComposer.getState();
2578
+ const { edit } = editComposerStore.getState();
2516
2579
  edit();
2517
- }, [useEditComposer]);
2580
+ }, [editComposerStore]);
2518
2581
  if (disabled) return null;
2519
2582
  return callback;
2520
2583
  };
@@ -2522,18 +2585,26 @@ var useActionBarEdit = () => {
2522
2585
  // src/primitive-hooks/actionBar/useActionBarReload.tsx
2523
2586
  import { useCallback as useCallback5 } from "react";
2524
2587
  var useActionBarReload = () => {
2525
- const { useThread, useThreadActions, useComposer, useViewport } = useThreadContext();
2526
- const { useMessage } = useMessageContext();
2588
+ const messageStore = useMessageStore();
2589
+ const threadStore = useThreadStore();
2590
+ const threadActionsStore = useThreadActionsStore();
2591
+ const threadComposerStore = useThreadComposerStore();
2592
+ const threadViewportStore = useThreadViewportStore();
2527
2593
  const disabled = useCombinedStore(
2528
- [useThread, useMessage],
2594
+ [threadStore, messageStore],
2529
2595
  (t, m) => t.isRunning || t.isDisabled || m.message.role !== "assistant"
2530
2596
  );
2531
2597
  const callback = useCallback5(() => {
2532
- const { parentId } = useMessage.getState();
2533
- useThreadActions.getState().startRun(parentId);
2534
- useViewport.getState().scrollToBottom();
2535
- useComposer.getState().focus();
2536
- }, [useThreadActions, useComposer, useViewport, useMessage]);
2598
+ const { parentId } = messageStore.getState();
2599
+ threadActionsStore.getState().startRun(parentId);
2600
+ threadViewportStore.getState().scrollToBottom();
2601
+ threadComposerStore.getState().focus();
2602
+ }, [
2603
+ threadActionsStore,
2604
+ threadComposerStore,
2605
+ threadViewportStore,
2606
+ messageStore
2607
+ ]);
2537
2608
  if (disabled) return null;
2538
2609
  return callback;
2539
2610
  };
@@ -2541,19 +2612,21 @@ var useActionBarReload = () => {
2541
2612
  // src/primitive-hooks/actionBar/useActionBarSpeak.tsx
2542
2613
  import { useCallback as useCallback6 } from "react";
2543
2614
  var useActionBarSpeak = () => {
2544
- const { useThreadActions } = useThreadContext();
2545
- const { useMessage, useEditComposer, useMessageUtils } = useMessageContext();
2615
+ const messageStore = useMessageStore();
2616
+ const editComposerStore = useEditComposerStore();
2617
+ const threadActionsStore = useThreadActionsStore();
2618
+ const messageUtilsStore = useMessageUtilsStore();
2546
2619
  const hasSpeakableContent = useCombinedStore(
2547
- [useMessage, useEditComposer],
2620
+ [messageStore, editComposerStore],
2548
2621
  ({ message }, c) => {
2549
2622
  return !c.isEditing && (message.role !== "assistant" || message.status.type !== "running") && message.content.some((c2) => c2.type === "text" && c2.text.length > 0);
2550
2623
  }
2551
2624
  );
2552
2625
  const callback = useCallback6(async () => {
2553
- const { message } = useMessage.getState();
2554
- const utt = useThreadActions.getState().speak(message.id);
2555
- useMessageUtils.getState().addUtterance(utt);
2556
- }, [useThreadActions, useMessage, useMessageUtils]);
2626
+ const { message } = messageStore.getState();
2627
+ const utt = threadActionsStore.getState().speak(message.id);
2628
+ messageUtilsStore.getState().addUtterance(utt);
2629
+ }, [threadActionsStore, messageStore, messageUtilsStore]);
2557
2630
  if (!hasSpeakableContent) return null;
2558
2631
  return callback;
2559
2632
  };
@@ -2561,18 +2634,17 @@ var useActionBarSpeak = () => {
2561
2634
  // src/primitive-hooks/actionBar/useActionBarStopSpeaking.tsx
2562
2635
  import { useCallback as useCallback7 } from "react";
2563
2636
  var useActionBarStopSpeaking = () => {
2564
- const { useMessageUtils } = useMessageContext();
2637
+ const messageUtilsStore = useMessageUtilsStore();
2565
2638
  const isSpeaking = useMessageUtils((u) => u.isSpeaking);
2566
2639
  const callback = useCallback7(async () => {
2567
- useMessageUtils.getState().stopSpeaking();
2568
- }, [useMessageUtils]);
2640
+ messageUtilsStore.getState().stopSpeaking();
2641
+ }, [messageUtilsStore]);
2569
2642
  if (!isSpeaking) return null;
2570
2643
  return callback;
2571
2644
  };
2572
2645
 
2573
2646
  // src/primitive-hooks/branchPicker/useBranchPickerCount.tsx
2574
2647
  var useBranchPickerCount = () => {
2575
- const { useMessage } = useMessageContext();
2576
2648
  const branchCount = useMessage((s) => s.branches.length);
2577
2649
  return branchCount;
2578
2650
  };
@@ -2580,23 +2652,23 @@ var useBranchPickerCount = () => {
2580
2652
  // src/primitive-hooks/branchPicker/useBranchPickerNext.tsx
2581
2653
  import { useCallback as useCallback8 } from "react";
2582
2654
  var useBranchPickerNext = () => {
2583
- const { useThreadActions } = useThreadContext();
2584
- const { useMessage, useEditComposer } = useMessageContext();
2655
+ const messageStore = useMessageStore();
2656
+ const editComposerStore = useEditComposerStore();
2657
+ const threadActionsStore = useThreadActionsStore();
2585
2658
  const disabled = useCombinedStore(
2586
- [useMessage, useEditComposer],
2659
+ [messageStore, editComposerStore],
2587
2660
  (m, c) => c.isEditing || m.branches.indexOf(m.message.id) + 1 >= m.branches.length
2588
2661
  );
2589
2662
  const callback = useCallback8(() => {
2590
- const { message, branches } = useMessage.getState();
2591
- useThreadActions.getState().switchToBranch(branches[branches.indexOf(message.id) + 1]);
2592
- }, [useThreadActions, useMessage]);
2663
+ const { message, branches } = messageStore.getState();
2664
+ threadActionsStore.getState().switchToBranch(branches[branches.indexOf(message.id) + 1]);
2665
+ }, [threadActionsStore, messageStore]);
2593
2666
  if (disabled) return null;
2594
2667
  return callback;
2595
2668
  };
2596
2669
 
2597
2670
  // src/primitive-hooks/branchPicker/useBranchPickerNumber.tsx
2598
2671
  var useBranchPickerNumber = () => {
2599
- const { useMessage } = useMessageContext();
2600
2672
  const branchIdx = useMessage((s) => s.branches.indexOf(s.message.id));
2601
2673
  return branchIdx + 1;
2602
2674
  };
@@ -2604,16 +2676,17 @@ var useBranchPickerNumber = () => {
2604
2676
  // src/primitive-hooks/branchPicker/useBranchPickerPrevious.tsx
2605
2677
  import { useCallback as useCallback9 } from "react";
2606
2678
  var useBranchPickerPrevious = () => {
2607
- const { useThreadActions } = useThreadContext();
2608
- const { useMessage, useEditComposer } = useMessageContext();
2679
+ const messageStore = useMessageStore();
2680
+ const editComposerStore = useEditComposerStore();
2681
+ const threadActionsStore = useThreadActionsStore();
2609
2682
  const disabled = useCombinedStore(
2610
- [useMessage, useEditComposer],
2683
+ [messageStore, editComposerStore],
2611
2684
  (m, c) => c.isEditing || m.branches.indexOf(m.message.id) <= 0
2612
2685
  );
2613
2686
  const callback = useCallback9(() => {
2614
- const { message, branches } = useMessage.getState();
2615
- useThreadActions.getState().switchToBranch(branches[branches.indexOf(message.id) - 1]);
2616
- }, [useThreadActions, useMessage]);
2687
+ const { message, branches } = messageStore.getState();
2688
+ threadActionsStore.getState().switchToBranch(branches[branches.indexOf(message.id) - 1]);
2689
+ }, [threadActionsStore, messageStore]);
2617
2690
  if (disabled) return null;
2618
2691
  return callback;
2619
2692
  };
@@ -2621,19 +2694,18 @@ var useBranchPickerPrevious = () => {
2621
2694
  // src/primitive-hooks/composer/useComposerCancel.tsx
2622
2695
  import { useCallback as useCallback10 } from "react";
2623
2696
  var useComposerCancel = () => {
2624
- const { useComposer } = useComposerContext();
2697
+ const composerStore = useComposerStore();
2625
2698
  const disabled = useComposer((c) => !c.canCancel);
2626
2699
  const callback = useCallback10(() => {
2627
- const { cancel } = useComposer.getState();
2700
+ const { cancel } = composerStore.getState();
2628
2701
  cancel();
2629
- }, [useComposer]);
2702
+ }, [composerStore]);
2630
2703
  if (disabled) return null;
2631
2704
  return callback;
2632
2705
  };
2633
2706
 
2634
2707
  // src/primitive-hooks/composer/useComposerIf.tsx
2635
2708
  var useComposerIf = (props) => {
2636
- const { useComposer } = useComposerContext();
2637
2709
  return useComposer((composer) => {
2638
2710
  if (props.editing === true && !composer.isEditing) return false;
2639
2711
  if (props.editing === false && composer.isEditing) return false;
@@ -2644,23 +2716,21 @@ var useComposerIf = (props) => {
2644
2716
  // src/primitive-hooks/composer/useComposerSend.tsx
2645
2717
  import { useCallback as useCallback11 } from "react";
2646
2718
  var useComposerSend = () => {
2647
- const {
2648
- useThread,
2649
- useViewport,
2650
- useComposer: useNewComposer
2651
- } = useThreadContext();
2652
- const { useComposer } = useComposerContext();
2719
+ const threadStore = useThreadStore();
2720
+ const threadViewportStore = useThreadViewportStore();
2721
+ const composerStore = useComposerStore();
2722
+ const threadComposerStore = useThreadComposerStore();
2653
2723
  const disabled = useCombinedStore(
2654
- [useThread, useComposer],
2724
+ [threadStore, composerStore],
2655
2725
  (t, c) => t.isRunning || !c.isEditing || c.isEmpty
2656
2726
  );
2657
2727
  const callback = useCallback11(() => {
2658
- const composerState = useComposer.getState();
2728
+ const composerState = composerStore.getState();
2659
2729
  if (!composerState.isEditing) return;
2660
2730
  composerState.send();
2661
- useViewport.getState().scrollToBottom();
2662
- useNewComposer.getState().focus();
2663
- }, [useNewComposer, useComposer, useViewport]);
2731
+ threadViewportStore.getState().scrollToBottom();
2732
+ threadComposerStore.getState().focus();
2733
+ }, [threadComposerStore, composerStore, threadViewportStore]);
2664
2734
  if (disabled) return null;
2665
2735
  return callback;
2666
2736
  };
@@ -2668,11 +2738,12 @@ var useComposerSend = () => {
2668
2738
  // src/primitive-hooks/composer/useComposerAddAttachment.tsx
2669
2739
  import { useCallback as useCallback12 } from "react";
2670
2740
  var useComposerAddAttachment = () => {
2671
- const { useComposer, useThreadRuntime } = useThreadContext();
2672
2741
  const disabled = useComposer((c) => !c.isEditing);
2742
+ const threadComposerStore = useThreadComposerStore();
2743
+ const threadRuntimeStore = useThreadRuntimeStore();
2673
2744
  const callback = useCallback12(() => {
2674
- const { addAttachment } = useComposer.getState();
2675
- const { attachmentAccept } = useThreadRuntime.getState().composer;
2745
+ const { addAttachment } = threadComposerStore.getState();
2746
+ const { attachmentAccept } = threadRuntimeStore.getState().composer;
2676
2747
  const input = document.createElement("input");
2677
2748
  input.type = "file";
2678
2749
  if (attachmentAccept !== "*") {
@@ -2684,14 +2755,13 @@ var useComposerAddAttachment = () => {
2684
2755
  addAttachment(file);
2685
2756
  };
2686
2757
  input.click();
2687
- }, [useComposer, useThreadRuntime]);
2758
+ }, [threadComposerStore, threadRuntimeStore]);
2688
2759
  if (disabled) return null;
2689
2760
  return callback;
2690
2761
  };
2691
2762
 
2692
2763
  // src/primitive-hooks/contentPart/useContentPartDisplay.tsx
2693
2764
  var useContentPartDisplay = () => {
2694
- const { useContentPart } = useContentPartContext();
2695
2765
  const display = useContentPart((c) => {
2696
2766
  if (c.part.type !== "ui")
2697
2767
  throw new Error(
@@ -2704,7 +2774,6 @@ var useContentPartDisplay = () => {
2704
2774
 
2705
2775
  // src/primitive-hooks/contentPart/useContentPartImage.tsx
2706
2776
  var useContentPartImage = () => {
2707
- const { useContentPart } = useContentPartContext();
2708
2777
  const image = useContentPart((c) => {
2709
2778
  if (c.part.type !== "image")
2710
2779
  throw new Error(
@@ -2717,7 +2786,6 @@ var useContentPartImage = () => {
2717
2786
 
2718
2787
  // src/primitive-hooks/contentPart/useContentPartText.tsx
2719
2788
  var useContentPartText = () => {
2720
- const { useContentPart } = useContentPartContext();
2721
2789
  const text = useContentPart((c) => {
2722
2790
  if (c.part.type !== "text")
2723
2791
  throw new Error(
@@ -2730,9 +2798,10 @@ var useContentPartText = () => {
2730
2798
 
2731
2799
  // src/primitive-hooks/message/useMessageIf.tsx
2732
2800
  var useMessageIf = (props) => {
2733
- const { useMessage, useMessageUtils } = useMessageContext();
2801
+ const messageStore = useMessageStore();
2802
+ const messageUtilsStore = useMessageUtilsStore();
2734
2803
  return useCombinedStore(
2735
- [useMessage, useMessageUtils],
2804
+ [messageStore, messageUtilsStore],
2736
2805
  ({ message, branches, isLast }, { isCopied, isHovering, isSpeaking }) => {
2737
2806
  if (props.hasBranches === true && branches.length < 2) return false;
2738
2807
  if (props.user && message.role !== "user") return false;
@@ -2754,9 +2823,10 @@ var useMessageIf = (props) => {
2754
2823
 
2755
2824
  // src/primitive-hooks/thread/useThreadIf.tsx
2756
2825
  var useThreadIf = (props) => {
2757
- const { useThread, useThreadMessages } = useThreadContext();
2826
+ const threadStore = useThreadStore();
2827
+ const threadMessagesStore = useThreadMessagesStore();
2758
2828
  return useCombinedStore(
2759
- [useThread, useThreadMessages],
2829
+ [threadStore, threadMessagesStore],
2760
2830
  (thread, messages) => {
2761
2831
  if (props.empty === true && messages.length !== 0) return false;
2762
2832
  if (props.empty === false && messages.length === 0) return false;
@@ -2777,12 +2847,13 @@ var useThreadEmpty = () => {
2777
2847
  // src/primitive-hooks/thread/useThreadScrollToBottom.tsx
2778
2848
  import { useCallback as useCallback13 } from "react";
2779
2849
  var useThreadScrollToBottom = () => {
2780
- const { useComposer, useViewport } = useThreadContext();
2781
- const isAtBottom = useViewport((s) => s.isAtBottom);
2850
+ const isAtBottom = useThreadViewport((s) => s.isAtBottom);
2851
+ const threadViewportStore = useThreadViewportStore();
2852
+ const threadComposerStore = useThreadComposerStore();
2782
2853
  const handleScrollToBottom = useCallback13(() => {
2783
- useViewport.getState().scrollToBottom();
2784
- useComposer.getState().focus();
2785
- }, [useViewport, useComposer]);
2854
+ threadViewportStore.getState().scrollToBottom();
2855
+ threadComposerStore.getState().focus();
2856
+ }, [threadViewportStore, threadComposerStore]);
2786
2857
  if (isAtBottom) return null;
2787
2858
  return handleScrollToBottom;
2788
2859
  };
@@ -2793,19 +2864,20 @@ var useThreadSuggestion = ({
2793
2864
  prompt,
2794
2865
  autoSend
2795
2866
  }) => {
2796
- const { useThread, useComposer } = useThreadContext();
2867
+ const threadStore = useThreadStore();
2868
+ const composerStore = useThreadComposerStore();
2797
2869
  const append = useAppendMessage();
2798
2870
  const disabled = useThread((t) => t.isDisabled);
2799
2871
  const callback = useCallback14(() => {
2800
- const thread = useThread.getState();
2801
- const composer = useComposer.getState();
2872
+ const thread = threadStore.getState();
2873
+ const composer = composerStore.getState();
2802
2874
  if (autoSend && !thread.isRunning) {
2803
2875
  append(prompt);
2804
2876
  composer.setText("");
2805
2877
  } else {
2806
2878
  composer.setText(prompt);
2807
2879
  }
2808
- }, [useThread, useComposer, autoSend, append, prompt]);
2880
+ }, [threadStore, composerStore, autoSend, append, prompt]);
2809
2881
  if (disabled) return null;
2810
2882
  return callback;
2811
2883
  };
@@ -2831,10 +2903,11 @@ var useActionBarFloatStatus = ({
2831
2903
  autohide,
2832
2904
  autohideFloat
2833
2905
  }) => {
2834
- const { useThread } = useThreadContext();
2835
- const { useMessage, useMessageUtils } = useMessageContext();
2906
+ const threadStore = useThreadStore();
2907
+ const messageStore = useMessageStore();
2908
+ const messageUtilsStore = useMessageUtilsStore();
2836
2909
  return useCombinedStore(
2837
- [useThread, useMessage, useMessageUtils],
2910
+ [threadStore, messageStore, messageUtilsStore],
2838
2911
  (t, m, mu) => {
2839
2912
  if (hideWhenRunning && t.isRunning) return "hidden" /* Hidden */;
2840
2913
  const autohideEnabled = autohide === "always" || autohide === "not-last" && !m.isLast;
@@ -2953,6 +3026,7 @@ var ActionBarPrimitiveStopSpeaking = forwardRef7((props, ref) => {
2953
3026
  }
2954
3027
  );
2955
3028
  });
3029
+ ActionBarPrimitiveStopSpeaking.displayName = "ActionBarPrimitive.StopSpeaking";
2956
3030
 
2957
3031
  // src/primitives/assistantModal/index.ts
2958
3032
  var assistantModal_exports = {};
@@ -2973,12 +3047,12 @@ import { useCallbackRef as useCallbackRef2 } from "@radix-ui/react-use-callback-
2973
3047
  import { useEffect as useEffect8 } from "react";
2974
3048
  var useOnComposerFocus = (callback) => {
2975
3049
  const callbackRef = useCallbackRef2(callback);
2976
- const { useComposer } = useThreadContext();
3050
+ const threadComposerStore = useThreadComposerStore();
2977
3051
  useEffect8(() => {
2978
- return useComposer.getState().onFocus(() => {
3052
+ return threadComposerStore.getState().onFocus(() => {
2979
3053
  callbackRef();
2980
3054
  });
2981
- }, [useComposer, callbackRef]);
3055
+ }, [threadComposerStore, callbackRef]);
2982
3056
  };
2983
3057
 
2984
3058
  // src/primitives/assistantModal/scope.tsx
@@ -3160,10 +3234,10 @@ var useManagedRef = (callback) => {
3160
3234
  import { useComposedRefs } from "@radix-ui/react-compose-refs";
3161
3235
  import { jsx as jsx19 } from "react/jsx-runtime";
3162
3236
  var useIsHoveringRef = () => {
3163
- const { useMessageUtils } = useMessageContext();
3237
+ const messageUtilsStore = useMessageUtilsStore();
3164
3238
  const callbackRef = useCallback16(
3165
3239
  (el) => {
3166
- const setIsHovering = useMessageUtils.getState().setIsHovering;
3240
+ const setIsHovering = messageUtilsStore.getState().setIsHovering;
3167
3241
  const handleMouseEnter = () => {
3168
3242
  setIsHovering(true);
3169
3243
  };
@@ -3178,14 +3252,14 @@ var useIsHoveringRef = () => {
3178
3252
  setIsHovering(false);
3179
3253
  };
3180
3254
  },
3181
- [useMessageUtils]
3255
+ [messageUtilsStore]
3182
3256
  );
3183
3257
  return useManagedRef(callbackRef);
3184
3258
  };
3185
- var MessagePrimitiveRoot = forwardRef11(({ onMouseEnter, onMouseLeave, ...rest }, forwardRef30) => {
3259
+ var MessagePrimitiveRoot = forwardRef11((props, forwardRef30) => {
3186
3260
  const isHoveringRef = useIsHoveringRef();
3187
3261
  const ref = useComposedRefs(forwardRef30, isHoveringRef);
3188
- return /* @__PURE__ */ jsx19(Primitive5.div, { ...rest, ref });
3262
+ return /* @__PURE__ */ jsx19(Primitive5.div, { ...props, ref });
3189
3263
  });
3190
3264
  MessagePrimitiveRoot.displayName = "MessagePrimitive.Root";
3191
3265
 
@@ -3204,7 +3278,7 @@ import { memo as memo2 } from "react";
3204
3278
 
3205
3279
  // src/context/providers/ContentPartProvider.tsx
3206
3280
  import { useEffect as useEffect9, useState as useState11 } from "react";
3207
- import { create as create13 } from "zustand";
3281
+ import { create as create12 } from "zustand";
3208
3282
  import { jsx as jsx20 } from "react/jsx-runtime";
3209
3283
  var COMPLETE_STATUS = {
3210
3284
  type: "complete"
@@ -3225,7 +3299,7 @@ var toContentPartStatus = (message, partIndex, part) => {
3225
3299
  return message.status;
3226
3300
  };
3227
3301
  var EMPTY_CONTENT = Object.freeze({ type: "text", text: "" });
3228
- var getContentPartState = ({ message }, useContentPart, partIndex) => {
3302
+ var getContentPartState = ({ message }, useContentPart2, partIndex) => {
3229
3303
  let part = message.content[partIndex];
3230
3304
  if (!part) {
3231
3305
  if (message.content.length === 0 && partIndex === 0) {
@@ -3233,20 +3307,22 @@ var getContentPartState = ({ message }, useContentPart, partIndex) => {
3233
3307
  } else {
3234
3308
  return null;
3235
3309
  }
3310
+ } else if (message.content.length === 1 && part.type === "text" && part.text.length === 0) {
3311
+ part = EMPTY_CONTENT;
3236
3312
  }
3237
3313
  const status = toContentPartStatus(message, partIndex, part);
3238
- const currentState = useContentPart?.getState();
3314
+ const currentState = useContentPart2?.getState();
3239
3315
  if (currentState && currentState.part === part && currentState.status === status)
3240
3316
  return null;
3241
3317
  return Object.freeze({ part, status });
3242
3318
  };
3243
3319
  var useContentPartContext2 = (partIndex) => {
3244
- const { useMessage } = useMessageContext();
3320
+ const messageStore = useMessageStore();
3245
3321
  const [context] = useState11(() => {
3246
- const useContentPart = create13(
3247
- () => getContentPartState(useMessage.getState(), void 0, partIndex)
3322
+ const useContentPart2 = create12(
3323
+ () => getContentPartState(messageStore.getState(), void 0, partIndex)
3248
3324
  );
3249
- return { useContentPart };
3325
+ return { useContentPart: useContentPart2 };
3250
3326
  });
3251
3327
  useEffect9(() => {
3252
3328
  const syncContentPart = (message) => {
@@ -3258,9 +3334,9 @@ var useContentPartContext2 = (partIndex) => {
3258
3334
  if (!newState) return;
3259
3335
  writableStore(context.useContentPart).setState(newState, true);
3260
3336
  };
3261
- syncContentPart(useMessage.getState());
3262
- return useMessage.subscribe(syncContentPart);
3263
- }, [context, useMessage, partIndex]);
3337
+ syncContentPart(messageStore.getState());
3338
+ return messageStore.subscribe(syncContentPart);
3339
+ }, [context, messageStore, partIndex]);
3264
3340
  return context;
3265
3341
  };
3266
3342
  var ContentPartProvider = ({
@@ -3308,7 +3384,6 @@ ContentPartPrimitiveDisplay.displayName = "ContentPartPrimitive.Display";
3308
3384
 
3309
3385
  // src/primitives/contentPart/ContentPartInProgress.tsx
3310
3386
  var ContentPartPrimitiveInProgress = ({ children }) => {
3311
- const { useContentPart } = useContentPartContext();
3312
3387
  const isInProgress = useContentPart((c) => c.status.type === "running");
3313
3388
  return isInProgress ? children : null;
3314
3389
  };
@@ -3320,7 +3395,6 @@ var ToolUIDisplay = ({
3320
3395
  UI,
3321
3396
  ...props
3322
3397
  }) => {
3323
- const { useToolUIs } = useAssistantContext();
3324
3398
  const Render = useToolUIs((s) => s.getToolUI(props.part.toolName)) ?? UI;
3325
3399
  if (!Render) return null;
3326
3400
  return /* @__PURE__ */ jsx23(Render, { ...props });
@@ -3335,24 +3409,24 @@ var defaultComponents = {
3335
3409
  };
3336
3410
  var MessageContentPartComponent = ({
3337
3411
  components: {
3338
- Empty = defaultComponents.Text,
3339
3412
  Text: Text2 = defaultComponents.Text,
3413
+ Empty,
3340
3414
  Image: Image2 = defaultComponents.Image,
3341
3415
  UI = defaultComponents.UI,
3342
3416
  tools: { by_name = {}, Fallback: Fallback2 = void 0 } = {}
3343
3417
  } = {}
3344
3418
  }) => {
3345
- const { useThreadActions } = useThreadContext();
3346
- const { useMessage } = useMessageContext();
3347
- const addToolResult = useThreadActions((t) => t.addToolResult);
3348
- const { useContentPart } = useContentPartContext();
3419
+ const messageStore = useMessageStore();
3420
+ const threadActionsStore = useThreadActionsStore();
3349
3421
  const { part, status } = useContentPart();
3350
3422
  const type = part.type;
3351
3423
  switch (type) {
3352
3424
  case "text":
3353
3425
  if (status.type === "requires-action")
3354
3426
  throw new Error("Encountered unexpected requires-action status");
3355
- if (part === EMPTY_CONTENT) return /* @__PURE__ */ jsx23(Empty, { part, status });
3427
+ if (part === EMPTY_CONTENT && !!Empty) {
3428
+ return /* @__PURE__ */ jsx23(Empty, { status });
3429
+ }
3356
3430
  return /* @__PURE__ */ jsx23(Text2, { part, status });
3357
3431
  case "image":
3358
3432
  if (status.type === "requires-action")
@@ -3364,8 +3438,8 @@ var MessageContentPartComponent = ({
3364
3438
  return /* @__PURE__ */ jsx23(UI, { part, status });
3365
3439
  case "tool-call": {
3366
3440
  const Tool = by_name[part.toolName] || Fallback2;
3367
- const addResult = (result) => addToolResult({
3368
- messageId: useMessage.getState().message.id,
3441
+ const addResult = (result) => threadActionsStore.getState().addToolResult({
3442
+ messageId: messageStore.getState().message.id,
3369
3443
  toolName: part.toolName,
3370
3444
  toolCallId: part.toolCallId,
3371
3445
  result
@@ -3398,7 +3472,6 @@ var MessageContentPart = memo2(
3398
3472
  var MessagePrimitiveContent = ({
3399
3473
  components
3400
3474
  }) => {
3401
- const { useMessage } = useMessageContext();
3402
3475
  const contentLength = useMessage((s) => s.message.content.length) || 1;
3403
3476
  return Array.from({ length: contentLength }, (_, index) => /* @__PURE__ */ jsx23(MessageContentPart, { partIndex: index, components }, index));
3404
3477
  };
@@ -3414,48 +3487,70 @@ MessagePrimitiveInProgress.displayName = "MessagePrimitive.InProgress";
3414
3487
  import { memo as memo3 } from "react";
3415
3488
 
3416
3489
  // src/context/react/AttachmentContext.ts
3417
- import { createContext as createContext6, useContext as useContext6 } from "react";
3490
+ import { createContext as createContext6, useContext as useContext3 } from "react";
3418
3491
  var AttachmentContext = createContext6(
3419
3492
  null
3420
3493
  );
3421
3494
  function useAttachmentContext(options) {
3422
- const context = useContext6(AttachmentContext);
3423
- if (options?.type === "composer" && context?.type !== "composer")
3495
+ const context = useContext3(AttachmentContext);
3496
+ if (!options?.optional && !context)
3424
3497
  throw new Error(
3425
- "This component must be used within a ComposerPrimitive.Attachments component."
3498
+ "This component must be used within a ComposerPrimitive.Attachments or MessagePrimitive.Attachments component."
3426
3499
  );
3427
- if (options?.type === "message" && context?.type !== "message")
3500
+ return context;
3501
+ }
3502
+ function useComposerAttachmentContext(options) {
3503
+ const context = useAttachmentContext(options);
3504
+ if (!context) return null;
3505
+ if (context.type !== "composer")
3428
3506
  throw new Error(
3429
- "This component must be used within a MessagePrimitive.Attachments component."
3507
+ "This component must be used within a ComposerPrimitive.Attachments component."
3430
3508
  );
3431
- if (!options?.optional && !context)
3509
+ return context;
3510
+ }
3511
+ function useMessageAttachmentContext(options) {
3512
+ const context = useAttachmentContext(options);
3513
+ if (!context) return null;
3514
+ if (context.type !== "message")
3432
3515
  throw new Error(
3433
- "This component must be used within a ComposerPrimitive.Attachments or MessagePrimitive.Attachments component."
3516
+ "This component must be used within a MessagePrimitive.Attachments component."
3434
3517
  );
3435
3518
  return context;
3436
3519
  }
3520
+ var { useAttachment, useAttachmentStore } = createContextStoreHook(
3521
+ useAttachmentContext,
3522
+ "useAttachment"
3523
+ );
3524
+ var {
3525
+ useAttachment: useComposerAttachment,
3526
+ useAttachmentStore: useComposerAttachmentStore
3527
+ } = createContextStoreHook(useComposerAttachmentContext, "useAttachment");
3528
+ var {
3529
+ useAttachment: useMessageAttachment,
3530
+ useAttachmentStore: useMessageAttachmentStore
3531
+ } = createContextStoreHook(useMessageAttachmentContext, "useAttachment");
3437
3532
 
3438
3533
  // src/context/providers/MessageAttachmentProvider.tsx
3439
3534
  import { useEffect as useEffect10, useState as useState12 } from "react";
3440
- import { create as create14 } from "zustand";
3535
+ import { create as create13 } from "zustand";
3441
3536
  import { jsx as jsx24 } from "react/jsx-runtime";
3442
- var getAttachment = ({ message }, useAttachment, partIndex) => {
3537
+ var getAttachment = ({ message }, useAttachment2, partIndex) => {
3443
3538
  if (message.role !== "user") return null;
3444
3539
  const attachments = message.attachments;
3445
- let attachment = attachments[partIndex];
3540
+ const attachment = attachments[partIndex];
3446
3541
  if (!attachment) return null;
3447
- const currentState = useAttachment?.getState();
3542
+ const currentState = useAttachment2?.getState();
3448
3543
  if (currentState && currentState.attachment === attachment) return null;
3449
3544
  return Object.freeze({ attachment });
3450
3545
  };
3451
- var useMessageAttachmentContext = (partIndex) => {
3452
- const { useMessage } = useMessageContext();
3546
+ var useMessageAttachmentContext2 = (partIndex) => {
3547
+ const messageStore = useMessageStore();
3453
3548
  const [context] = useState12(
3454
3549
  () => {
3455
- const useAttachment = create14(
3456
- () => getAttachment(useMessage.getState(), void 0, partIndex)
3550
+ const useAttachment2 = create13(
3551
+ () => getAttachment(messageStore.getState(), void 0, partIndex)
3457
3552
  );
3458
- return { type: "message", useAttachment };
3553
+ return { type: "message", useAttachment: useAttachment2 };
3459
3554
  }
3460
3555
  );
3461
3556
  useEffect10(() => {
@@ -3468,16 +3563,16 @@ var useMessageAttachmentContext = (partIndex) => {
3468
3563
  if (!newState) return;
3469
3564
  writableStore(context.useAttachment).setState(newState, true);
3470
3565
  };
3471
- syncAttachment(useMessage.getState());
3472
- return useMessage.subscribe(syncAttachment);
3473
- }, [context, useMessage, partIndex]);
3566
+ syncAttachment(messageStore.getState());
3567
+ return messageStore.subscribe(syncAttachment);
3568
+ }, [context, messageStore, partIndex]);
3474
3569
  return context;
3475
3570
  };
3476
3571
  var MessageAttachmentProvider = ({
3477
3572
  attachmentIndex: partIndex,
3478
3573
  children
3479
3574
  }) => {
3480
- const context = useMessageAttachmentContext(partIndex);
3575
+ const context = useMessageAttachmentContext2(partIndex);
3481
3576
  return /* @__PURE__ */ jsx24(AttachmentContext.Provider, { value: context, children });
3482
3577
  };
3483
3578
 
@@ -3498,8 +3593,7 @@ var getComponent = (components, attachment) => {
3498
3593
  }
3499
3594
  };
3500
3595
  var AttachmentComponent = ({ components }) => {
3501
- const { useAttachment } = useAttachmentContext({ type: "message" });
3502
- const Component = useAttachment(
3596
+ const Component = useMessageAttachment(
3503
3597
  (a) => getComponent(components, a.attachment)
3504
3598
  );
3505
3599
  if (!Component) return null;
@@ -3513,7 +3607,6 @@ var MessageAttachment = memo3(
3513
3607
  (prev, next) => prev.attachmentIndex === next.attachmentIndex && prev.components?.Image === next.components?.Image && prev.components?.Document === next.components?.Document && prev.components?.File === next.components?.File && prev.components?.Attachment === next.components?.Attachment
3514
3608
  );
3515
3609
  var MessagePrimitiveAttachments = ({ components }) => {
3516
- const { useMessage } = useMessageContext();
3517
3610
  const attachmentsCount = useMessage(({ message }) => {
3518
3611
  if (message.role !== "user") return 0;
3519
3612
  return message.attachments.length;
@@ -3595,8 +3688,8 @@ var ComposerPrimitiveInput = forwardRef16(
3595
3688
  onKeyDown,
3596
3689
  ...rest
3597
3690
  }, forwardedRef) => {
3598
- const { useThread } = useThreadContext();
3599
- const { useComposer, type } = useComposerContext();
3691
+ const threadStore = useThreadStore();
3692
+ const composerStore = useComposerStore();
3600
3693
  const value = useComposer((c) => {
3601
3694
  if (!c.isEditing) return "";
3602
3695
  return c.text;
@@ -3606,7 +3699,7 @@ var ComposerPrimitiveInput = forwardRef16(
3606
3699
  const textareaRef = useRef4(null);
3607
3700
  const ref = useComposedRefs2(forwardedRef, textareaRef);
3608
3701
  useEscapeKeydown2((e) => {
3609
- const composer = useComposer.getState();
3702
+ const composer = composerStore.getState();
3610
3703
  if (composer.canCancel) {
3611
3704
  composer.cancel();
3612
3705
  e.preventDefault();
@@ -3616,7 +3709,7 @@ var ComposerPrimitiveInput = forwardRef16(
3616
3709
  if (isDisabled) return;
3617
3710
  if (e.nativeEvent.isComposing) return;
3618
3711
  if (e.key === "Enter" && e.shiftKey === false) {
3619
- const { isRunning } = useThread.getState();
3712
+ const { isRunning } = threadStore.getState();
3620
3713
  if (!isRunning) {
3621
3714
  e.preventDefault();
3622
3715
  textareaRef.current?.closest("form")?.requestSubmit();
@@ -3635,7 +3728,7 @@ var ComposerPrimitiveInput = forwardRef16(
3635
3728
  }, [autoFocusEnabled]);
3636
3729
  useEffect11(() => focus(), [focus]);
3637
3730
  useOnComposerFocus(() => {
3638
- if (type === "new") {
3731
+ if (composerStore.getState().type === "thread") {
3639
3732
  focus();
3640
3733
  }
3641
3734
  });
@@ -3648,7 +3741,7 @@ var ComposerPrimitiveInput = forwardRef16(
3648
3741
  ref,
3649
3742
  disabled: isDisabled,
3650
3743
  onChange: composeEventHandlers6(onChange, (e) => {
3651
- const composerState = useComposer.getState();
3744
+ const composerState = composerStore.getState();
3652
3745
  if (!composerState.isEditing) return;
3653
3746
  return composerState.setText(e.target.value);
3654
3747
  }),
@@ -3682,23 +3775,23 @@ import { memo as memo4 } from "react";
3682
3775
 
3683
3776
  // src/context/providers/ComposerAttachmentProvider.tsx
3684
3777
  import { useEffect as useEffect12, useState as useState13 } from "react";
3685
- import { create as create15 } from "zustand";
3778
+ import { create as create14 } from "zustand";
3686
3779
  import { jsx as jsx29 } from "react/jsx-runtime";
3687
- var getAttachment2 = ({ attachments }, useAttachment, partIndex) => {
3688
- let attachment = attachments[partIndex];
3780
+ var getAttachment2 = ({ attachments }, useAttachment2, partIndex) => {
3781
+ const attachment = attachments[partIndex];
3689
3782
  if (!attachment) return null;
3690
- const currentState = useAttachment?.getState();
3783
+ const currentState = useAttachment2?.getState();
3691
3784
  if (currentState && currentState.attachment === attachment) return null;
3692
3785
  return Object.freeze({ attachment });
3693
3786
  };
3694
- var useComposerAttachmentContext = (partIndex) => {
3695
- const { useComposer } = useThreadContext();
3787
+ var useComposerAttachmentContext2 = (partIndex) => {
3788
+ const threadComposerStore = useThreadComposerStore();
3696
3789
  const [context] = useState13(
3697
3790
  () => {
3698
- const useAttachment = create15(
3699
- () => getAttachment2(useComposer.getState(), void 0, partIndex)
3791
+ const useAttachment2 = create14(
3792
+ () => getAttachment2(threadComposerStore.getState(), void 0, partIndex)
3700
3793
  );
3701
- return { type: "composer", useAttachment };
3794
+ return { type: "composer", useAttachment: useAttachment2 };
3702
3795
  }
3703
3796
  );
3704
3797
  useEffect12(() => {
@@ -3711,13 +3804,13 @@ var useComposerAttachmentContext = (partIndex) => {
3711
3804
  if (!newState) return;
3712
3805
  writableStore(context.useAttachment).setState(newState, true);
3713
3806
  };
3714
- syncAttachment(useComposer.getState());
3715
- return useComposer.subscribe(syncAttachment);
3716
- }, [context, useComposer, partIndex]);
3807
+ syncAttachment(threadComposerStore.getState());
3808
+ return threadComposerStore.subscribe(syncAttachment);
3809
+ }, [context, threadComposerStore, partIndex]);
3717
3810
  return context;
3718
3811
  };
3719
3812
  var ComposerAttachmentProvider = ({ attachmentIndex: partIndex, children }) => {
3720
- const context = useComposerAttachmentContext(partIndex);
3813
+ const context = useComposerAttachmentContext2(partIndex);
3721
3814
  return /* @__PURE__ */ jsx29(AttachmentContext.Provider, { value: context, children });
3722
3815
  };
3723
3816
 
@@ -3738,8 +3831,7 @@ var getComponent2 = (components, attachment) => {
3738
3831
  }
3739
3832
  };
3740
3833
  var AttachmentComponent2 = ({ components }) => {
3741
- const { useAttachment } = useAttachmentContext({ type: "composer" });
3742
- const Component = useAttachment(
3834
+ const Component = useComposerAttachment(
3743
3835
  (a) => getComponent2(components, a.attachment)
3744
3836
  );
3745
3837
  if (!Component) return null;
@@ -3753,8 +3845,7 @@ var ComposerAttachment = memo4(
3753
3845
  (prev, next) => prev.attachmentIndex === next.attachmentIndex && prev.components?.Image === next.components?.Image && prev.components?.Document === next.components?.Document && prev.components?.File === next.components?.File && prev.components?.Attachment === next.components?.Attachment
3754
3846
  );
3755
3847
  var ComposerPrimitiveAttachments = ({ components }) => {
3756
- const { useComposer } = useThreadContext();
3757
- const attachmentsCount = useComposer((s) => s.attachments.length);
3848
+ const attachmentsCount = useThreadComposer((s) => s.attachments.length);
3758
3849
  return Array.from({ length: attachmentsCount }, (_, index) => /* @__PURE__ */ jsx30(
3759
3850
  ComposerAttachment,
3760
3851
  {
@@ -3879,12 +3970,12 @@ import { useCallbackRef as useCallbackRef4 } from "@radix-ui/react-use-callback-
3879
3970
  import { useEffect as useEffect13 } from "react";
3880
3971
  var useOnScrollToBottom = (callback) => {
3881
3972
  const callbackRef = useCallbackRef4(callback);
3882
- const { useViewport } = useThreadContext();
3973
+ const threadViewportStore = useThreadViewportStore();
3883
3974
  useEffect13(() => {
3884
- return useViewport.getState().onScrollToBottom(() => {
3975
+ return threadViewportStore.getState().onScrollToBottom(() => {
3885
3976
  callbackRef();
3886
3977
  });
3887
- }, [useViewport, callbackRef]);
3978
+ }, [threadViewportStore, callbackRef]);
3888
3979
  };
3889
3980
 
3890
3981
  // src/primitive-hooks/thread/useThreadViewportAutoScroll.tsx
@@ -3892,7 +3983,7 @@ var useThreadViewportAutoScroll = ({
3892
3983
  autoScroll = true
3893
3984
  }) => {
3894
3985
  const divRef = useRef5(null);
3895
- const { useViewport } = useThreadContext();
3986
+ const threadViewportStore = useThreadViewportStore();
3896
3987
  const lastScrollTop = useRef5(0);
3897
3988
  const isScrollingToBottomRef = useRef5(false);
3898
3989
  const scrollToBottom = (behavior) => {
@@ -3904,7 +3995,7 @@ var useThreadViewportAutoScroll = ({
3904
3995
  const handleScroll = () => {
3905
3996
  const div = divRef.current;
3906
3997
  if (!div) return;
3907
- const isAtBottom = useViewport.getState().isAtBottom;
3998
+ const isAtBottom = threadViewportStore.getState().isAtBottom;
3908
3999
  const newIsAtBottom = div.scrollHeight - div.scrollTop <= div.clientHeight + 1;
3909
4000
  if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {
3910
4001
  } else {
@@ -3912,13 +4003,15 @@ var useThreadViewportAutoScroll = ({
3912
4003
  isScrollingToBottomRef.current = false;
3913
4004
  }
3914
4005
  if (newIsAtBottom !== isAtBottom) {
3915
- writableStore(useViewport).setState({ isAtBottom: newIsAtBottom });
4006
+ writableStore(threadViewportStore).setState({
4007
+ isAtBottom: newIsAtBottom
4008
+ });
3916
4009
  }
3917
4010
  }
3918
4011
  lastScrollTop.current = div.scrollTop;
3919
4012
  };
3920
4013
  const resizeRef = useOnResizeContent(() => {
3921
- if (isScrollingToBottomRef.current || useViewport.getState().isAtBottom) {
4014
+ if (isScrollingToBottomRef.current || threadViewportStore.getState().isAtBottom) {
3922
4015
  scrollToBottom("instant");
3923
4016
  }
3924
4017
  handleScroll();
@@ -3938,7 +4031,7 @@ var useThreadViewportAutoScroll = ({
3938
4031
 
3939
4032
  // src/primitives/thread/ThreadViewport.tsx
3940
4033
  import { jsx as jsx32 } from "react/jsx-runtime";
3941
- var ThreadPrimitiveViewport = forwardRef18(({ autoScroll, onScroll, children, ...rest }, forwardedRef) => {
4034
+ var ThreadPrimitiveViewport = forwardRef18(({ autoScroll, children, ...rest }, forwardedRef) => {
3942
4035
  const autoScrollRef = useThreadViewportAutoScroll({
3943
4036
  autoScroll
3944
4037
  });
@@ -3952,14 +4045,15 @@ import { memo as memo5 } from "react";
3952
4045
 
3953
4046
  // src/context/providers/MessageProvider.tsx
3954
4047
  import { useEffect as useEffect14, useState as useState14 } from "react";
3955
- import { create as create18 } from "zustand";
4048
+ import { create as create17 } from "zustand";
3956
4049
 
3957
4050
  // src/context/stores/EditComposer.ts
3958
- import { create as create16 } from "zustand";
4051
+ import { create as create15 } from "zustand";
3959
4052
  var makeEditComposerStore = ({
3960
4053
  onEdit,
3961
4054
  onSend
3962
- }) => create16()((set, get) => ({
4055
+ }) => create15()((set, get) => ({
4056
+ type: "edit",
3963
4057
  get value() {
3964
4058
  return get().text;
3965
4059
  },
@@ -3993,8 +4087,8 @@ var makeEditComposerStore = ({
3993
4087
  }));
3994
4088
 
3995
4089
  // src/context/stores/MessageUtils.ts
3996
- import { create as create17 } from "zustand";
3997
- var makeMessageUtilsStore = () => create17((set) => {
4090
+ import { create as create16 } from "zustand";
4091
+ var makeMessageUtilsStore = () => create16((set) => {
3998
4092
  let utterance = null;
3999
4093
  return {
4000
4094
  isCopied: false,
@@ -4024,13 +4118,13 @@ import { jsx as jsx33 } from "react/jsx-runtime";
4024
4118
  var getIsLast = (messages, message) => {
4025
4119
  return messages[messages.length - 1]?.id === message.id;
4026
4120
  };
4027
- var getMessageState = (messages, getBranches, useMessage, messageIndex) => {
4121
+ var getMessageState = (messages, getBranches, useMessage2, messageIndex) => {
4028
4122
  const parentId = messages[messageIndex - 1]?.id ?? null;
4029
4123
  const message = messages[messageIndex];
4030
4124
  if (!message) return null;
4031
4125
  const isLast = getIsLast(messages, message);
4032
4126
  const branches = getBranches(message.id);
4033
- const currentState = useMessage?.getState();
4127
+ const currentState = useMessage2?.getState();
4034
4128
  if (currentState && currentState.message === message && currentState.parentId === parentId && currentState.branches === branches && currentState.isLast === isLast)
4035
4129
  return null;
4036
4130
  return Object.freeze({
@@ -4041,62 +4135,55 @@ var getMessageState = (messages, getBranches, useMessage, messageIndex) => {
4041
4135
  });
4042
4136
  };
4043
4137
  var useMessageContext2 = (messageIndex) => {
4044
- const { useThreadMessages, useThreadActions } = useThreadContext();
4138
+ const threadMessagesStore = useThreadMessagesStore();
4139
+ const threadActionsStore = useThreadActionsStore();
4045
4140
  const [context] = useState14(() => {
4046
- const useMessage = create18(
4141
+ const useMessage2 = create17(
4047
4142
  () => getMessageState(
4048
- useThreadMessages.getState(),
4049
- useThreadActions.getState().getBranches,
4143
+ threadMessagesStore.getState(),
4144
+ threadActionsStore.getState().getBranches,
4050
4145
  void 0,
4051
4146
  messageIndex
4052
4147
  )
4053
4148
  );
4054
- const useMessageUtils = makeMessageUtilsStore();
4055
- const useEditComposer = makeEditComposerStore({
4149
+ const useMessageUtils2 = makeMessageUtilsStore();
4150
+ const useEditComposer2 = makeEditComposerStore({
4056
4151
  onEdit: () => {
4057
- const message = useMessage.getState().message;
4058
- if (message.role !== "user")
4059
- throw new Error(
4060
- "Tried to edit a non-user message. Editing is only supported for user messages. This is likely an internal bug in assistant-ui."
4061
- );
4152
+ const message = useMessage2.getState().message;
4062
4153
  const text = getThreadMessageText(message);
4063
4154
  return text;
4064
4155
  },
4065
4156
  onSend: (text) => {
4066
- const { message, parentId } = useMessage.getState();
4067
- if (message.role !== "user")
4068
- throw new Error(
4069
- "Tried to edit a non-user message. Editing is only supported for user messages. This is likely an internal bug in assistant-ui."
4070
- );
4157
+ const { message, parentId } = useMessage2.getState();
4071
4158
  const previousText = getThreadMessageText(message);
4072
4159
  if (previousText === text) return;
4073
4160
  const nonTextParts = message.content.filter(
4074
4161
  (part) => part.type !== "text" && part.type !== "ui"
4075
4162
  );
4076
- useThreadActions.getState().append({
4163
+ threadActionsStore.getState().append({
4077
4164
  parentId,
4078
- role: "user",
4165
+ role: message.role,
4079
4166
  content: [{ type: "text", text }, ...nonTextParts],
4080
4167
  attachments: message.attachments
4081
4168
  });
4082
4169
  }
4083
4170
  });
4084
- return { useMessage, useMessageUtils, useEditComposer };
4171
+ return { useMessage: useMessage2, useMessageUtils: useMessageUtils2, useEditComposer: useEditComposer2 };
4085
4172
  });
4086
4173
  useEffect14(() => {
4087
4174
  const syncMessage = (thread) => {
4088
4175
  const newState = getMessageState(
4089
4176
  thread,
4090
- useThreadActions.getState().getBranches,
4177
+ threadActionsStore.getState().getBranches,
4091
4178
  context.useMessage,
4092
4179
  messageIndex
4093
4180
  );
4094
4181
  if (!newState) return;
4095
4182
  writableStore(context.useMessage).setState(newState, true);
4096
4183
  };
4097
- syncMessage(useThreadMessages.getState());
4098
- return useThreadMessages.subscribe(syncMessage);
4099
- }, [useThreadMessages, useThreadActions, context, messageIndex]);
4184
+ syncMessage(threadMessagesStore.getState());
4185
+ return threadMessagesStore.subscribe(syncMessage);
4186
+ }, [threadMessagesStore, threadActionsStore, context, messageIndex]);
4100
4187
  return context;
4101
4188
  };
4102
4189
  var MessageProvider = ({
@@ -4108,38 +4195,57 @@ var MessageProvider = ({
4108
4195
  };
4109
4196
 
4110
4197
  // src/primitives/thread/ThreadMessages.tsx
4111
- import { jsx as jsx34, jsxs as jsxs4 } from "react/jsx-runtime";
4198
+ import { jsx as jsx34 } from "react/jsx-runtime";
4199
+ var isComponentsSame = (prev, next) => {
4200
+ return prev.Message === next.Message && prev.EditComposer === next.EditComposer && prev.UserEditComposer === next.UserEditComposer && prev.AssistantEditComposer === next.AssistantEditComposer && prev.SystemEditComposer === next.SystemEditComposer && prev.UserMessage === next.UserMessage && prev.AssistantMessage === next.AssistantMessage && prev.SystemMessage === next.SystemMessage;
4201
+ };
4112
4202
  var DEFAULT_SYSTEM_MESSAGE = () => null;
4113
- var getComponents = (components) => {
4114
- return {
4115
- EditComposer: components.EditComposer ?? components.UserMessage ?? components.Message,
4116
- UserMessage: components.UserMessage ?? components.Message,
4117
- AssistantMessage: components.AssistantMessage ?? components.Message,
4118
- SystemMessage: components.SystemMessage ?? DEFAULT_SYSTEM_MESSAGE
4119
- };
4203
+ var getComponent3 = (components, role, isEditing) => {
4204
+ switch (role) {
4205
+ case "user":
4206
+ if (isEditing) {
4207
+ return components.UserEditComposer ?? components.EditComposer ?? components.UserMessage ?? components.Message;
4208
+ } else {
4209
+ return components.UserMessage ?? components.Message;
4210
+ }
4211
+ case "assistant":
4212
+ if (isEditing) {
4213
+ return components.AssistantEditComposer ?? components.EditComposer ?? components.AssistantMessage ?? components.Message;
4214
+ } else {
4215
+ return components.AssistantMessage ?? components.Message;
4216
+ }
4217
+ case "system":
4218
+ if (isEditing) {
4219
+ return components.SystemEditComposer ?? components.EditComposer ?? components.SystemMessage ?? components.Message;
4220
+ } else {
4221
+ return components.SystemMessage ?? DEFAULT_SYSTEM_MESSAGE;
4222
+ }
4223
+ default:
4224
+ const _exhaustiveCheck = role;
4225
+ throw new Error(`Unknown message role: ${_exhaustiveCheck}`);
4226
+ }
4227
+ };
4228
+ var ThreadMessageComponent = ({
4229
+ components
4230
+ }) => {
4231
+ const role = useMessage((m) => m.message.role);
4232
+ const isEditing = useEditComposer((c) => c.isEditing);
4233
+ const Component = getComponent3(components, role, isEditing);
4234
+ return /* @__PURE__ */ jsx34(Component, {});
4120
4235
  };
4121
4236
  var ThreadMessageImpl = ({
4122
4237
  messageIndex,
4123
4238
  components
4124
4239
  }) => {
4125
- const { UserMessage: UserMessage2, EditComposer: EditComposer2, AssistantMessage: AssistantMessage2, SystemMessage: SystemMessage2 } = getComponents(components);
4126
- return /* @__PURE__ */ jsxs4(MessageProvider, { messageIndex, children: [
4127
- /* @__PURE__ */ jsxs4(MessagePrimitiveIf, { user: true, children: [
4128
- /* @__PURE__ */ jsx34(ComposerPrimitiveIf, { editing: false, children: /* @__PURE__ */ jsx34(UserMessage2, {}) }),
4129
- /* @__PURE__ */ jsx34(ComposerPrimitiveIf, { editing: true, children: /* @__PURE__ */ jsx34(EditComposer2, {}) })
4130
- ] }),
4131
- /* @__PURE__ */ jsx34(MessagePrimitiveIf, { assistant: true, children: /* @__PURE__ */ jsx34(AssistantMessage2, {}) }),
4132
- /* @__PURE__ */ jsx34(MessagePrimitiveIf, { system: true, children: /* @__PURE__ */ jsx34(SystemMessage2, {}) })
4133
- ] });
4240
+ return /* @__PURE__ */ jsx34(MessageProvider, { messageIndex, children: /* @__PURE__ */ jsx34(ThreadMessageComponent, { components }) });
4134
4241
  };
4135
4242
  var ThreadMessage = memo5(
4136
4243
  ThreadMessageImpl,
4137
- (prev, next) => prev.messageIndex === next.messageIndex && prev.components.Message === next.components.Message && prev.components.UserMessage === next.components.UserMessage && prev.components.EditComposer === next.components.EditComposer && prev.components.AssistantMessage === next.components.AssistantMessage && prev.components.SystemMessage === next.components.SystemMessage
4244
+ (prev, next) => prev.messageIndex === next.messageIndex && isComponentsSame(prev.components, next.components)
4138
4245
  );
4139
4246
  var ThreadPrimitiveMessagesImpl = ({
4140
4247
  components
4141
4248
  }) => {
4142
- const { useThreadMessages } = useThreadContext();
4143
4249
  const messagesLength = useThreadMessages((t) => t.length);
4144
4250
  if (messagesLength === 0) return null;
4145
4251
  return Array.from({ length: messagesLength }, (_, index) => /* @__PURE__ */ jsx34(ThreadMessage, { messageIndex: index, components }, index));
@@ -4147,7 +4253,7 @@ var ThreadPrimitiveMessagesImpl = ({
4147
4253
  ThreadPrimitiveMessagesImpl.displayName = "ThreadPrimitive.Messages";
4148
4254
  var ThreadPrimitiveMessages = memo5(
4149
4255
  ThreadPrimitiveMessagesImpl,
4150
- (prev, next) => prev.components?.Message === next.components?.Message && prev.components?.UserMessage === next.components?.UserMessage && prev.components?.EditComposer === next.components?.EditComposer && prev.components?.AssistantMessage === next.components?.AssistantMessage && prev.components?.SystemMessage === next.components?.SystemMessage
4256
+ (prev, next) => isComponentsSame(prev.components, next.components)
4151
4257
  );
4152
4258
 
4153
4259
  // src/primitives/thread/ThreadScrollToBottom.tsx
@@ -4166,21 +4272,21 @@ var ThreadPrimitiveSuggestion = createActionButton(
4166
4272
  // src/ui/thread-config.tsx
4167
4273
  import {
4168
4274
  createContext as createContext7,
4169
- useContext as useContext7
4275
+ useContext as useContext4
4170
4276
  } from "react";
4171
4277
  import { Fragment as Fragment3, jsx as jsx35 } from "react/jsx-runtime";
4172
4278
  var ThreadConfigContext = createContext7({});
4173
4279
  var useThreadConfig = () => {
4174
- return useContext7(ThreadConfigContext);
4280
+ return useContext4(ThreadConfigContext);
4175
4281
  };
4176
4282
  var ThreadConfigProvider = ({
4177
4283
  children,
4178
4284
  config
4179
4285
  }) => {
4180
- const assistant = useAssistantContext({ optional: true });
4286
+ const hasAssistant = !!useAssistantRuntimeStore({ optional: true });
4181
4287
  const configProvider = config && Object.keys(config ?? {}).length > 0 ? /* @__PURE__ */ jsx35(ThreadConfigContext.Provider, { value: config, children }) : /* @__PURE__ */ jsx35(Fragment3, { children });
4182
4288
  if (!config?.runtime) return configProvider;
4183
- if (assistant) {
4289
+ if (hasAssistant) {
4184
4290
  throw new Error(
4185
4291
  "You provided a runtime to <Thread> while simulataneously using <AssistantRuntimeProvider>. This is not allowed."
4186
4292
  );
@@ -4198,22 +4304,19 @@ import {
4198
4304
  RefreshCwIcon,
4199
4305
  StopCircleIcon
4200
4306
  } from "lucide-react";
4201
- import { Fragment as Fragment4, jsx as jsx36, jsxs as jsxs5 } from "react/jsx-runtime";
4307
+ import { Fragment as Fragment4, jsx as jsx36, jsxs as jsxs4 } from "react/jsx-runtime";
4202
4308
  var useAllowCopy = (ensureCapability = false) => {
4203
4309
  const { assistantMessage: { allowCopy = true } = {} } = useThreadConfig();
4204
- const { useThread } = useThreadContext();
4205
4310
  const copySupported = useThread((t) => t.capabilities.unstable_copy);
4206
4311
  return allowCopy && (!ensureCapability || copySupported);
4207
4312
  };
4208
4313
  var useAllowSpeak = (ensureCapability = false) => {
4209
4314
  const { assistantMessage: { allowSpeak = true } = {} } = useThreadConfig();
4210
- const { useThread } = useThreadContext();
4211
4315
  const speakSupported = useThread((t) => t.capabilities.speak);
4212
4316
  return allowSpeak && (!ensureCapability || speakSupported);
4213
4317
  };
4214
4318
  var useAllowReload = (ensureCapability = false) => {
4215
4319
  const { assistantMessage: { allowReload = true } = {} } = useThreadConfig();
4216
- const { useThread } = useThreadContext();
4217
4320
  const reloadSupported = useThread((t) => t.capabilities.reload);
4218
4321
  return allowReload && (!ensureCapability || reloadSupported);
4219
4322
  };
@@ -4222,7 +4325,7 @@ var AssistantActionBar = () => {
4222
4325
  const allowReload = useAllowReload(true);
4223
4326
  const allowSpeak = useAllowSpeak(true);
4224
4327
  if (!allowCopy && !allowReload && !allowSpeak) return null;
4225
- return /* @__PURE__ */ jsxs5(
4328
+ return /* @__PURE__ */ jsxs4(
4226
4329
  AssistantActionBarRoot,
4227
4330
  {
4228
4331
  hideWhenRunning: true,
@@ -4247,14 +4350,14 @@ var AssistantActionBarCopy = forwardRef19((props, ref) => {
4247
4350
  assistantMessage: { copy: { tooltip = "Copy" } = {} } = {}
4248
4351
  } = {}
4249
4352
  } = useThreadConfig();
4250
- return /* @__PURE__ */ jsx36(actionBar_exports.Copy, { asChild: true, children: /* @__PURE__ */ jsx36(TooltipIconButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsxs5(Fragment4, { children: [
4353
+ return /* @__PURE__ */ jsx36(actionBar_exports.Copy, { asChild: true, children: /* @__PURE__ */ jsx36(TooltipIconButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsxs4(Fragment4, { children: [
4251
4354
  /* @__PURE__ */ jsx36(message_exports.If, { copied: true, children: /* @__PURE__ */ jsx36(CheckIcon, {}) }),
4252
4355
  /* @__PURE__ */ jsx36(message_exports.If, { copied: false, children: /* @__PURE__ */ jsx36(CopyIcon, {}) })
4253
4356
  ] }) }) });
4254
4357
  });
4255
4358
  AssistantActionBarCopy.displayName = "AssistantActionBarCopy";
4256
4359
  var AssistantActionBarSpeechControl = () => {
4257
- return /* @__PURE__ */ jsxs5(Fragment4, { children: [
4360
+ return /* @__PURE__ */ jsxs4(Fragment4, { children: [
4258
4361
  /* @__PURE__ */ jsx36(message_exports.If, { speaking: false, children: /* @__PURE__ */ jsx36(AssistantActionBarSpeak, {}) }),
4259
4362
  /* @__PURE__ */ jsx36(message_exports.If, { speaking: true, children: /* @__PURE__ */ jsx36(AssistantActionBarStopSpeaking, {}) })
4260
4363
  ] });
@@ -4310,17 +4413,16 @@ import { forwardRef as forwardRef21, useMemo as useMemo5 } from "react";
4310
4413
  // src/ui/branch-picker.tsx
4311
4414
  import { forwardRef as forwardRef20 } from "react";
4312
4415
  import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
4313
- import { jsx as jsx37, jsxs as jsxs6 } from "react/jsx-runtime";
4416
+ import { jsx as jsx37, jsxs as jsxs5 } from "react/jsx-runtime";
4314
4417
  var useAllowBranchPicker = (ensureCapability = false) => {
4315
4418
  const { branchPicker: { allowBranchPicker = true } = {} } = useThreadConfig();
4316
- const { useThread } = useThreadContext();
4317
4419
  const branchPickerSupported = useThread((t) => t.capabilities.edit);
4318
4420
  return allowBranchPicker && (!ensureCapability || branchPickerSupported);
4319
4421
  };
4320
4422
  var BranchPicker = () => {
4321
4423
  const allowBranchPicker = useAllowBranchPicker();
4322
4424
  if (!allowBranchPicker) return null;
4323
- return /* @__PURE__ */ jsxs6(BranchPickerRoot, { hideWhenSingleBranch: true, children: [
4425
+ return /* @__PURE__ */ jsxs5(BranchPickerRoot, { hideWhenSingleBranch: true, children: [
4324
4426
  /* @__PURE__ */ jsx37(BranchPickerPrevious2, {}),
4325
4427
  /* @__PURE__ */ jsx37(BranchPickerState, {}),
4326
4428
  /* @__PURE__ */ jsx37(BranchPickerNext, {})
@@ -4345,7 +4447,7 @@ var BranchPickerStateWrapper = withDefaults("span", {
4345
4447
  className: "aui-branch-picker-state"
4346
4448
  });
4347
4449
  var BranchPickerState = forwardRef20((props, ref) => {
4348
- return /* @__PURE__ */ jsxs6(BranchPickerStateWrapper, { ...props, ref, children: [
4450
+ return /* @__PURE__ */ jsxs5(BranchPickerStateWrapper, { ...props, ref, children: [
4349
4451
  /* @__PURE__ */ jsx37(branchPicker_exports.Number, {}),
4350
4452
  " / ",
4351
4453
  /* @__PURE__ */ jsx37(branchPicker_exports.Count, {})
@@ -4369,10 +4471,10 @@ var branch_picker_default = Object.assign(BranchPicker, exports2);
4369
4471
 
4370
4472
  // src/ui/base/avatar.tsx
4371
4473
  import * as AvatarPrimitive from "@radix-ui/react-avatar";
4372
- import { jsx as jsx38, jsxs as jsxs7 } from "react/jsx-runtime";
4474
+ import { jsx as jsx38, jsxs as jsxs6 } from "react/jsx-runtime";
4373
4475
  var Avatar = ({ src, alt, fallback }) => {
4374
4476
  if (src == null && fallback == null) return null;
4375
- return /* @__PURE__ */ jsxs7(AvatarRoot, { children: [
4477
+ return /* @__PURE__ */ jsxs6(AvatarRoot, { children: [
4376
4478
  src != null && /* @__PURE__ */ jsx38(AvatarImage, { src, alt }),
4377
4479
  fallback != null && /* @__PURE__ */ jsx38(AvatarFallback, { children: fallback })
4378
4480
  ] });
@@ -4411,9 +4513,9 @@ var exports3 = { Text: withSmoothContextProvider(Text) };
4411
4513
  var content_part_default = exports3;
4412
4514
 
4413
4515
  // src/ui/assistant-message.tsx
4414
- import { jsx as jsx40, jsxs as jsxs8 } from "react/jsx-runtime";
4516
+ import { jsx as jsx40, jsxs as jsxs7 } from "react/jsx-runtime";
4415
4517
  var AssistantMessage = () => {
4416
- return /* @__PURE__ */ jsxs8(AssistantMessageRoot, { children: [
4518
+ return /* @__PURE__ */ jsxs7(AssistantMessageRoot, { children: [
4417
4519
  /* @__PURE__ */ jsx40(AssistantMessageAvatar, {}),
4418
4520
  /* @__PURE__ */ jsx40(AssistantMessageContent, {}),
4419
4521
  /* @__PURE__ */ jsx40(branch_picker_default, {}),
@@ -4501,15 +4603,14 @@ CircleStopIcon.displayName = "CircleStopIcon";
4501
4603
  // src/ui/composer-attachment.tsx
4502
4604
  import { forwardRef as forwardRef22 } from "react";
4503
4605
  import { CircleXIcon } from "lucide-react";
4504
- import { jsx as jsx42, jsxs as jsxs9 } from "react/jsx-runtime";
4606
+ import { jsx as jsx42, jsxs as jsxs8 } from "react/jsx-runtime";
4505
4607
  var ComposerAttachmentRoot = withDefaults("div", {
4506
4608
  className: "aui-composer-attachment-root"
4507
4609
  });
4508
4610
  ComposerAttachmentRoot.displayName = "ComposerAttachmentRoot";
4509
4611
  var ComposerAttachment2 = () => {
4510
- const { useAttachment } = useAttachmentContext({ type: "composer" });
4511
- const attachment = useAttachment((a) => a.attachment);
4512
- return /* @__PURE__ */ jsxs9(ComposerAttachmentRoot, { children: [
4612
+ const attachment = useComposerAttachment((a) => a.attachment);
4613
+ return /* @__PURE__ */ jsxs8(ComposerAttachmentRoot, { children: [
4513
4614
  ".",
4514
4615
  attachment.name.split(".").pop(),
4515
4616
  /* @__PURE__ */ jsx42(ComposerAttachmentRemove, {})
@@ -4522,10 +4623,10 @@ var ComposerAttachmentRemove = forwardRef22((props, ref) => {
4522
4623
  composer: { removeAttachment: { tooltip = "Remove file" } = {} } = {}
4523
4624
  } = {}
4524
4625
  } = useThreadConfig();
4525
- const { useComposer } = useThreadContext();
4526
- const { useAttachment } = useAttachmentContext();
4626
+ const composerStore = useThreadComposerStore();
4627
+ const attachmentStore = useAttachmentStore();
4527
4628
  const handleRemoveAttachment = () => {
4528
- useComposer.getState().removeAttachment(useAttachment.getState().attachment.id);
4629
+ composerStore.getState().removeAttachment(attachmentStore.getState().attachment.id);
4529
4630
  };
4530
4631
  return /* @__PURE__ */ jsx42(
4531
4632
  TooltipIconButton,
@@ -4551,16 +4652,15 @@ var composer_attachment_default = Object.assign(
4551
4652
  );
4552
4653
 
4553
4654
  // src/ui/composer.tsx
4554
- import { Fragment as Fragment5, jsx as jsx43, jsxs as jsxs10 } from "react/jsx-runtime";
4655
+ import { Fragment as Fragment5, jsx as jsx43, jsxs as jsxs9 } from "react/jsx-runtime";
4555
4656
  var useAllowAttachments = (ensureCapability = false) => {
4556
4657
  const { composer: { allowAttachments = true } = {} } = useThreadConfig();
4557
- const { useThread } = useThreadContext();
4558
4658
  const attachmentsSupported = useThread((t) => t.capabilities.attachments);
4559
4659
  return allowAttachments && (!ensureCapability || attachmentsSupported);
4560
4660
  };
4561
4661
  var Composer = () => {
4562
4662
  const allowAttachments = useAllowAttachments(true);
4563
- return /* @__PURE__ */ jsxs10(ComposerRoot, { children: [
4663
+ return /* @__PURE__ */ jsxs9(ComposerRoot, { children: [
4564
4664
  allowAttachments && /* @__PURE__ */ jsx43(ComposerAttachments, {}),
4565
4665
  allowAttachments && /* @__PURE__ */ jsx43(ComposerAddAttachment, {}),
4566
4666
  /* @__PURE__ */ jsx43(ComposerInput, { autoFocus: true }),
@@ -4626,14 +4726,13 @@ var ComposerAddAttachment = forwardRef23((props, ref) => {
4626
4726
  });
4627
4727
  ComposerAddAttachment.displayName = "ComposerAddAttachment";
4628
4728
  var useAllowCancel = () => {
4629
- const { useThread } = useThreadContext();
4630
4729
  const cancelSupported = useThread((t) => t.capabilities.cancel);
4631
4730
  return cancelSupported;
4632
4731
  };
4633
4732
  var ComposerAction = () => {
4634
4733
  const allowCancel = useAllowCancel();
4635
4734
  if (!allowCancel) return /* @__PURE__ */ jsx43(ComposerSend, {});
4636
- return /* @__PURE__ */ jsxs10(Fragment5, { children: [
4735
+ return /* @__PURE__ */ jsxs9(Fragment5, { children: [
4637
4736
  /* @__PURE__ */ jsx43(thread_exports.If, { running: false, children: /* @__PURE__ */ jsx43(ComposerSend, {}) }),
4638
4737
  /* @__PURE__ */ jsx43(thread_exports.If, { running: true, children: /* @__PURE__ */ jsx43(ComposerCancel, {}) })
4639
4738
  ] });
@@ -4674,10 +4773,10 @@ var composer_default = Object.assign(Composer, exports6);
4674
4773
 
4675
4774
  // src/ui/thread-welcome.tsx
4676
4775
  import { forwardRef as forwardRef24 } from "react";
4677
- import { jsx as jsx44, jsxs as jsxs11 } from "react/jsx-runtime";
4776
+ import { jsx as jsx44, jsxs as jsxs10 } from "react/jsx-runtime";
4678
4777
  var ThreadWelcome = () => {
4679
- return /* @__PURE__ */ jsxs11(ThreadWelcomeRoot, { children: [
4680
- /* @__PURE__ */ jsxs11(ThreadWelcomeCenter, { children: [
4778
+ return /* @__PURE__ */ jsxs10(ThreadWelcomeRoot, { children: [
4779
+ /* @__PURE__ */ jsxs10(ThreadWelcomeCenter, { children: [
4681
4780
  /* @__PURE__ */ jsx44(ThreadWelcomeAvatar, {}),
4682
4781
  /* @__PURE__ */ jsx44(ThreadWelcomeMessage, {})
4683
4782
  ] }),
@@ -4755,7 +4854,6 @@ import { PencilIcon } from "lucide-react";
4755
4854
  import { jsx as jsx45 } from "react/jsx-runtime";
4756
4855
  var useAllowEdit = (ensureCapability = false) => {
4757
4856
  const { userMessage: { allowEdit = true } = {} } = useThreadConfig();
4758
- const { useThread } = useThreadContext();
4759
4857
  const editSupported = useThread((t) => t.capabilities.edit);
4760
4858
  return allowEdit && (!ensureCapability || editSupported);
4761
4859
  };
@@ -4784,15 +4882,14 @@ var exports8 = {
4784
4882
  var user_action_bar_default = Object.assign(UserActionBar, exports8);
4785
4883
 
4786
4884
  // src/ui/user-message-attachment.tsx
4787
- import { jsxs as jsxs12 } from "react/jsx-runtime";
4885
+ import { jsxs as jsxs11 } from "react/jsx-runtime";
4788
4886
  var UserMessageAttachmentRoot = withDefaults("div", {
4789
4887
  className: "aui-user-message-attachment-root"
4790
4888
  });
4791
4889
  UserMessageAttachmentRoot.displayName = "UserMessageAttachmentRoot";
4792
4890
  var UserMessageAttachment = () => {
4793
- const { useAttachment } = useAttachmentContext();
4794
4891
  const attachment = useAttachment((a) => a.attachment);
4795
- return /* @__PURE__ */ jsxs12(UserMessageAttachmentRoot, { children: [
4892
+ return /* @__PURE__ */ jsxs11(UserMessageAttachmentRoot, { children: [
4796
4893
  ".",
4797
4894
  attachment.name.split(".").pop()
4798
4895
  ] });
@@ -4807,9 +4904,9 @@ var user_message_attachment_default = Object.assign(
4807
4904
  );
4808
4905
 
4809
4906
  // src/ui/user-message.tsx
4810
- import { jsx as jsx46, jsxs as jsxs13 } from "react/jsx-runtime";
4907
+ import { jsx as jsx46, jsxs as jsxs12 } from "react/jsx-runtime";
4811
4908
  var UserMessage = () => {
4812
- return /* @__PURE__ */ jsxs13(UserMessageRoot, { children: [
4909
+ return /* @__PURE__ */ jsxs12(UserMessageRoot, { children: [
4813
4910
  /* @__PURE__ */ jsx46(UserMessageAttachments, {}),
4814
4911
  /* @__PURE__ */ jsx46(user_action_bar_default, {}),
4815
4912
  /* @__PURE__ */ jsx46(UserMessageContent, {}),
@@ -4863,11 +4960,11 @@ var user_message_default = Object.assign(UserMessage, exports10);
4863
4960
 
4864
4961
  // src/ui/edit-composer.tsx
4865
4962
  import { forwardRef as forwardRef27 } from "react";
4866
- import { jsx as jsx47, jsxs as jsxs14 } from "react/jsx-runtime";
4963
+ import { jsx as jsx47, jsxs as jsxs13 } from "react/jsx-runtime";
4867
4964
  var EditComposer = () => {
4868
- return /* @__PURE__ */ jsxs14(EditComposerRoot, { children: [
4965
+ return /* @__PURE__ */ jsxs13(EditComposerRoot, { children: [
4869
4966
  /* @__PURE__ */ jsx47(EditComposerInput, {}),
4870
- /* @__PURE__ */ jsxs14(EditComposerFooter, { children: [
4967
+ /* @__PURE__ */ jsxs13(EditComposerFooter, { children: [
4871
4968
  /* @__PURE__ */ jsx47(EditComposerCancel, {}),
4872
4969
  /* @__PURE__ */ jsx47(EditComposerSend, {})
4873
4970
  ] })
@@ -4916,12 +5013,12 @@ var exports11 = {
4916
5013
  var edit_composer_default = Object.assign(EditComposer, exports11);
4917
5014
 
4918
5015
  // src/ui/thread.tsx
4919
- import { jsx as jsx48, jsxs as jsxs15 } from "react/jsx-runtime";
5016
+ import { jsx as jsx48, jsxs as jsxs14 } from "react/jsx-runtime";
4920
5017
  var Thread = (config) => {
4921
- return /* @__PURE__ */ jsx48(ThreadRoot, { config, children: /* @__PURE__ */ jsxs15(ThreadViewport, { children: [
5018
+ return /* @__PURE__ */ jsx48(ThreadRoot, { config, children: /* @__PURE__ */ jsxs14(ThreadViewport, { children: [
4922
5019
  /* @__PURE__ */ jsx48(thread_welcome_default, {}),
4923
5020
  /* @__PURE__ */ jsx48(ThreadMessages, {}),
4924
- /* @__PURE__ */ jsxs15(ThreadViewportFooter, { children: [
5021
+ /* @__PURE__ */ jsxs14(ThreadViewportFooter, { children: [
4925
5022
  /* @__PURE__ */ jsx48(ThreadScrollToBottom, {}),
4926
5023
  /* @__PURE__ */ jsx48(composer_default, {})
4927
5024
  ] })
@@ -4983,9 +5080,9 @@ var exports12 = {
4983
5080
  var thread_default = Object.assign(Thread, exports12);
4984
5081
 
4985
5082
  // src/ui/assistant-modal.tsx
4986
- import { Fragment as Fragment6, jsx as jsx49, jsxs as jsxs16 } from "react/jsx-runtime";
5083
+ import { Fragment as Fragment6, jsx as jsx49, jsxs as jsxs15 } from "react/jsx-runtime";
4987
5084
  var AssistantModal = (config) => {
4988
- return /* @__PURE__ */ jsxs16(AssistantModalRoot, { config, children: [
5085
+ return /* @__PURE__ */ jsxs15(AssistantModalRoot, { config, children: [
4989
5086
  /* @__PURE__ */ jsx49(AssistantModalTrigger, {}),
4990
5087
  /* @__PURE__ */ jsx49(AssistantModalContent, { children: /* @__PURE__ */ jsx49(thread_default, {}) })
4991
5088
  ] });
@@ -5029,7 +5126,7 @@ var AssistantModalButton = forwardRef29(({ "data-state": state, ...rest }, ref)
5029
5126
  "data-state": state,
5030
5127
  ...rest,
5031
5128
  ref,
5032
- children: rest.children ?? /* @__PURE__ */ jsxs16(Fragment6, { children: [
5129
+ children: rest.children ?? /* @__PURE__ */ jsxs15(Fragment6, { children: [
5033
5130
  /* @__PURE__ */ jsx49(
5034
5131
  BotIcon,
5035
5132
  {
@@ -5112,36 +5209,64 @@ export {
5112
5209
  useActionBarSpeak,
5113
5210
  useActionBarStopSpeaking,
5114
5211
  useAppendMessage,
5212
+ useAssistantActions,
5213
+ useAssistantActionsStore,
5115
5214
  useAssistantContext,
5116
5215
  useAssistantInstructions,
5216
+ useAssistantRuntime,
5217
+ useAssistantRuntimeStore,
5117
5218
  useAssistantTool,
5118
5219
  useAssistantToolUI,
5119
5220
  useBranchPickerCount,
5120
5221
  useBranchPickerNext,
5121
5222
  useBranchPickerNumber,
5122
5223
  useBranchPickerPrevious,
5224
+ useComposer,
5123
5225
  useComposerAddAttachment,
5124
5226
  useComposerCancel,
5125
5227
  useComposerContext,
5126
5228
  useComposerIf,
5127
5229
  useComposerSend,
5230
+ useComposerStore,
5231
+ useContentPart,
5128
5232
  useContentPartContext,
5129
5233
  useContentPartDisplay,
5130
5234
  useContentPartImage,
5235
+ useContentPartStore,
5131
5236
  useContentPartText,
5132
5237
  useDangerousInBrowserRuntime,
5133
5238
  useEdgeRuntime,
5239
+ useEditComposer,
5240
+ useEditComposerStore,
5134
5241
  useExternalMessageConverter,
5135
5242
  useExternalStoreRuntime,
5136
5243
  useLocalRuntime,
5244
+ useMessage,
5137
5245
  useMessageContext,
5138
5246
  useMessageIf,
5247
+ useMessageStore,
5248
+ useMessageUtils,
5249
+ useMessageUtilsStore,
5139
5250
  useSwitchToNewThread,
5251
+ useThread,
5252
+ useThreadActions,
5253
+ useThreadActionsStore,
5254
+ useThreadComposer,
5255
+ useThreadComposerStore,
5140
5256
  useThreadConfig,
5141
5257
  useThreadContext,
5142
5258
  useThreadEmpty,
5143
5259
  useThreadIf,
5260
+ useThreadMessages,
5261
+ useThreadMessagesStore,
5262
+ useThreadRuntime,
5263
+ useThreadRuntimeStore,
5144
5264
  useThreadScrollToBottom,
5145
- useThreadSuggestion
5265
+ useThreadStore,
5266
+ useThreadSuggestion,
5267
+ useThreadViewport,
5268
+ useThreadViewportStore,
5269
+ useToolUIs,
5270
+ useToolUIsStore
5146
5271
  };
5147
5272
  //# sourceMappingURL=index.mjs.map