@assistant-ui/react 0.5.52 → 0.5.55

Sign up to get free protection for your applications and to get access to all the features.
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