@assistant-ui/react 0.5.66 → 0.5.68

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.mjs CHANGED
@@ -145,7 +145,9 @@ var { useThread, useThreadStore } = createContextStoreHook(
145
145
  useThreadContext,
146
146
  "useThread"
147
147
  );
148
- var { useThreadMessages, useThreadMessagesStore } = createContextStoreHook(useThreadContext, "useThreadMessages");
148
+ var messages = createContextStoreHook(useThreadContext, "useThreadMessages");
149
+ var useThreadMessages = messages.useThreadMessages;
150
+ var useThreadMessagesStore = messages.useThreadMessagesStore;
149
151
  var {
150
152
  useComposer: useThreadComposer,
151
153
  useComposerStore: useThreadComposerStore
@@ -155,61 +157,11 @@ var {
155
157
  useViewportStore: useThreadViewportStore
156
158
  } = createContextStoreHook(useThreadContext, "useViewport");
157
159
 
158
- // src/context/stores/ThreadComposer.ts
159
- import { create as create2 } from "zustand";
160
- var makeThreadComposerStore = (runtime) => {
161
- const focusListeners = /* @__PURE__ */ new Set();
162
- return create2()((_, get) => {
163
- return {
164
- type: "thread",
165
- get value() {
166
- return get().text;
167
- },
168
- setValue(value) {
169
- get().setText(value);
170
- },
171
- ...runtime.getState(),
172
- canCancel: false,
173
- // "TODO",
174
- isEditing: true,
175
- addAttachment: (file) => {
176
- runtime.addAttachment(file);
177
- },
178
- removeAttachment: (attachmentId) => {
179
- runtime.removeAttachment(attachmentId);
180
- },
181
- reset: () => {
182
- runtime.reset();
183
- },
184
- setText: (text) => {
185
- runtime.setText(text);
186
- },
187
- send: () => {
188
- runtime.send();
189
- },
190
- cancel: () => {
191
- runtime.cancel();
192
- },
193
- focus: () => {
194
- for (const listener of focusListeners) {
195
- listener();
196
- }
197
- },
198
- onFocus: (listener) => {
199
- focusListeners.add(listener);
200
- return () => {
201
- focusListeners.delete(listener);
202
- };
203
- }
204
- };
205
- });
206
- };
207
-
208
160
  // src/context/stores/ThreadViewport.tsx
209
- import { create as create3 } from "zustand";
161
+ import { create as create2 } from "zustand";
210
162
  var makeThreadViewportStore = () => {
211
163
  const scrollToBottomListeners = /* @__PURE__ */ new Set();
212
- return create3(() => ({
164
+ return create2(() => ({
213
165
  isAtBottom: true,
214
166
  scrollToBottom: () => {
215
167
  for (const listener of scrollToBottomListeners) {
@@ -231,17 +183,17 @@ var writableStore = (store) => {
231
183
  };
232
184
 
233
185
  // src/context/providers/ThreadRuntimeProvider.tsx
234
- import { create as create4 } from "zustand";
235
- import { jsx, jsxs } from "react/jsx-runtime";
186
+ import { create as create3 } from "zustand";
187
+ import { jsx } from "react/jsx-runtime";
236
188
  var useThreadRuntimeStore2 = (runtime) => {
237
- const [store] = useState(() => create4(() => runtime));
189
+ const [store] = useState(() => create3(() => runtime));
238
190
  useEffect(() => {
239
191
  writableStore(store).setState(runtime, true);
240
192
  }, [runtime, store]);
241
193
  return store;
242
194
  };
243
195
  var useThreadStore2 = (runtime) => {
244
- const [store] = useState(() => create4(() => runtime.getState()));
196
+ const [store] = useState(() => create3(() => runtime.getState()));
245
197
  useEffect(() => {
246
198
  const updateState = () => writableStore(store).setState(runtime.getState(), true);
247
199
  updateState();
@@ -250,7 +202,7 @@ var useThreadStore2 = (runtime) => {
250
202
  return store;
251
203
  };
252
204
  var useThreadMessagesStore2 = (runtime) => {
253
- const [store] = useState(() => create4(() => runtime.messages));
205
+ const [store] = useState(() => create3(() => runtime.messages));
254
206
  useEffect(() => {
255
207
  const updateState = () => writableStore(store).setState(runtime.messages, true);
256
208
  updateState();
@@ -259,9 +211,9 @@ var useThreadMessagesStore2 = (runtime) => {
259
211
  return store;
260
212
  };
261
213
  var useThreadComposerStore2 = (runtime) => {
262
- const [store] = useState(() => makeThreadComposerStore(runtime));
214
+ const [store] = useState(() => create3(() => runtime.getState()));
263
215
  useEffect(() => {
264
- const updateState = () => writableStore(store).setState(runtime.getState());
216
+ const updateState = () => writableStore(store).setState(runtime.getState(), true);
265
217
  updateState();
266
218
  return runtime.subscribe(updateState);
267
219
  }, [runtime, store]);
@@ -283,20 +235,14 @@ var ThreadRuntimeProvider = ({ children, runtime }) => {
283
235
  useViewport
284
236
  };
285
237
  }, [useThread2, useThreadRuntime2, useThreadMessages2, useThreadComposer2]);
286
- const Synchronizer = context.useThread(
287
- (t) => t.unstable_synchronizer
288
- );
289
- return /* @__PURE__ */ jsxs(ThreadContext.Provider, { value: context, children: [
290
- Synchronizer && /* @__PURE__ */ jsx(Synchronizer, {}),
291
- children
292
- ] });
238
+ return /* @__PURE__ */ jsx(ThreadContext.Provider, { value: context, children });
293
239
  };
294
240
 
295
241
  // src/context/providers/AssistantRuntimeProvider.tsx
296
- import { create as create5 } from "zustand";
242
+ import { create as create4 } from "zustand";
297
243
  import { jsx as jsx2 } from "react/jsx-runtime";
298
244
  var useAssistantRuntimeStore2 = (runtime) => {
299
- const [store] = useState2(() => create5(() => runtime));
245
+ const [store] = useState2(() => create4(() => runtime));
300
246
  useEffect2(() => {
301
247
  writableStore(store).setState(runtime, true);
302
248
  }, [runtime, store]);
@@ -321,7 +267,7 @@ var AssistantRuntimeProvider = memo(AssistantRuntimeProviderImpl);
321
267
 
322
268
  // src/context/providers/TextContentPartProvider.tsx
323
269
  import { useEffect as useEffect3, useState as useState3 } from "react";
324
- import { create as create6 } from "zustand";
270
+ import { create as create5 } from "zustand";
325
271
 
326
272
  // src/context/react/ContentPartContext.ts
327
273
  import { createContext as createContext3 } from "react";
@@ -332,11 +278,47 @@ var useContentPartContext = createContextHook(
332
278
  ContentPartContext,
333
279
  "a component passed to <MessagePrimitive.Content components={...}>"
334
280
  );
281
+ function useContentPartRuntime(options) {
282
+ const context = useContentPartContext(options);
283
+ if (!context) return null;
284
+ return context.useContentPartRuntime();
285
+ }
335
286
  var { useContentPart, useContentPartStore } = createContextStoreHook(
336
287
  useContentPartContext,
337
288
  "useContentPart"
338
289
  );
339
290
 
291
+ // src/api/ContentPartRuntime.ts
292
+ var ContentPartRuntime = class {
293
+ constructor(contentBinding, messageApi, threadApi) {
294
+ this.contentBinding = contentBinding;
295
+ this.messageApi = messageApi;
296
+ this.threadApi = threadApi;
297
+ }
298
+ getState() {
299
+ return this.contentBinding.getState();
300
+ }
301
+ addToolResult(result) {
302
+ const message = this.messageApi.getState();
303
+ if (!message) throw new Error("Message is not available");
304
+ const state = this.contentBinding.getState();
305
+ if (!state) throw new Error("Content part is not available");
306
+ if (state.type !== "tool-call")
307
+ throw new Error("Tried to add tool result to non-tool content part");
308
+ const toolName = state.toolName;
309
+ const toolCallId = state.toolCallId;
310
+ this.threadApi.getState().addToolResult({
311
+ messageId: message.id,
312
+ toolName,
313
+ toolCallId,
314
+ result
315
+ });
316
+ }
317
+ subscribe(callback) {
318
+ return this.contentBinding.subscribe(callback);
319
+ }
320
+ };
321
+
340
322
  // src/context/providers/TextContentPartProvider.tsx
341
323
  import { jsx as jsx3 } from "react/jsx-runtime";
342
324
  var COMPLETE_STATUS = {
@@ -347,18 +329,22 @@ var RUNNING_STATUS = {
347
329
  };
348
330
  var TextContentPartProvider = ({ children, text, isRunning }) => {
349
331
  const [context] = useState3(() => {
350
- const useContentPart2 = create6(() => ({
332
+ const useContentPartRuntime2 = create5(
333
+ // TODO
334
+ () => new ContentPartRuntime(null, null, null)
335
+ );
336
+ const useContentPart2 = create5(() => ({
351
337
  status: isRunning ? RUNNING_STATUS : COMPLETE_STATUS,
352
- part: { type: "text", text }
338
+ part: { type: "text", text },
339
+ type: "text",
340
+ text
353
341
  }));
354
- return {
355
- useContentPart: useContentPart2
356
- };
342
+ return { useContentPartRuntime: useContentPartRuntime2, useContentPart: useContentPart2 };
357
343
  });
358
344
  useEffect3(() => {
359
345
  const state = context.useContentPart.getState();
360
- const textUpdated = state.part.text !== text;
361
- const targetTextPart = textUpdated ? { type: "text", text } : state.part;
346
+ const textUpdated = state.text !== text;
347
+ const targetTextPart = textUpdated ? { type: "text", text } : state;
362
348
  const targetStatus = isRunning ? RUNNING_STATUS : COMPLETE_STATUS;
363
349
  const statusUpdated = state.status !== targetStatus;
364
350
  if (!textUpdated && !statusUpdated) return;
@@ -401,20 +387,25 @@ var { useEditComposer, useEditComposerStore } = createContextStoreHook(
401
387
  // src/context/react/ComposerContext.ts
402
388
  import { useMemo as useMemo3 } from "react";
403
389
  var useComposerContext = () => {
404
- const { useComposer: useComposer2 } = useThreadContext();
390
+ const { useComposer: useThreadComposer2 } = useThreadContext();
405
391
  const { useEditComposer: useEditComposer2 } = useMessageContext({ optional: true }) ?? {};
406
392
  return useMemo3(
407
393
  () => ({
408
- useComposer: useEditComposer2 ?? useComposer2,
394
+ useComposer: useEditComposer2 ?? useThreadComposer2,
409
395
  type: useEditComposer2 ? "edit" : "new"
410
396
  }),
411
- [useEditComposer2, useComposer2]
397
+ [useEditComposer2, useThreadComposer2]
412
398
  );
413
399
  };
414
400
  var { useComposer, useComposerStore } = createContextStoreHook(
415
401
  useComposerContext,
416
402
  "useComposer"
417
403
  );
404
+ function useComposerRuntime(options) {
405
+ const messageRuntime = useMessageRuntime({ optional: true });
406
+ const threadRuntime = useThreadRuntime(options);
407
+ return messageRuntime ? messageRuntime.composer : threadRuntime?.composer ?? null;
408
+ }
418
409
 
419
410
  // src/hooks/useAppendMessage.tsx
420
411
  import { useCallback } from "react";
@@ -580,12 +571,11 @@ var useActionBarCopy = ({
580
571
  // src/primitive-hooks/actionBar/useActionBarEdit.tsx
581
572
  import { useCallback as useCallback4 } from "react";
582
573
  var useActionBarEdit = () => {
583
- const editComposerStore = useEditComposerStore();
574
+ const messageRuntime = useMessageRuntime();
584
575
  const disabled = useEditComposer((c) => c.isEditing);
585
576
  const callback = useCallback4(() => {
586
- const { edit } = editComposerStore.getState();
587
- edit();
588
- }, [editComposerStore]);
577
+ messageRuntime.composer.beginEdit();
578
+ }, [messageRuntime]);
589
579
  if (disabled) return null;
590
580
  return callback;
591
581
  };
@@ -595,7 +585,7 @@ import { useCallback as useCallback5 } from "react";
595
585
  var useActionBarReload = () => {
596
586
  const messageStore = useMessageStore();
597
587
  const threadStore = useThreadStore();
598
- const threadRuntime = useThreadRuntime();
588
+ const messageRuntime = useMessageRuntime();
599
589
  const threadComposerStore = useThreadComposerStore();
600
590
  const threadViewportStore = useThreadViewportStore();
601
591
  const disabled = useCombinedStore(
@@ -603,11 +593,10 @@ var useActionBarReload = () => {
603
593
  (t, m) => t.isRunning || t.isDisabled || m.role !== "assistant"
604
594
  );
605
595
  const callback = useCallback5(() => {
606
- const { parentId } = messageStore.getState();
607
- threadRuntime.startRun(parentId);
596
+ messageRuntime.reload();
608
597
  threadViewportStore.getState().scrollToBottom();
609
598
  threadComposerStore.getState().focus();
610
- }, [threadRuntime, threadComposerStore, threadViewportStore, messageStore]);
599
+ }, [messageRuntime, threadComposerStore, threadViewportStore]);
611
600
  if (disabled) return null;
612
601
  return callback;
613
602
  };
@@ -617,19 +606,18 @@ import { useCallback as useCallback6 } from "react";
617
606
  var useActionBarSpeak = () => {
618
607
  const messageStore = useMessageStore();
619
608
  const editComposerStore = useEditComposerStore();
620
- const threadRuntime = useThreadRuntime();
609
+ const messageRunime = useMessageRuntime();
621
610
  const messageUtilsStore = useMessageUtilsStore();
622
611
  const hasSpeakableContent = useCombinedStore(
623
612
  [messageStore, editComposerStore],
624
- ({ message }, c) => {
613
+ (message, c) => {
625
614
  return !c.isEditing && (message.role !== "assistant" || message.status.type !== "running") && message.content.some((c2) => c2.type === "text" && c2.text.length > 0);
626
615
  }
627
616
  );
628
617
  const callback = useCallback6(async () => {
629
- const { message } = messageStore.getState();
630
- const utt = threadRuntime.speak(message.id);
618
+ const utt = messageRunime.speak();
631
619
  messageUtilsStore.getState().addUtterance(utt);
632
- }, [threadRuntime, messageStore, messageUtilsStore]);
620
+ }, [messageRunime, messageUtilsStore]);
633
621
  if (!hasSpeakableContent) return null;
634
622
  return callback;
635
623
  };
@@ -649,32 +637,28 @@ var useActionBarStopSpeaking = () => {
649
637
  // src/primitive-hooks/actionBar/useActionBarFeedbackPositive.tsx
650
638
  import { useCallback as useCallback8 } from "react";
651
639
  var useActionBarFeedbackPositive = () => {
652
- const threadRuntime = useThreadRuntime();
653
- const messageStore = useMessageStore();
640
+ const messageRuntime = useMessageRuntime();
654
641
  const messageUtilsStore = useMessageUtilsStore();
655
642
  const callback = useCallback8(() => {
656
- threadRuntime.submitFeedback({
657
- messageId: messageStore.getState().id,
643
+ messageRuntime.submitFeedback({
658
644
  type: "positive"
659
645
  });
660
646
  messageUtilsStore.getState().setSubmittedFeedback("positive");
661
- }, [messageStore, messageUtilsStore, threadRuntime]);
647
+ }, [messageUtilsStore, messageRuntime]);
662
648
  return callback;
663
649
  };
664
650
 
665
651
  // src/primitive-hooks/actionBar/useActionBarFeedbackNegative.tsx
666
652
  import { useCallback as useCallback9 } from "react";
667
653
  var useActionBarFeedbackNegative = () => {
668
- const threadRuntime = useThreadRuntime();
669
- const messageStore = useMessageStore();
654
+ const messageRuntime = useMessageRuntime();
670
655
  const messageUtilsStore = useMessageUtilsStore();
671
656
  const callback = useCallback9(() => {
672
- threadRuntime.submitFeedback({
673
- messageId: messageStore.getState().id,
657
+ messageRuntime.submitFeedback({
674
658
  type: "negative"
675
659
  });
676
660
  messageUtilsStore.getState().setSubmittedFeedback("negative");
677
- }, [messageStore, messageUtilsStore, threadRuntime]);
661
+ }, [messageUtilsStore, messageRuntime]);
678
662
  return callback;
679
663
  };
680
664
 
@@ -796,7 +780,7 @@ var useComposerAddAttachment = () => {
796
780
  // src/primitive-hooks/contentPart/useContentPartDisplay.tsx
797
781
  var useContentPartDisplay = () => {
798
782
  const display = useContentPart((c) => {
799
- if (c.part.type !== "ui")
783
+ if (c.type !== "ui")
800
784
  throw new Error(
801
785
  "This component can only be used inside ui content parts."
802
786
  );
@@ -808,7 +792,7 @@ var useContentPartDisplay = () => {
808
792
  // src/primitive-hooks/contentPart/useContentPartImage.tsx
809
793
  var useContentPartImage = () => {
810
794
  const image = useContentPart((c) => {
811
- if (c.part.type !== "image")
795
+ if (c.type !== "image")
812
796
  throw new Error(
813
797
  "ContentPartImage can only be used inside image content parts."
814
798
  );
@@ -820,7 +804,7 @@ var useContentPartImage = () => {
820
804
  // src/primitive-hooks/contentPart/useContentPartText.tsx
821
805
  var useContentPartText = () => {
822
806
  const text = useContentPart((c) => {
823
- if (c.part.type !== "text")
807
+ if (c.type !== "text")
824
808
  throw new Error(
825
809
  "ContentPartText can only be used inside text content parts."
826
810
  );
@@ -858,20 +842,15 @@ var useMessageIf = (props) => {
858
842
 
859
843
  // src/primitive-hooks/thread/useThreadIf.tsx
860
844
  var useThreadIf = (props) => {
861
- const threadStore = useThreadStore();
862
- const threadMessagesStore = useThreadMessagesStore();
863
- return useCombinedStore(
864
- [threadStore, threadMessagesStore],
865
- (thread, messages) => {
866
- if (props.empty === true && messages.length !== 0) return false;
867
- if (props.empty === false && messages.length === 0) return false;
868
- if (props.running === true && !thread.isRunning) return false;
869
- if (props.running === false && thread.isRunning) return false;
870
- if (props.disabled === true && thread.isDisabled) return false;
871
- if (props.disabled === false && thread.isDisabled) return false;
872
- return true;
873
- }
874
- );
845
+ return useThread((thread) => {
846
+ if (props.empty === true && thread.messages.length !== 0) return false;
847
+ if (props.empty === false && thread.messages.length === 0) return false;
848
+ if (props.running === true && !thread.isRunning) return false;
849
+ if (props.running === false && thread.isRunning) return false;
850
+ if (props.disabled === true && thread.isDisabled) return false;
851
+ if (props.disabled === false && thread.isDisabled) return false;
852
+ return true;
853
+ });
875
854
  };
876
855
 
877
856
  // src/primitive-hooks/thread/useThreadEmpty.tsx
@@ -1380,76 +1359,37 @@ var MessagePrimitiveIf = ({
1380
1359
  MessagePrimitiveIf.displayName = "MessagePrimitive.If";
1381
1360
 
1382
1361
  // src/primitives/message/MessageContent.tsx
1383
- import { memo as memo2 } from "react";
1362
+ import { memo as memo2, useMemo as useMemo6 } from "react";
1384
1363
 
1385
- // src/context/providers/ContentPartProvider.tsx
1364
+ // src/context/providers/ContentPartRuntimeProvider.tsx
1386
1365
  import { useEffect as useEffect8, useState as useState5 } from "react";
1387
- import { create as create7 } from "zustand";
1366
+ import { create as create6 } from "zustand";
1388
1367
  import { jsx as jsx17 } from "react/jsx-runtime";
1389
- var COMPLETE_STATUS2 = {
1390
- type: "complete"
1391
- };
1392
- var toContentPartStatus = (message, partIndex, part) => {
1393
- if (message.role !== "assistant") return COMPLETE_STATUS2;
1394
- const isLastPart = partIndex === Math.max(0, message.content.length - 1);
1395
- if (part.type !== "tool-call") {
1396
- if ("reason" in message.status && message.status.reason === "tool-calls" && isLastPart)
1397
- throw new Error(
1398
- "Encountered unexpected requires-action status. This is likely an internal bug in assistant-ui."
1399
- );
1400
- return isLastPart ? message.status : COMPLETE_STATUS2;
1401
- }
1402
- if (!!part.result) {
1403
- return COMPLETE_STATUS2;
1404
- }
1405
- return message.status;
1406
- };
1407
- var EMPTY_CONTENT = Object.freeze({ type: "text", text: "" });
1408
- var getContentPartState = ({ message }, useContentPart2, partIndex) => {
1409
- let part = message.content[partIndex];
1410
- if (!part) {
1411
- if (message.content.length === 0 && partIndex === 0) {
1412
- part = EMPTY_CONTENT;
1413
- } else {
1414
- return null;
1415
- }
1416
- } else if (message.content.length === 1 && part.type === "text" && part.text.length === 0) {
1417
- part = EMPTY_CONTENT;
1418
- }
1419
- const status = toContentPartStatus(message, partIndex, part);
1420
- const currentState = useContentPart2?.getState();
1421
- if (currentState && currentState.part === part && currentState.status === status)
1422
- return null;
1423
- return Object.freeze({ part, status });
1368
+ var useContentPartRuntimeStore = (runtime) => {
1369
+ const [store] = useState5(() => create6(() => runtime));
1370
+ useEffect8(() => {
1371
+ writableStore(store).setState(runtime, true);
1372
+ }, [runtime, store]);
1373
+ return store;
1424
1374
  };
1425
- var useContentPartContext2 = (partIndex) => {
1426
- const messageStore = useMessageStore();
1427
- const [context] = useState5(() => {
1428
- const useContentPart2 = create7(
1429
- () => getContentPartState(messageStore.getState(), void 0, partIndex)
1430
- );
1431
- return { useContentPart: useContentPart2 };
1432
- });
1375
+ var useContentPartStore2 = (runtime) => {
1376
+ const [store] = useState5(() => create6(() => runtime.getState()));
1433
1377
  useEffect8(() => {
1434
- const syncContentPart = (message) => {
1435
- const newState = getContentPartState(
1436
- message,
1437
- context.useContentPart,
1438
- partIndex
1439
- );
1440
- if (!newState) return;
1441
- writableStore(context.useContentPart).setState(newState, true);
1442
- };
1443
- syncContentPart(messageStore.getState());
1444
- return messageStore.subscribe(syncContentPart);
1445
- }, [context, messageStore, partIndex]);
1446
- return context;
1378
+ const updateState = () => writableStore(store).setState(runtime.getState(), true);
1379
+ updateState();
1380
+ return runtime.subscribe(updateState);
1381
+ }, [runtime, store]);
1382
+ return store;
1447
1383
  };
1448
- var ContentPartProvider = ({
1449
- partIndex,
1384
+ var ContentPartRuntimeProvider = ({
1385
+ runtime,
1450
1386
  children
1451
1387
  }) => {
1452
- const context = useContentPartContext2(partIndex);
1388
+ const useContentPartRuntime2 = useContentPartRuntimeStore(runtime);
1389
+ const useContentPart2 = useContentPartStore2(runtime);
1390
+ const [context] = useState5(() => {
1391
+ return { useContentPartRuntime: useContentPartRuntime2, useContentPart: useContentPart2 };
1392
+ });
1453
1393
  return /* @__PURE__ */ jsx17(ContentPartContext.Provider, { value: context, children });
1454
1394
  };
1455
1395
 
@@ -1469,11 +1409,11 @@ import {
1469
1409
  useContext as useContext2,
1470
1410
  useState as useState6
1471
1411
  } from "react";
1472
- import { create as create8 } from "zustand";
1412
+ import { create as create7 } from "zustand";
1473
1413
  import { jsx as jsx18 } from "react/jsx-runtime";
1474
1414
  var SmoothContext = createContext5(null);
1475
1415
  var makeSmoothContext = (initialState) => {
1476
- const useSmoothStatus2 = create8(() => initialState);
1416
+ const useSmoothStatus2 = create7(() => initialState);
1477
1417
  return { useSmoothStatus: useSmoothStatus2 };
1478
1418
  };
1479
1419
  var SmoothContextProvider = ({ children }) => {
@@ -1554,9 +1494,7 @@ var SMOOTH_STATUS = Object.freeze({
1554
1494
  type: "running"
1555
1495
  });
1556
1496
  var useSmooth = (state, smooth = false) => {
1557
- const {
1558
- part: { text }
1559
- } = state;
1497
+ const { text } = state;
1560
1498
  const id = useMessage({
1561
1499
  optional: true,
1562
1500
  selector: (m) => m.id
@@ -1568,17 +1506,17 @@ var useSmooth = (state, smooth = false) => {
1568
1506
  setDisplayedText(text2);
1569
1507
  if (smoothStatusStore) {
1570
1508
  writableStore(smoothStatusStore).setState(
1571
- text2 !== state.part.text ? SMOOTH_STATUS : state.status
1509
+ text2 !== state.text ? SMOOTH_STATUS : state.status
1572
1510
  );
1573
1511
  }
1574
1512
  });
1575
1513
  useEffect9(() => {
1576
1514
  if (smoothStatusStore) {
1577
1515
  writableStore(smoothStatusStore).setState(
1578
- text !== state.part.text ? SMOOTH_STATUS : state.status
1516
+ text !== state.text ? SMOOTH_STATUS : state.status
1579
1517
  );
1580
1518
  }
1581
- }, [smoothStatusStore, text, displayedText, state.status, state.part.text]);
1519
+ }, [smoothStatusStore, text, displayedText, state.status, state.text]);
1582
1520
  const [animatorRef] = useState7(
1583
1521
  new TextStreamAnimator(text, setText)
1584
1522
  );
@@ -1605,6 +1543,8 @@ var useSmooth = (state, smooth = false) => {
1605
1543
  }, [animatorRef]);
1606
1544
  return useMemo5(
1607
1545
  () => smooth ? {
1546
+ type: "text",
1547
+ text: displayedText,
1608
1548
  part: { type: "text", text: displayedText },
1609
1549
  status: text === displayedText ? state.status : SMOOTH_STATUS
1610
1550
  } : state,
@@ -1615,10 +1555,7 @@ var useSmooth = (state, smooth = false) => {
1615
1555
  // src/primitives/contentPart/ContentPartText.tsx
1616
1556
  import { jsx as jsx19 } from "react/jsx-runtime";
1617
1557
  var ContentPartPrimitiveText = forwardRef12(({ smooth = true, component: Component = "span", ...rest }, forwardedRef) => {
1618
- const {
1619
- part: { text },
1620
- status
1621
- } = useSmooth(useContentPartText(), smooth);
1558
+ const { text, status } = useSmooth(useContentPartText(), smooth);
1622
1559
  return /* @__PURE__ */ jsx19(Component, { "data-status": status.type, ...rest, ref: forwardedRef, children: text });
1623
1560
  });
1624
1561
  ContentPartPrimitiveText.displayName = "ContentPartPrimitive.Text";
@@ -1628,18 +1565,14 @@ import { Primitive as Primitive8 } from "@radix-ui/react-primitive";
1628
1565
  import { forwardRef as forwardRef13 } from "react";
1629
1566
  import { jsx as jsx20 } from "react/jsx-runtime";
1630
1567
  var ContentPartPrimitiveImage = forwardRef13((props, forwardedRef) => {
1631
- const {
1632
- part: { image }
1633
- } = useContentPartImage();
1568
+ const { image } = useContentPartImage();
1634
1569
  return /* @__PURE__ */ jsx20(Primitive8.img, { src: image, ...props, ref: forwardedRef });
1635
1570
  });
1636
1571
  ContentPartPrimitiveImage.displayName = "ContentPartPrimitive.Image";
1637
1572
 
1638
1573
  // src/primitives/contentPart/ContentPartDisplay.tsx
1639
1574
  var ContentPartPrimitiveDisplay = () => {
1640
- const {
1641
- part: { display }
1642
- } = useContentPartDisplay();
1575
+ const { display } = useContentPartDisplay();
1643
1576
  return display ?? null;
1644
1577
  };
1645
1578
  ContentPartPrimitiveDisplay.displayName = "ContentPartPrimitive.Display";
@@ -1651,105 +1584,655 @@ var ContentPartPrimitiveInProgress = ({ children }) => {
1651
1584
  };
1652
1585
  ContentPartPrimitiveInProgress.displayName = "ContentPartPrimitive.InProgress";
1653
1586
 
1654
- // src/primitives/message/MessageContent.tsx
1655
- import { jsx as jsx21, jsxs as jsxs2 } from "react/jsx-runtime";
1656
- var ToolUIDisplay = ({
1657
- UI,
1658
- ...props
1659
- }) => {
1660
- const Render = useToolUIs((s) => s.getToolUI(props.part.toolName)) ?? UI;
1661
- if (!Render) return null;
1662
- return /* @__PURE__ */ jsx21(Render, { ...props });
1587
+ // src/api/AttachmentRuntime.ts
1588
+ var AttachmentRuntime = class {
1589
+ constructor(_core) {
1590
+ this._core = _core;
1591
+ }
1592
+ getState() {
1593
+ return this._core.getState();
1594
+ }
1595
+ subscribe(callback) {
1596
+ return this._core.subscribe(callback);
1597
+ }
1663
1598
  };
1664
- var defaultComponents = {
1665
- Text: () => /* @__PURE__ */ jsxs2("p", { style: { whiteSpace: "pre-line" }, children: [
1666
- /* @__PURE__ */ jsx21(ContentPartPrimitiveText, {}),
1667
- /* @__PURE__ */ jsx21(ContentPartPrimitiveInProgress, { children: /* @__PURE__ */ jsx21("span", { style: { fontFamily: "revert" }, children: " \u25CF" }) })
1668
- ] }),
1669
- Image: () => /* @__PURE__ */ jsx21(ContentPartPrimitiveImage, {}),
1670
- UI: () => /* @__PURE__ */ jsx21(ContentPartPrimitiveDisplay, {})
1599
+ var ComposerAttachmentRuntime = class extends AttachmentRuntime {
1600
+ constructor(core, _composerApi) {
1601
+ super(core);
1602
+ this._composerApi = _composerApi;
1603
+ }
1604
+ remove() {
1605
+ const core = this._composerApi.getState();
1606
+ if (!core) throw new Error("Composer is not available");
1607
+ return core.removeAttachment(this.getState().id);
1608
+ }
1671
1609
  };
1672
- var MessageContentPartComponent = ({
1673
- components: {
1674
- Text: Text2 = defaultComponents.Text,
1675
- Empty,
1676
- Image: Image2 = defaultComponents.Image,
1677
- UI = defaultComponents.UI,
1678
- tools: { by_name = {}, Fallback: Fallback2 = void 0 } = {}
1679
- } = {}
1680
- }) => {
1681
- const messageStore = useMessageStore();
1682
- const threadRuntime = useThreadRuntime();
1683
- const { part, status } = useContentPart();
1684
- const type = part.type;
1685
- switch (type) {
1686
- case "text":
1687
- if (status.type === "requires-action")
1688
- throw new Error("Encountered unexpected requires-action status");
1689
- if (part === EMPTY_CONTENT && !!Empty) {
1690
- return /* @__PURE__ */ jsx21(Empty, { status });
1691
- }
1692
- return /* @__PURE__ */ jsx21(Text2, { part, status });
1693
- case "image":
1694
- if (status.type === "requires-action")
1695
- throw new Error("Encountered unexpected requires-action status");
1696
- return /* @__PURE__ */ jsx21(Image2, { part, status });
1697
- case "ui":
1698
- if (status.type === "requires-action")
1699
- throw new Error("Encountered unexpected requires-action status");
1700
- return /* @__PURE__ */ jsx21(UI, { part, status });
1701
- case "tool-call": {
1702
- const Tool = by_name[part.toolName] || Fallback2;
1703
- const addResult = (result) => threadRuntime.addToolResult({
1704
- messageId: messageStore.getState().id,
1705
- toolName: part.toolName,
1706
- toolCallId: part.toolCallId,
1707
- result
1708
- });
1709
- return /* @__PURE__ */ jsx21(
1710
- ToolUIDisplay,
1711
- {
1712
- UI: Tool,
1713
- part,
1714
- status,
1715
- addResult
1716
- }
1717
- );
1718
- }
1719
- default:
1720
- const unhandledType = type;
1721
- throw new Error(`Unknown content part type: ${unhandledType}`);
1610
+ var ThreadComposerAttachmentRuntime = class extends ComposerAttachmentRuntime {
1611
+ get source() {
1612
+ return "thread-composer";
1722
1613
  }
1723
1614
  };
1724
- var MessageContentPartImpl = ({
1725
- partIndex,
1726
- components
1727
- }) => {
1728
- return /* @__PURE__ */ jsx21(ContentPartProvider, { partIndex, children: /* @__PURE__ */ jsx21(MessageContentPartComponent, { components }) });
1615
+ var EditComposerAttachmentRuntime = class extends ComposerAttachmentRuntime {
1616
+ get source() {
1617
+ return "edit-composer";
1618
+ }
1729
1619
  };
1730
- var MessageContentPart = memo2(
1731
- MessageContentPartImpl,
1732
- (prev, next) => prev.partIndex === next.partIndex && prev.components?.Text === next.components?.Text && prev.components?.Image === next.components?.Image && prev.components?.UI === next.components?.UI && prev.components?.tools === next.components?.tools
1733
- );
1734
- var MessagePrimitiveContent = ({
1735
- components
1736
- }) => {
1737
- const contentLength = useMessage((s) => s.content.length) || 1;
1738
- return Array.from({ length: contentLength }, (_, index) => /* @__PURE__ */ jsx21(MessageContentPart, { partIndex: index, components }, index));
1620
+ var MessageAttachmentRuntime = class extends AttachmentRuntime {
1621
+ get source() {
1622
+ return "message";
1623
+ }
1624
+ constructor(core) {
1625
+ super(core);
1626
+ }
1627
+ remove() {
1628
+ throw new Error("Message attachments cannot be removed");
1629
+ }
1739
1630
  };
1740
- MessagePrimitiveContent.displayName = "MessagePrimitive.Content";
1741
1631
 
1742
- // src/primitives/message/MessageInProgress.tsx
1743
- var MessagePrimitiveInProgress = () => {
1744
- return null;
1632
+ // src/api/subscribable/BaseSubject.ts
1633
+ var BaseSubject = class {
1634
+ _subscriptions = /* @__PURE__ */ new Set();
1635
+ _connection;
1636
+ get isConnected() {
1637
+ return !!this._connection;
1638
+ }
1639
+ notifySubscribers() {
1640
+ for (const callback of this._subscriptions) callback();
1641
+ }
1642
+ _updateConnection() {
1643
+ if (this._subscriptions.size > 0) {
1644
+ if (this._connection) return;
1645
+ this._connection = this._connect();
1646
+ } else {
1647
+ this._connection?.();
1648
+ this._connection = void 0;
1649
+ }
1650
+ }
1651
+ subscribe(callback) {
1652
+ this._subscriptions.add(callback);
1653
+ this._updateConnection();
1654
+ return () => {
1655
+ this._subscriptions.delete(callback);
1656
+ this._updateConnection();
1657
+ };
1658
+ }
1745
1659
  };
1746
- MessagePrimitiveInProgress.displayName = "MessagePrimitive.InProgress";
1747
1660
 
1748
- // src/primitives/message/MessageAttachments.tsx
1749
- import { memo as memo3 } from "react";
1661
+ // src/api/subscribable/SKIP_UPDATE.ts
1662
+ var SKIP_UPDATE = Symbol("skip-update");
1750
1663
 
1751
- // src/context/react/AttachmentContext.ts
1752
- import { createContext as createContext6, useContext as useContext3 } from "react";
1664
+ // src/api/subscribable/LazyMemoizeSubject.ts
1665
+ var LazyMemoizeSubject = class extends BaseSubject {
1666
+ constructor(binding) {
1667
+ super();
1668
+ this.binding = binding;
1669
+ }
1670
+ _previousStateDirty = true;
1671
+ _previousState;
1672
+ getState = () => {
1673
+ if (!this.isConnected || this._previousStateDirty) {
1674
+ const newState = this.binding.getState();
1675
+ if (newState !== SKIP_UPDATE) {
1676
+ this._previousState = newState;
1677
+ }
1678
+ this._previousStateDirty = false;
1679
+ }
1680
+ if (this._previousState === void 0)
1681
+ throw new Error("Entry not available in the store");
1682
+ return this._previousState;
1683
+ };
1684
+ _connect() {
1685
+ const callback = () => {
1686
+ this._previousStateDirty = true;
1687
+ this.notifySubscribers();
1688
+ };
1689
+ return this.binding.subscribe(callback);
1690
+ }
1691
+ };
1692
+
1693
+ // src/api/subscribable/shallowEqual.ts
1694
+ function shallowEqual(objA, objB) {
1695
+ if (objA === void 0 && objB === void 0) return true;
1696
+ if (objA === void 0) return false;
1697
+ if (objB === void 0) return false;
1698
+ for (const key of Object.keys(objA)) {
1699
+ const valueA = objA[key];
1700
+ const valueB = objB[key];
1701
+ if (!Object.is(valueA, valueB)) return false;
1702
+ }
1703
+ return true;
1704
+ }
1705
+
1706
+ // src/api/subscribable/ShallowMemoizeSubject.ts
1707
+ var ShallowMemoizeSubject = class extends BaseSubject {
1708
+ constructor(binding) {
1709
+ super();
1710
+ this.binding = binding;
1711
+ const state = binding.getState();
1712
+ if (state === SKIP_UPDATE)
1713
+ throw new Error("Entry not available in the store");
1714
+ this._previousState = state;
1715
+ }
1716
+ _previousState;
1717
+ getState = () => {
1718
+ if (!this.isConnected) this._syncState();
1719
+ return this._previousState;
1720
+ };
1721
+ _syncState() {
1722
+ const state = this.binding.getState();
1723
+ if (state === SKIP_UPDATE) return false;
1724
+ if (shallowEqual(state, this._previousState)) return false;
1725
+ this._previousState = state;
1726
+ return true;
1727
+ }
1728
+ _connect() {
1729
+ const callback = () => {
1730
+ if (this._syncState()) {
1731
+ this.notifySubscribers();
1732
+ }
1733
+ };
1734
+ return this.binding.subscribe(callback);
1735
+ }
1736
+ };
1737
+
1738
+ // src/api/ComposerRuntime.ts
1739
+ var METHOD_NOT_SUPPORTED = () => {
1740
+ throw new Error("Composer is not available");
1741
+ };
1742
+ var EMPTY_ARRAY = Object.freeze([]);
1743
+ var getThreadComposerState = (runtime, focus, onFocus) => {
1744
+ return Object.freeze({
1745
+ type: "thread",
1746
+ isEditing: runtime?.isEditing ?? false,
1747
+ canCancel: runtime?.canCancel ?? false,
1748
+ isEmpty: runtime?.isEmpty ?? true,
1749
+ text: runtime?.text ?? "",
1750
+ attachments: runtime?.attachments ?? EMPTY_ARRAY,
1751
+ attachmentAccept: runtime?.attachmentAccept ?? "*",
1752
+ value: runtime?.text ?? "",
1753
+ setValue: runtime?.setText.bind(runtime) ?? METHOD_NOT_SUPPORTED,
1754
+ setText: runtime?.setText.bind(runtime) ?? METHOD_NOT_SUPPORTED,
1755
+ // edit: beginEdit,
1756
+ send: runtime?.send.bind(runtime) ?? METHOD_NOT_SUPPORTED,
1757
+ cancel: runtime?.cancel.bind(runtime) ?? METHOD_NOT_SUPPORTED,
1758
+ focus,
1759
+ onFocus,
1760
+ reset: runtime?.reset.bind(runtime) ?? METHOD_NOT_SUPPORTED,
1761
+ addAttachment: runtime?.addAttachment.bind(runtime) ?? METHOD_NOT_SUPPORTED,
1762
+ removeAttachment: runtime?.removeAttachment.bind(runtime) ?? METHOD_NOT_SUPPORTED
1763
+ });
1764
+ };
1765
+ var getEditComposerState = (runtime, beginEdit) => {
1766
+ return Object.freeze({
1767
+ type: "edit",
1768
+ isEditing: runtime?.isEditing ?? false,
1769
+ canCancel: runtime?.canCancel ?? false,
1770
+ isEmpty: runtime?.isEmpty ?? true,
1771
+ text: runtime?.text ?? "",
1772
+ attachments: runtime?.attachments ?? EMPTY_ARRAY,
1773
+ attachmentAccept: runtime?.attachmentAccept ?? "*",
1774
+ value: runtime?.text ?? "",
1775
+ setValue: runtime?.setText.bind(runtime) ?? METHOD_NOT_SUPPORTED,
1776
+ setText: runtime?.setText.bind(runtime) ?? METHOD_NOT_SUPPORTED,
1777
+ edit: beginEdit,
1778
+ send: runtime?.send.bind(runtime) ?? METHOD_NOT_SUPPORTED,
1779
+ cancel: runtime?.cancel.bind(runtime) ?? METHOD_NOT_SUPPORTED
1780
+ });
1781
+ };
1782
+ var ComposerRuntime = class {
1783
+ constructor(_core) {
1784
+ this._core = _core;
1785
+ }
1786
+ /**
1787
+ * @deprecated Use `getState().isEditing` instead. This will be removed in 0.6.0.
1788
+ */
1789
+ get isEditing() {
1790
+ return this.getState().isEditing;
1791
+ }
1792
+ /**
1793
+ * @deprecated Use `getState().isEmpty` instead. This will be removed in 0.6.0.
1794
+ */
1795
+ get isEmpty() {
1796
+ return this.getState().isEmpty;
1797
+ }
1798
+ /**
1799
+ * @deprecated Use `getState().canCancel` instead. This will be removed in 0.6.0.
1800
+ */
1801
+ get canCancel() {
1802
+ return this.getState().canCancel;
1803
+ }
1804
+ /**
1805
+ * @deprecated Use `getState().text` instead. This will be removed in 0.6.0.
1806
+ */
1807
+ get text() {
1808
+ return this.getState().text;
1809
+ }
1810
+ /**
1811
+ * @deprecated Use `getState().attachmentAccept` instead. This will be removed in 0.6.0.
1812
+ */
1813
+ get attachmentAccept() {
1814
+ return this.getState().attachmentAccept;
1815
+ }
1816
+ /**
1817
+ * @deprecated Use `getState().attachments` instead. This will be removed in 0.6.0.
1818
+ */
1819
+ get attachments() {
1820
+ return this.getState().attachments;
1821
+ }
1822
+ /**
1823
+ * @deprecated Use `getState().text` instead. This will be removed in 0.6.0.
1824
+ */
1825
+ get value() {
1826
+ return this.text;
1827
+ }
1828
+ setText(text) {
1829
+ const core = this._core.getState();
1830
+ if (!core) throw new Error("Composer is not available");
1831
+ core.setText(text);
1832
+ }
1833
+ setValue(text) {
1834
+ this.setText(text);
1835
+ }
1836
+ addAttachment(file) {
1837
+ const core = this._core.getState();
1838
+ if (!core) throw new Error("Composer is not available");
1839
+ return core.addAttachment(file);
1840
+ }
1841
+ // /**
1842
+ // * @deprecated Use `getAttachmentById(id).removeAttachment` instead. This will be removed in 0.6.0.
1843
+ // */
1844
+ removeAttachment(attachmentId) {
1845
+ const core = this._core.getState();
1846
+ if (!core) throw new Error("Composer is not available");
1847
+ return core.removeAttachment(attachmentId);
1848
+ }
1849
+ /**
1850
+ * @deprecated This method will be removed in 0.6.0. Submit feedback if you need this functionality.
1851
+ */
1852
+ reset() {
1853
+ const core = this._core.getState();
1854
+ if (!core) throw new Error("Composer is not available");
1855
+ core.reset();
1856
+ }
1857
+ send() {
1858
+ const core = this._core.getState();
1859
+ if (!core) throw new Error("Composer is not available");
1860
+ core.send();
1861
+ }
1862
+ cancel() {
1863
+ const core = this._core.getState();
1864
+ if (!core) throw new Error("Composer is not available");
1865
+ core.cancel();
1866
+ }
1867
+ subscribe(callback) {
1868
+ return this._core.subscribe(callback);
1869
+ }
1870
+ };
1871
+ var ThreadComposerRuntime = class extends ComposerRuntime {
1872
+ get type() {
1873
+ return "thread";
1874
+ }
1875
+ _getState;
1876
+ constructor(core) {
1877
+ const stateBinding = new LazyMemoizeSubject({
1878
+ getState: () => getThreadComposerState(
1879
+ core.getState(),
1880
+ this.focus.bind(this),
1881
+ this.onFocus.bind(this)
1882
+ ),
1883
+ subscribe: (callback) => core.subscribe(callback)
1884
+ });
1885
+ super({
1886
+ getState: () => core.getState(),
1887
+ subscribe: (callback) => stateBinding.subscribe(callback)
1888
+ });
1889
+ this._getState = stateBinding.getState.bind(stateBinding);
1890
+ }
1891
+ get attachments() {
1892
+ return this.getState()?.attachments ?? EMPTY_ARRAY;
1893
+ }
1894
+ getState() {
1895
+ return this._getState();
1896
+ }
1897
+ // TODO replace with events
1898
+ _focusListeners = /* @__PURE__ */ new Set();
1899
+ focus() {
1900
+ this._focusListeners.forEach((callback) => callback());
1901
+ }
1902
+ onFocus(callback) {
1903
+ this._focusListeners.add(callback);
1904
+ return () => this._focusListeners.delete(callback);
1905
+ }
1906
+ unstable_getAttachmentByIndex(idx) {
1907
+ return new ThreadComposerAttachmentRuntime(
1908
+ new ShallowMemoizeSubject({
1909
+ getState: () => {
1910
+ const attachments = this.getState().attachments;
1911
+ const attachment = attachments[idx];
1912
+ if (!attachment) return SKIP_UPDATE;
1913
+ return {
1914
+ ...attachment,
1915
+ attachment,
1916
+ source: "thread-composer"
1917
+ };
1918
+ },
1919
+ subscribe: (callback) => this._core.subscribe(callback)
1920
+ }),
1921
+ this._core
1922
+ );
1923
+ }
1924
+ };
1925
+ var EditComposerRuntime = class extends ComposerRuntime {
1926
+ constructor(core, _beginEdit) {
1927
+ const stateBinding = new LazyMemoizeSubject({
1928
+ getState: () => getEditComposerState(core.getState(), this._beginEdit),
1929
+ subscribe: (callback) => core.subscribe(callback)
1930
+ });
1931
+ super({
1932
+ getState: () => core.getState(),
1933
+ subscribe: (callback) => stateBinding.subscribe(callback)
1934
+ });
1935
+ this._beginEdit = _beginEdit;
1936
+ this._getState = stateBinding.getState.bind(stateBinding);
1937
+ }
1938
+ get type() {
1939
+ return "edit";
1940
+ }
1941
+ _getState;
1942
+ getState() {
1943
+ return this._getState();
1944
+ }
1945
+ beginEdit() {
1946
+ this._beginEdit();
1947
+ }
1948
+ /**
1949
+ * @deprecated Use `beginEdit()` instead. This will be removed in 0.6.0.
1950
+ */
1951
+ edit() {
1952
+ this.beginEdit();
1953
+ }
1954
+ unstable_getAttachmentByIndex(idx) {
1955
+ return new EditComposerAttachmentRuntime(
1956
+ new ShallowMemoizeSubject({
1957
+ getState: () => {
1958
+ const attachments = this.getState().attachments;
1959
+ const attachment = attachments[idx];
1960
+ if (!attachment) return SKIP_UPDATE;
1961
+ return {
1962
+ ...attachment,
1963
+ attachment,
1964
+ source: "edit-composer"
1965
+ };
1966
+ },
1967
+ subscribe: (callback) => this._core.subscribe(callback)
1968
+ }),
1969
+ this._core
1970
+ );
1971
+ }
1972
+ };
1973
+
1974
+ // src/api/subscribable/NestedSubscriptionSubject.ts
1975
+ var NestedSubscriptionSubject = class extends BaseSubject {
1976
+ constructor(binding) {
1977
+ super();
1978
+ this.binding = binding;
1979
+ }
1980
+ getState() {
1981
+ return this.binding.getState();
1982
+ }
1983
+ _connect() {
1984
+ const callback = () => {
1985
+ this.notifySubscribers();
1986
+ };
1987
+ let lastState = this.binding.getState();
1988
+ let innerUnsubscribe = lastState?.subscribe(callback);
1989
+ const onRuntimeUpdate = () => {
1990
+ const newState = this.binding.getState();
1991
+ if (newState === lastState) return;
1992
+ lastState = newState;
1993
+ innerUnsubscribe?.();
1994
+ innerUnsubscribe = this.binding.getState()?.subscribe(callback);
1995
+ callback();
1996
+ };
1997
+ const outerUnsubscribe = this.binding.subscribe(onRuntimeUpdate);
1998
+ return () => {
1999
+ outerUnsubscribe?.();
2000
+ innerUnsubscribe?.();
2001
+ };
2002
+ }
2003
+ };
2004
+
2005
+ // src/api/MessageRuntime.ts
2006
+ var COMPLETE_STATUS2 = {
2007
+ type: "complete"
2008
+ };
2009
+ var toContentPartStatus = (message, partIndex, part) => {
2010
+ if (message.role !== "assistant") return COMPLETE_STATUS2;
2011
+ const isLastPart = partIndex === Math.max(0, message.content.length - 1);
2012
+ if (part.type !== "tool-call") {
2013
+ if ("reason" in message.status && message.status.reason === "tool-calls" && isLastPart)
2014
+ throw new Error(
2015
+ "Encountered unexpected requires-action status. This is likely an internal bug in assistant-ui."
2016
+ );
2017
+ return isLastPart ? message.status : COMPLETE_STATUS2;
2018
+ }
2019
+ if (!!part.result) {
2020
+ return COMPLETE_STATUS2;
2021
+ }
2022
+ return message.status;
2023
+ };
2024
+ var EMPTY_CONTENT = Object.freeze({ type: "text", text: "" });
2025
+ var getContentPartState = (message, partIndex) => {
2026
+ let part = message.content[partIndex];
2027
+ if (!part) {
2028
+ if (message.content.length === 0 && partIndex === 0) {
2029
+ part = EMPTY_CONTENT;
2030
+ } else {
2031
+ return SKIP_UPDATE;
2032
+ }
2033
+ } else if (message.content.length === 1 && part.type === "text" && part.text.length === 0) {
2034
+ part = EMPTY_CONTENT;
2035
+ }
2036
+ const status = toContentPartStatus(message, partIndex, part);
2037
+ return Object.freeze({ ...part, part, status });
2038
+ };
2039
+ var MessageRuntime = class {
2040
+ constructor(_core, _threadBinding) {
2041
+ this._core = _core;
2042
+ this._threadBinding = _threadBinding;
2043
+ }
2044
+ composer = new EditComposerRuntime(
2045
+ new NestedSubscriptionSubject({
2046
+ getState: () => this._threadBinding.getState().getEditComposer(this._core.getState().id),
2047
+ subscribe: (callback) => this._threadBinding.subscribe(callback)
2048
+ }),
2049
+ () => this._threadBinding.getState().beginEdit(this._core.getState().id)
2050
+ );
2051
+ getState() {
2052
+ return this._core.getState();
2053
+ }
2054
+ // TODO improve type
2055
+ unstable_edit(message) {
2056
+ const state = this._core.getState();
2057
+ if (!state) throw new Error("Message is not available");
2058
+ this._threadBinding.getState().append({
2059
+ ...message,
2060
+ parentId: state.parentId
2061
+ });
2062
+ }
2063
+ reload() {
2064
+ const state = this._core.getState();
2065
+ if (!state) throw new Error("Message is not available");
2066
+ if (state.role !== "assistant")
2067
+ throw new Error("Can only reload assistant messages");
2068
+ this._threadBinding.getState().startRun(state.parentId);
2069
+ }
2070
+ speak() {
2071
+ const state = this._core.getState();
2072
+ if (!state) throw new Error("Message is not available");
2073
+ return this._threadBinding.getState().speak(state.id);
2074
+ }
2075
+ submitFeedback({ type }) {
2076
+ const state = this._core.getState();
2077
+ if (!state) throw new Error("Message is not available");
2078
+ this._threadBinding.getState().submitFeedback({
2079
+ messageId: state.id,
2080
+ type
2081
+ });
2082
+ }
2083
+ switchToBranch({
2084
+ position,
2085
+ branchId
2086
+ }) {
2087
+ const state = this._core.getState();
2088
+ if (!state) throw new Error("Message is not available");
2089
+ if (branchId && position) {
2090
+ throw new Error("May not specify both branchId and position");
2091
+ } else if (!branchId && !position) {
2092
+ throw new Error("Must specify either branchId or position");
2093
+ }
2094
+ const thread = this._threadBinding.getState();
2095
+ const branches = thread.getBranches(state.id);
2096
+ let targetBranch = branchId;
2097
+ if (position === "previous") {
2098
+ targetBranch = branches[state.branchNumber - 2];
2099
+ } else if (position === "next") {
2100
+ targetBranch = branches[state.branchNumber];
2101
+ }
2102
+ if (!targetBranch) throw new Error("Branch not found");
2103
+ this._threadBinding.getState().switchToBranch(targetBranch);
2104
+ }
2105
+ subscribe(callback) {
2106
+ return this._core.subscribe(callback);
2107
+ }
2108
+ unstable_getContentPartByIndex(idx) {
2109
+ if (idx < 0) throw new Error("Message index must be >= 0");
2110
+ return new ContentPartRuntime(
2111
+ new ShallowMemoizeSubject({
2112
+ getState: () => {
2113
+ return getContentPartState(this.getState(), idx);
2114
+ },
2115
+ subscribe: (callback) => this._core.subscribe(callback)
2116
+ }),
2117
+ this._core,
2118
+ this._threadBinding
2119
+ );
2120
+ }
2121
+ unstable_getAttachmentByIndex(idx) {
2122
+ return new MessageAttachmentRuntime(
2123
+ new ShallowMemoizeSubject({
2124
+ getState: () => {
2125
+ const attachments = this.getState().attachments;
2126
+ const attachment = attachments?.[idx];
2127
+ if (!attachment) return SKIP_UPDATE;
2128
+ return {
2129
+ ...attachment,
2130
+ attachment,
2131
+ source: "message"
2132
+ };
2133
+ },
2134
+ subscribe: (callback) => this._core.subscribe(callback)
2135
+ })
2136
+ );
2137
+ }
2138
+ };
2139
+
2140
+ // src/primitives/message/MessageContent.tsx
2141
+ import { jsx as jsx21, jsxs } from "react/jsx-runtime";
2142
+ var ToolUIDisplay = ({
2143
+ UI,
2144
+ ...props
2145
+ }) => {
2146
+ const Render = useToolUIs((s) => s.getToolUI(props.toolName)) ?? UI;
2147
+ if (!Render) return null;
2148
+ return /* @__PURE__ */ jsx21(Render, { ...props });
2149
+ };
2150
+ var defaultComponents = {
2151
+ Text: () => /* @__PURE__ */ jsxs("p", { style: { whiteSpace: "pre-line" }, children: [
2152
+ /* @__PURE__ */ jsx21(ContentPartPrimitiveText, {}),
2153
+ /* @__PURE__ */ jsx21(ContentPartPrimitiveInProgress, { children: /* @__PURE__ */ jsx21("span", { style: { fontFamily: "revert" }, children: " \u25CF" }) })
2154
+ ] }),
2155
+ Image: () => /* @__PURE__ */ jsx21(ContentPartPrimitiveImage, {}),
2156
+ UI: () => /* @__PURE__ */ jsx21(ContentPartPrimitiveDisplay, {})
2157
+ };
2158
+ var MessageContentPartComponent = ({
2159
+ components: {
2160
+ Text: Text2 = defaultComponents.Text,
2161
+ Empty,
2162
+ Image: Image2 = defaultComponents.Image,
2163
+ UI = defaultComponents.UI,
2164
+ tools: { by_name = {}, Fallback: Fallback2 = void 0 } = {}
2165
+ } = {}
2166
+ }) => {
2167
+ const messageStore = useMessageStore();
2168
+ const threadRuntime = useThreadRuntime();
2169
+ const part = useContentPart();
2170
+ const type = part.type;
2171
+ switch (type) {
2172
+ case "text":
2173
+ if (part.status.type === "requires-action")
2174
+ throw new Error("Encountered unexpected requires-action status");
2175
+ if (part.part === EMPTY_CONTENT && !!Empty) {
2176
+ return /* @__PURE__ */ jsx21(Empty, { status: part.status });
2177
+ }
2178
+ return /* @__PURE__ */ jsx21(Text2, { ...part, part });
2179
+ case "image":
2180
+ if (part.status.type === "requires-action")
2181
+ throw new Error("Encountered unexpected requires-action status");
2182
+ return /* @__PURE__ */ jsx21(Image2, { ...part, part });
2183
+ case "ui":
2184
+ if (part.status.type === "requires-action")
2185
+ throw new Error("Encountered unexpected requires-action status");
2186
+ return /* @__PURE__ */ jsx21(UI, { ...part, part });
2187
+ case "tool-call": {
2188
+ const Tool = by_name[part.toolName] || Fallback2;
2189
+ const addResult = (result) => threadRuntime.addToolResult({
2190
+ messageId: messageStore.getState().id,
2191
+ toolName: part.toolName,
2192
+ toolCallId: part.toolCallId,
2193
+ result
2194
+ });
2195
+ return /* @__PURE__ */ jsx21(ToolUIDisplay, { ...part, part, UI: Tool, addResult });
2196
+ }
2197
+ default:
2198
+ const unhandledType = type;
2199
+ throw new Error(`Unknown content part type: ${unhandledType}`);
2200
+ }
2201
+ };
2202
+ var MessageContentPartImpl = ({
2203
+ partIndex,
2204
+ components
2205
+ }) => {
2206
+ const messageRuntime = useMessageRuntime();
2207
+ const runtime = useMemo6(
2208
+ () => messageRuntime.unstable_getContentPartByIndex(partIndex),
2209
+ [messageRuntime, partIndex]
2210
+ );
2211
+ return /* @__PURE__ */ jsx21(ContentPartRuntimeProvider, { runtime, children: /* @__PURE__ */ jsx21(MessageContentPartComponent, { components }) });
2212
+ };
2213
+ var MessageContentPart = memo2(
2214
+ MessageContentPartImpl,
2215
+ (prev, next) => prev.partIndex === next.partIndex && prev.components?.Text === next.components?.Text && prev.components?.Image === next.components?.Image && prev.components?.UI === next.components?.UI && prev.components?.tools === next.components?.tools
2216
+ );
2217
+ var MessagePrimitiveContent = ({
2218
+ components
2219
+ }) => {
2220
+ const contentLength = useMessage((s) => s.content.length) || 1;
2221
+ return Array.from({ length: contentLength }, (_, index) => /* @__PURE__ */ jsx21(MessageContentPart, { partIndex: index, components }, index));
2222
+ };
2223
+ MessagePrimitiveContent.displayName = "MessagePrimitive.Content";
2224
+
2225
+ // src/primitives/message/MessageInProgress.tsx
2226
+ var MessagePrimitiveInProgress = () => {
2227
+ return null;
2228
+ };
2229
+ MessagePrimitiveInProgress.displayName = "MessagePrimitive.InProgress";
2230
+
2231
+ // src/primitives/message/MessageAttachments.tsx
2232
+ import { memo as memo3, useMemo as useMemo8 } from "react";
2233
+
2234
+ // src/context/react/AttachmentContext.ts
2235
+ import { createContext as createContext6, useContext as useContext3 } from "react";
1753
2236
  var AttachmentContext = createContext6(
1754
2237
  null
1755
2238
  );
@@ -1757,84 +2240,91 @@ function useAttachmentContext(options) {
1757
2240
  const context = useContext3(AttachmentContext);
1758
2241
  if (!options?.optional && !context)
1759
2242
  throw new Error(
1760
- "This component must be used within a ComposerPrimitive.Attachments or MessagePrimitive.Attachments component."
2243
+ "This component must be used within a ComposerPrimitive.Attachments or MessagePrimitive.Attachments component."
2244
+ );
2245
+ return context;
2246
+ }
2247
+ function useThreadComposerAttachmentContext(options) {
2248
+ const context = useAttachmentContext(options);
2249
+ if (!context) return null;
2250
+ if (context.source !== "thread-composer")
2251
+ throw new Error(
2252
+ "This component must be used within a thread's ComposerPrimitive.Attachments component."
1761
2253
  );
1762
2254
  return context;
1763
2255
  }
1764
- function useComposerAttachmentContext(options) {
2256
+ function useEditComposerAttachmentContext(options) {
1765
2257
  const context = useAttachmentContext(options);
1766
2258
  if (!context) return null;
1767
- if (context.type !== "composer")
2259
+ if (context.source !== "edit-composer")
1768
2260
  throw new Error(
1769
- "This component must be used within a ComposerPrimitive.Attachments component."
2261
+ "This component must be used within a messages's ComposerPrimitive.Attachments component."
1770
2262
  );
1771
2263
  return context;
1772
2264
  }
1773
2265
  function useMessageAttachmentContext(options) {
1774
2266
  const context = useAttachmentContext(options);
1775
2267
  if (!context) return null;
1776
- if (context.type !== "message")
2268
+ if (context.source !== "message")
1777
2269
  throw new Error(
1778
2270
  "This component must be used within a MessagePrimitive.Attachments component."
1779
2271
  );
1780
2272
  return context;
1781
2273
  }
1782
- var { useAttachment, useAttachmentStore } = createContextStoreHook(
2274
+ function useAttachmentRuntime(options) {
2275
+ const attachmentRuntime = useAttachmentContext(options);
2276
+ if (!attachmentRuntime) return null;
2277
+ return attachmentRuntime.useAttachmentRuntime();
2278
+ }
2279
+ var { useAttachment } = createContextStoreHook(
1783
2280
  useAttachmentContext,
1784
2281
  "useAttachment"
1785
2282
  );
1786
- var {
1787
- useAttachment: useComposerAttachment,
1788
- useAttachmentStore: useComposerAttachmentStore
1789
- } = createContextStoreHook(useComposerAttachmentContext, "useAttachment");
1790
- var {
1791
- useAttachment: useMessageAttachment,
1792
- useAttachmentStore: useMessageAttachmentStore
1793
- } = createContextStoreHook(useMessageAttachmentContext, "useAttachment");
2283
+ var { useAttachment: useThreadComposerAttachment } = createContextStoreHook(useThreadComposerAttachmentContext, "useAttachment");
2284
+ var { useAttachment: useEditComposerAttachment } = createContextStoreHook(useEditComposerAttachmentContext, "useAttachment");
2285
+ var { useAttachment: useMessageAttachment } = createContextStoreHook(
2286
+ useMessageAttachmentContext,
2287
+ "useAttachment"
2288
+ );
1794
2289
 
1795
- // src/context/providers/MessageAttachmentProvider.tsx
1796
- import { useEffect as useEffect10, useState as useState8 } from "react";
1797
- import { create as create9 } from "zustand";
2290
+ // src/context/providers/AttachmentRuntimeProvider.tsx
2291
+ import {
2292
+ useEffect as useEffect10,
2293
+ useMemo as useMemo7,
2294
+ useState as useState8
2295
+ } from "react";
2296
+ import { create as create8 } from "zustand";
1798
2297
  import { jsx as jsx22 } from "react/jsx-runtime";
1799
- var getAttachment = (message, useAttachment2, partIndex) => {
1800
- if (message.role !== "user") return null;
1801
- const attachments = message.attachments;
1802
- const attachment = attachments[partIndex];
1803
- if (!attachment) return null;
1804
- const currentState = useAttachment2?.getState();
1805
- if (currentState && currentState.attachment === attachment) return null;
1806
- return Object.freeze({ attachment });
1807
- };
1808
- var useMessageAttachmentContext2 = (partIndex) => {
1809
- const messageStore = useMessageStore();
1810
- const [context] = useState8(
1811
- () => {
1812
- const useAttachment2 = create9(
1813
- () => getAttachment(messageStore.getState(), void 0, partIndex)
1814
- );
1815
- return { type: "message", useAttachment: useAttachment2 };
1816
- }
1817
- );
2298
+ var useAttachmentRuntimeStore = (runtime) => {
2299
+ const [store] = useState8(() => create8(() => runtime));
1818
2300
  useEffect10(() => {
1819
- const syncAttachment = (messageState) => {
1820
- const newState = getAttachment(
1821
- messageState,
1822
- context.useAttachment,
1823
- partIndex
1824
- );
1825
- if (!newState) return;
1826
- writableStore(context.useAttachment).setState(newState, true);
1827
- };
1828
- syncAttachment(messageStore.getState());
1829
- return messageStore.subscribe(syncAttachment);
1830
- }, [context, messageStore, partIndex]);
1831
- return context;
2301
+ writableStore(store).setState(runtime, true);
2302
+ }, [runtime, store]);
2303
+ return store;
2304
+ };
2305
+ var useAttachmentStore = (runtime) => {
2306
+ const [store] = useState8(() => create8(() => runtime.getState()));
2307
+ useEffect10(() => {
2308
+ const updateState = () => writableStore(store).setState(runtime.getState(), true);
2309
+ updateState();
2310
+ return runtime.subscribe(updateState);
2311
+ }, [runtime, store]);
2312
+ return store;
1832
2313
  };
1833
- var MessageAttachmentProvider = ({
1834
- attachmentIndex: partIndex,
2314
+ var AttachmentRuntimeProvider = ({
2315
+ runtime,
1835
2316
  children
1836
2317
  }) => {
1837
- const context = useMessageAttachmentContext2(partIndex);
2318
+ const useAttachmentRuntime2 = useAttachmentRuntimeStore(runtime);
2319
+ const useAttachment2 = useAttachmentStore(runtime);
2320
+ const source = useAttachment2((s) => s.source);
2321
+ const context = useMemo7(() => {
2322
+ return {
2323
+ source,
2324
+ useAttachmentRuntime: useAttachmentRuntime2,
2325
+ useAttachment: useAttachment2
2326
+ };
2327
+ }, [useAttachmentRuntime2, useAttachment2]);
1838
2328
  return /* @__PURE__ */ jsx22(AttachmentContext.Provider, { value: context, children });
1839
2329
  };
1840
2330
 
@@ -1862,7 +2352,12 @@ var AttachmentComponent = ({ components }) => {
1862
2352
  return /* @__PURE__ */ jsx23(Component, {});
1863
2353
  };
1864
2354
  var MessageAttachmentImpl = ({ components, attachmentIndex }) => {
1865
- return /* @__PURE__ */ jsx23(MessageAttachmentProvider, { attachmentIndex, children: /* @__PURE__ */ jsx23(AttachmentComponent, { components }) });
2355
+ const messageRuntime = useMessageRuntime();
2356
+ const runtime = useMemo8(
2357
+ () => messageRuntime.unstable_getAttachmentByIndex(attachmentIndex),
2358
+ [messageRuntime, attachmentIndex]
2359
+ );
2360
+ return /* @__PURE__ */ jsx23(AttachmentRuntimeProvider, { runtime, children: /* @__PURE__ */ jsx23(AttachmentComponent, { components }) });
1866
2361
  };
1867
2362
  var MessageAttachment = memo3(
1868
2363
  MessageAttachmentImpl,
@@ -2036,51 +2531,8 @@ var ComposerPrimitiveAddAttachment = createActionButton(
2036
2531
  );
2037
2532
 
2038
2533
  // src/primitives/composer/ComposerAttachments.tsx
2039
- import { memo as memo4 } from "react";
2040
-
2041
- // src/context/providers/ComposerAttachmentProvider.tsx
2042
- import { useEffect as useEffect12, useState as useState9 } from "react";
2043
- import { create as create10 } from "zustand";
2534
+ import { memo as memo4, useMemo as useMemo9 } from "react";
2044
2535
  import { jsx as jsx27 } from "react/jsx-runtime";
2045
- var getAttachment2 = ({ attachments }, useAttachment2, partIndex) => {
2046
- const attachment = attachments[partIndex];
2047
- if (!attachment) return null;
2048
- const currentState = useAttachment2?.getState();
2049
- if (currentState && currentState.attachment === attachment) return null;
2050
- return Object.freeze({ attachment });
2051
- };
2052
- var useComposerAttachmentContext2 = (partIndex) => {
2053
- const threadComposerStore = useThreadComposerStore();
2054
- const [context] = useState9(
2055
- () => {
2056
- const useAttachment2 = create10(
2057
- () => getAttachment2(threadComposerStore.getState(), void 0, partIndex)
2058
- );
2059
- return { type: "composer", useAttachment: useAttachment2 };
2060
- }
2061
- );
2062
- useEffect12(() => {
2063
- const syncAttachment = (composer) => {
2064
- const newState = getAttachment2(
2065
- composer,
2066
- context.useAttachment,
2067
- partIndex
2068
- );
2069
- if (!newState) return;
2070
- writableStore(context.useAttachment).setState(newState, true);
2071
- };
2072
- syncAttachment(threadComposerStore.getState());
2073
- return threadComposerStore.subscribe(syncAttachment);
2074
- }, [context, threadComposerStore, partIndex]);
2075
- return context;
2076
- };
2077
- var ComposerAttachmentProvider = ({ attachmentIndex: partIndex, children }) => {
2078
- const context = useComposerAttachmentContext2(partIndex);
2079
- return /* @__PURE__ */ jsx27(AttachmentContext.Provider, { value: context, children });
2080
- };
2081
-
2082
- // src/primitives/composer/ComposerAttachments.tsx
2083
- import { jsx as jsx28 } from "react/jsx-runtime";
2084
2536
  var getComponent2 = (components, attachment) => {
2085
2537
  const type = attachment.type;
2086
2538
  switch (type) {
@@ -2096,22 +2548,27 @@ var getComponent2 = (components, attachment) => {
2096
2548
  }
2097
2549
  };
2098
2550
  var AttachmentComponent2 = ({ components }) => {
2099
- const Component = useComposerAttachment(
2100
- (a) => getComponent2(components, a.attachment)
2551
+ const Component = useThreadComposerAttachment(
2552
+ (a) => getComponent2(components, a)
2101
2553
  );
2102
2554
  if (!Component) return null;
2103
- return /* @__PURE__ */ jsx28(Component, {});
2555
+ return /* @__PURE__ */ jsx27(Component, {});
2104
2556
  };
2105
2557
  var ComposerAttachmentImpl = ({ components, attachmentIndex }) => {
2106
- return /* @__PURE__ */ jsx28(ComposerAttachmentProvider, { attachmentIndex, children: /* @__PURE__ */ jsx28(AttachmentComponent2, { components }) });
2558
+ const composerRuntime = useComposerRuntime();
2559
+ const runtime = useMemo9(
2560
+ () => composerRuntime.unstable_getAttachmentByIndex(attachmentIndex),
2561
+ [composerRuntime, attachmentIndex]
2562
+ );
2563
+ return /* @__PURE__ */ jsx27(AttachmentRuntimeProvider, { runtime, children: /* @__PURE__ */ jsx27(AttachmentComponent2, { components }) });
2107
2564
  };
2108
2565
  var ComposerAttachment = memo4(
2109
2566
  ComposerAttachmentImpl,
2110
2567
  (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
2111
2568
  );
2112
2569
  var ComposerPrimitiveAttachments = ({ components }) => {
2113
- const attachmentsCount = useThreadComposer((s) => s.attachments.length);
2114
- return Array.from({ length: attachmentsCount }, (_, index) => /* @__PURE__ */ jsx28(
2570
+ const attachmentsCount = useComposer((s) => s.attachments.length);
2571
+ return Array.from({ length: attachmentsCount }, (_, index) => /* @__PURE__ */ jsx27(
2115
2572
  ComposerAttachment,
2116
2573
  {
2117
2574
  attachmentIndex: index,
@@ -2156,9 +2613,9 @@ __export(thread_exports, {
2156
2613
  // src/primitives/thread/ThreadRoot.tsx
2157
2614
  import { Primitive as Primitive11 } from "@radix-ui/react-primitive";
2158
2615
  import { forwardRef as forwardRef17 } from "react";
2159
- import { jsx as jsx29 } from "react/jsx-runtime";
2616
+ import { jsx as jsx28 } from "react/jsx-runtime";
2160
2617
  var ThreadPrimitiveRoot = forwardRef17((props, ref) => {
2161
- return /* @__PURE__ */ jsx29(Primitive11.div, { ...props, ref });
2618
+ return /* @__PURE__ */ jsx28(Primitive11.div, { ...props, ref });
2162
2619
  });
2163
2620
  ThreadPrimitiveRoot.displayName = "ThreadPrimitive.Root";
2164
2621
 
@@ -2232,11 +2689,11 @@ var useOnResizeContent = (callback) => {
2232
2689
 
2233
2690
  // src/utils/hooks/useOnScrollToBottom.tsx
2234
2691
  import { useCallbackRef as useCallbackRef4 } from "@radix-ui/react-use-callback-ref";
2235
- import { useEffect as useEffect13 } from "react";
2692
+ import { useEffect as useEffect12 } from "react";
2236
2693
  var useOnScrollToBottom = (callback) => {
2237
2694
  const callbackRef = useCallbackRef4(callback);
2238
2695
  const threadViewportStore = useThreadViewportStore();
2239
- useEffect13(() => {
2696
+ useEffect12(() => {
2240
2697
  return threadViewportStore.getState().onScrollToBottom(() => {
2241
2698
  callbackRef();
2242
2699
  });
@@ -2295,65 +2752,26 @@ var useThreadViewportAutoScroll = ({
2295
2752
  };
2296
2753
 
2297
2754
  // src/primitives/thread/ThreadViewport.tsx
2298
- import { jsx as jsx30 } from "react/jsx-runtime";
2755
+ import { jsx as jsx29 } from "react/jsx-runtime";
2299
2756
  var ThreadPrimitiveViewport = forwardRef18(({ autoScroll, children, ...rest }, forwardedRef) => {
2300
2757
  const autoScrollRef = useThreadViewportAutoScroll({
2301
2758
  autoScroll
2302
2759
  });
2303
2760
  const ref = useComposedRefs4(forwardedRef, autoScrollRef);
2304
- return /* @__PURE__ */ jsx30(Primitive12.div, { ...rest, ref, children });
2761
+ return /* @__PURE__ */ jsx29(Primitive12.div, { ...rest, ref, children });
2305
2762
  });
2306
2763
  ThreadPrimitiveViewport.displayName = "ThreadPrimitive.Viewport";
2307
2764
 
2308
2765
  // src/primitives/thread/ThreadMessages.tsx
2309
- import { memo as memo5, useMemo as useMemo6 } from "react";
2766
+ import { memo as memo5, useMemo as useMemo10 } from "react";
2310
2767
 
2311
2768
  // src/context/providers/MessageRuntimeProvider.tsx
2312
- import { useEffect as useEffect14, useState as useState10 } from "react";
2313
- import { create as create13 } from "zustand";
2314
-
2315
- // src/context/stores/EditComposer.ts
2316
- import { create as create11 } from "zustand";
2317
- var makeEditComposerStore = ({
2318
- onEdit,
2319
- onSend
2320
- }) => create11()((set, get) => ({
2321
- type: "edit",
2322
- get value() {
2323
- return get().text;
2324
- },
2325
- setValue(value) {
2326
- get().setText(value);
2327
- },
2328
- text: "",
2329
- setText: (text) => {
2330
- set({ text, isEmpty: text.trim().length === 0 });
2331
- },
2332
- canCancel: false,
2333
- isEditing: false,
2334
- isEmpty: true,
2335
- edit: () => {
2336
- const text = onEdit();
2337
- set({
2338
- isEditing: true,
2339
- canCancel: true,
2340
- isEmpty: text.trim().length === 0,
2341
- text
2342
- });
2343
- },
2344
- send: () => {
2345
- const text = get().text;
2346
- set({ isEditing: false, canCancel: false });
2347
- onSend(text);
2348
- },
2349
- cancel: () => {
2350
- set({ isEditing: false, canCancel: false });
2351
- }
2352
- }));
2769
+ import { useEffect as useEffect13, useState as useState9 } from "react";
2770
+ import { create as create10 } from "zustand";
2353
2771
 
2354
2772
  // src/context/stores/MessageUtils.ts
2355
- import { create as create12 } from "zustand";
2356
- var makeMessageUtilsStore = () => create12((set) => {
2773
+ import { create as create9 } from "zustand";
2774
+ var makeMessageUtilsStore = () => create9((set) => {
2357
2775
  let utterance = null;
2358
2776
  return {
2359
2777
  isCopied: false,
@@ -2383,17 +2801,17 @@ var makeMessageUtilsStore = () => create12((set) => {
2383
2801
  });
2384
2802
 
2385
2803
  // src/context/providers/MessageRuntimeProvider.tsx
2386
- import { jsx as jsx31 } from "react/jsx-runtime";
2804
+ import { jsx as jsx30 } from "react/jsx-runtime";
2387
2805
  var useMessageRuntimeStore = (runtime) => {
2388
- const [store] = useState10(() => create13(() => runtime));
2389
- useEffect14(() => {
2806
+ const [store] = useState9(() => create10(() => runtime));
2807
+ useEffect13(() => {
2390
2808
  writableStore(store).setState(runtime, true);
2391
2809
  }, [runtime, store]);
2392
2810
  return store;
2393
2811
  };
2394
2812
  var useMessageStore2 = (runtime) => {
2395
- const [store] = useState10(() => create13(() => runtime.getState()));
2396
- useEffect14(() => {
2813
+ const [store] = useState9(() => create10(() => runtime.getState()));
2814
+ useEffect13(() => {
2397
2815
  const updateState = () => writableStore(store).setState(runtime.getState(), true);
2398
2816
  updateState();
2399
2817
  return runtime.subscribe(updateState);
@@ -2401,33 +2819,17 @@ var useMessageStore2 = (runtime) => {
2401
2819
  return store;
2402
2820
  };
2403
2821
  var useMessageUtilsStore2 = () => {
2404
- const [store] = useState10(() => makeMessageUtilsStore());
2822
+ const [store] = useState9(() => makeMessageUtilsStore());
2405
2823
  return store;
2406
2824
  };
2407
2825
  var useEditComposerStore2 = (useMessageRuntime2) => {
2408
- const [store] = useState10(
2409
- () => makeEditComposerStore({
2410
- onEdit: () => {
2411
- const text = getThreadMessageText(
2412
- useMessageRuntime2.getState().getState()
2413
- );
2414
- return text;
2415
- },
2416
- onSend: (text) => {
2417
- const message = useMessageRuntime2.getState().getState();
2418
- const previousText = getThreadMessageText(message);
2419
- if (previousText === text) return;
2420
- const nonTextParts = message.content.filter(
2421
- (part) => part.type !== "text" && part.type !== "ui"
2422
- );
2423
- useMessageRuntime2.getState().edit({
2424
- role: message.role,
2425
- content: [{ type: "text", text }, ...nonTextParts],
2426
- attachments: message.attachments ?? []
2427
- });
2428
- }
2429
- })
2430
- );
2826
+ const runtime = useMessageRuntime2.getState().composer;
2827
+ const [store] = useState9(() => create10(() => runtime.getState()));
2828
+ useEffect13(() => {
2829
+ const updateState = () => writableStore(store).setState(runtime.getState());
2830
+ updateState();
2831
+ return runtime.subscribe(updateState);
2832
+ }, [runtime, store]);
2431
2833
  return store;
2432
2834
  };
2433
2835
  var MessageRuntimeProvider = ({
@@ -2438,14 +2840,14 @@ var MessageRuntimeProvider = ({
2438
2840
  const useMessage2 = useMessageStore2(runtime);
2439
2841
  const useMessageUtils2 = useMessageUtilsStore2();
2440
2842
  const useEditComposer2 = useEditComposerStore2(useMessageRuntime2);
2441
- const [context] = useState10(() => {
2843
+ const [context] = useState9(() => {
2442
2844
  return { useMessageRuntime: useMessageRuntime2, useMessage: useMessage2, useMessageUtils: useMessageUtils2, useEditComposer: useEditComposer2 };
2443
2845
  });
2444
- return /* @__PURE__ */ jsx31(MessageContext.Provider, { value: context, children });
2846
+ return /* @__PURE__ */ jsx30(MessageContext.Provider, { value: context, children });
2445
2847
  };
2446
2848
 
2447
2849
  // src/primitives/thread/ThreadMessages.tsx
2448
- import { jsx as jsx32 } from "react/jsx-runtime";
2850
+ import { jsx as jsx31 } from "react/jsx-runtime";
2449
2851
  var isComponentsSame = (prev, next) => {
2450
2852
  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;
2451
2853
  };
@@ -2481,18 +2883,18 @@ var ThreadMessageComponent = ({
2481
2883
  const role = useMessage((m) => m.role);
2482
2884
  const isEditing = useEditComposer((c) => c.isEditing);
2483
2885
  const Component = getComponent3(components, role, isEditing);
2484
- return /* @__PURE__ */ jsx32(Component, {});
2886
+ return /* @__PURE__ */ jsx31(Component, {});
2485
2887
  };
2486
2888
  var ThreadMessageImpl = ({
2487
2889
  messageIndex,
2488
2890
  components
2489
2891
  }) => {
2490
2892
  const threadRuntime = useThreadRuntime();
2491
- const runtime = useMemo6(
2893
+ const runtime = useMemo10(
2492
2894
  () => threadRuntime.unstable_getMesssageByIndex(messageIndex),
2493
2895
  [threadRuntime, messageIndex]
2494
2896
  );
2495
- return /* @__PURE__ */ jsx32(MessageRuntimeProvider, { runtime, children: /* @__PURE__ */ jsx32(ThreadMessageComponent, { components }) });
2897
+ return /* @__PURE__ */ jsx31(MessageRuntimeProvider, { runtime, children: /* @__PURE__ */ jsx31(ThreadMessageComponent, { components }) });
2496
2898
  };
2497
2899
  var ThreadMessage = memo5(
2498
2900
  ThreadMessageImpl,
@@ -2501,9 +2903,9 @@ var ThreadMessage = memo5(
2501
2903
  var ThreadPrimitiveMessagesImpl = ({
2502
2904
  components
2503
2905
  }) => {
2504
- const messagesLength = useThreadMessages((t) => t.length);
2906
+ const messagesLength = useThread((t) => t.messages.length);
2505
2907
  if (messagesLength === 0) return null;
2506
- return Array.from({ length: messagesLength }, (_, index) => /* @__PURE__ */ jsx32(ThreadMessage, { messageIndex: index, components }, index));
2908
+ return Array.from({ length: messagesLength }, (_, index) => /* @__PURE__ */ jsx31(ThreadMessage, { messageIndex: index, components }, index));
2507
2909
  };
2508
2910
  ThreadPrimitiveMessagesImpl.displayName = "ThreadPrimitive.Messages";
2509
2911
  var ThreadPrimitiveMessages = memo5(
@@ -2545,7 +2947,7 @@ var subscribeToMainThread = (runtime, callback) => {
2545
2947
  };
2546
2948
 
2547
2949
  // src/runtimes/local/useLocalRuntime.tsx
2548
- import { useInsertionEffect, useMemo as useMemo7, useState as useState12 } from "react";
2950
+ import { useInsertionEffect, useMemo as useMemo11, useState as useState11 } from "react";
2549
2951
 
2550
2952
  // src/runtimes/core/BaseAssistantRuntimeCore.tsx
2551
2953
  var BaseAssistantRuntimeCore = class {
@@ -2575,7 +2977,7 @@ var internal_exports = {};
2575
2977
  __export(internal_exports, {
2576
2978
  AssistantRuntime: () => AssistantRuntime,
2577
2979
  BaseAssistantRuntimeCore: () => BaseAssistantRuntimeCore,
2578
- BaseThreadComposerRuntimeCore: () => BaseThreadComposerRuntimeCore,
2980
+ DefaultThreadComposerRuntimeCore: () => DefaultThreadComposerRuntimeCore,
2579
2981
  MessageRepository: () => MessageRepository,
2580
2982
  ProxyConfigProvider: () => ProxyConfigProvider,
2581
2983
  ThreadRuntime: () => ThreadRuntime,
@@ -2586,46 +2988,70 @@ __export(internal_exports, {
2586
2988
  withSmoothContextProvider: () => withSmoothContextProvider
2587
2989
  });
2588
2990
 
2589
- // src/runtimes/utils/BaseThreadComposerRuntimeCore.tsx
2590
- var BaseThreadComposerRuntimeCore = class {
2591
- constructor(runtime) {
2592
- this.runtime = runtime;
2593
- this.connect();
2594
- }
2595
- _attachmentAdapter;
2991
+ // src/runtimes/composer/BaseComposerRuntimeCore.tsx
2992
+ var isAttachmentComplete = (a) => a.status.type === "complete";
2993
+ var BaseComposerRuntimeCore = class {
2994
+ isEditing = true;
2596
2995
  attachmentAccept = "*";
2996
+ _attachments = [];
2997
+ set attachments(value) {
2998
+ this._attachments = value;
2999
+ this.notifySubscribers();
3000
+ }
3001
+ get attachments() {
3002
+ return this._attachments;
3003
+ }
2597
3004
  get isEmpty() {
2598
3005
  return !this.text.trim() && !this.attachments.length;
2599
3006
  }
2600
- _canCancel = false;
2601
- get canCancel() {
2602
- return this._canCancel;
3007
+ _text = "";
3008
+ get text() {
3009
+ return this._text;
2603
3010
  }
2604
- connect() {
2605
- return this.runtime.subscribe(() => {
2606
- if (this.canCancel !== this.runtime.capabilities.cancel) {
2607
- this._canCancel = this.runtime.capabilities.cancel;
2608
- this.notifySubscribers();
2609
- }
2610
- });
3011
+ setText(value) {
3012
+ this._text = value;
3013
+ this.notifySubscribers();
3014
+ }
3015
+ reset() {
3016
+ this._text = "";
3017
+ this._attachments = [];
3018
+ this.notifySubscribers();
3019
+ }
3020
+ async send() {
3021
+ const attachments = this._attachmentAdapter ? await Promise.all(
3022
+ this.attachments.map(async (a) => {
3023
+ if (isAttachmentComplete(a)) return a;
3024
+ const result = await this._attachmentAdapter.send(a);
3025
+ if (result.status?.type !== "complete") {
3026
+ result.status = { type: "complete" };
3027
+ }
3028
+ return result;
3029
+ })
3030
+ ) : [];
3031
+ const message = {
3032
+ role: "user",
3033
+ content: this.text ? [{ type: "text", text: this.text }] : [],
3034
+ attachments
3035
+ };
3036
+ this.reset();
3037
+ this.handleSend(message);
2611
3038
  }
3039
+ _attachmentAdapter;
2612
3040
  setAttachmentAdapter(adapter) {
2613
3041
  this._attachmentAdapter = adapter;
2614
3042
  const accept = adapter?.accept ?? "*";
2615
3043
  if (this.attachmentAccept !== accept) {
2616
3044
  this.attachmentAccept = accept;
2617
- return true;
3045
+ this.notifySubscribers();
2618
3046
  }
2619
- return false;
2620
- }
2621
- _attachments = [];
2622
- get attachments() {
2623
- return this._attachments;
2624
3047
  }
2625
3048
  async addAttachment(file) {
2626
3049
  if (!this._attachmentAdapter)
2627
3050
  throw new Error("Attachments are not supported");
2628
3051
  const attachment = await this._attachmentAdapter.add({ file });
3052
+ if (attachment.status === void 0) {
3053
+ attachment.status = { type: "requires-action", reason: "composer-send" };
3054
+ }
2629
3055
  this._attachments = [...this._attachments, attachment];
2630
3056
  this.notifySubscribers();
2631
3057
  }
@@ -2639,44 +3065,47 @@ var BaseThreadComposerRuntimeCore = class {
2639
3065
  this._attachments = this._attachments.toSpliced(index, 1);
2640
3066
  this.notifySubscribers();
2641
3067
  }
2642
- _text = "";
2643
- get text() {
2644
- return this._text;
3068
+ _subscriptions = /* @__PURE__ */ new Set();
3069
+ notifySubscribers() {
3070
+ for (const callback of this._subscriptions) callback();
2645
3071
  }
2646
- setText(value) {
2647
- this._text = value;
2648
- this.notifySubscribers();
3072
+ subscribe(callback) {
3073
+ this._subscriptions.add(callback);
3074
+ return () => this._subscriptions.delete(callback);
2649
3075
  }
2650
- reset() {
2651
- this._text = "";
2652
- this._attachments = [];
2653
- this.notifySubscribers();
3076
+ };
3077
+
3078
+ // src/runtimes/composer/DefaultThreadComposerRuntimeCore.tsx
3079
+ var DefaultThreadComposerRuntimeCore = class extends BaseComposerRuntimeCore {
3080
+ constructor(runtime) {
3081
+ super();
3082
+ this.runtime = runtime;
3083
+ this.connect();
2654
3084
  }
2655
- async send() {
2656
- const attachments = this._attachmentAdapter ? await Promise.all(
2657
- this.attachments.map(
2658
- async (a) => await this._attachmentAdapter.send(a)
2659
- )
2660
- ) : [];
3085
+ _canCancel = false;
3086
+ get canCancel() {
3087
+ return this._canCancel;
3088
+ }
3089
+ get attachments() {
3090
+ return super.attachments;
3091
+ }
3092
+ connect() {
3093
+ return this.runtime.subscribe(() => {
3094
+ if (this.canCancel !== this.runtime.capabilities.cancel) {
3095
+ this._canCancel = this.runtime.capabilities.cancel;
3096
+ this.notifySubscribers();
3097
+ }
3098
+ });
3099
+ }
3100
+ async handleSend(message) {
2661
3101
  this.runtime.append({
2662
- parentId: this.runtime.messages.at(-1)?.id ?? null,
2663
- role: "user",
2664
- content: this.text ? [{ type: "text", text: this.text }] : [],
2665
- attachments
3102
+ ...message,
3103
+ parentId: this.runtime.messages.at(-1)?.id ?? null
2666
3104
  });
2667
- this.reset();
2668
3105
  }
2669
3106
  async cancel() {
2670
3107
  this.runtime.cancelRun();
2671
3108
  }
2672
- _subscriptions = /* @__PURE__ */ new Set();
2673
- notifySubscribers() {
2674
- for (const callback of this._subscriptions) callback();
2675
- }
2676
- subscribe(callback) {
2677
- this._subscriptions.add(callback);
2678
- return () => this._subscriptions.delete(callback);
2679
- }
2680
3109
  };
2681
3110
 
2682
3111
  // src/utils/ProxyConfigProvider.ts
@@ -2804,11 +3233,11 @@ var MessageRepository = class {
2804
3233
  }
2805
3234
  }
2806
3235
  getMessages() {
2807
- const messages = new Array(this.head?.level ?? 0);
3236
+ const messages2 = new Array(this.head?.level ?? 0);
2808
3237
  for (let current = this.head; current; current = current.prev) {
2809
- messages[current.level] = current.current;
3238
+ messages2[current.level] = current.current;
2810
3239
  }
2811
- return messages;
3240
+ return messages2;
2812
3241
  }
2813
3242
  addOrUpdateMessage(parentId, message) {
2814
3243
  const existingItem = this.messages.get(message.id);
@@ -2934,11 +3363,11 @@ var MessageRepository = class {
2934
3363
  messages: exportItems
2935
3364
  };
2936
3365
  }
2937
- import({ headId, messages }) {
2938
- for (const { message, parentId } of messages) {
3366
+ import({ headId, messages: messages2 }) {
3367
+ for (const { message, parentId } of messages2) {
2939
3368
  this.addOrUpdateMessage(parentId, message);
2940
3369
  }
2941
- this.resetHead(headId ?? messages.at(-1)?.message.id ?? null);
3370
+ this.resetHead(headId ?? messages2.at(-1)?.message.id ?? null);
2942
3371
  }
2943
3372
  };
2944
3373
 
@@ -2953,7 +3382,7 @@ import {
2953
3382
  forwardRef as forwardRef19
2954
3383
  } from "react";
2955
3384
  import classNames from "classnames";
2956
- import { jsx as jsx33 } from "react/jsx-runtime";
3385
+ import { jsx as jsx32 } from "react/jsx-runtime";
2957
3386
  var withDefaultProps = ({
2958
3387
  className,
2959
3388
  ...defaultProps
@@ -2969,7 +3398,7 @@ var withDefaults = (Component, defaultProps) => {
2969
3398
  const WithDefaults = forwardRef19(
2970
3399
  (props, ref) => {
2971
3400
  const ComponentAsAny = Component;
2972
- return /* @__PURE__ */ jsx33(ComponentAsAny, { ...getProps(props), ref });
3401
+ return /* @__PURE__ */ jsx32(ComponentAsAny, { ...getProps(props), ref });
2973
3402
  }
2974
3403
  );
2975
3404
  WithDefaults.displayName = "withDefaults(" + (typeof Component === "string" ? Component : Component.displayName) + ")";
@@ -2977,9 +3406,9 @@ var withDefaults = (Component, defaultProps) => {
2977
3406
  };
2978
3407
 
2979
3408
  // src/ui/base/tooltip.tsx
2980
- import { jsx as jsx34 } from "react/jsx-runtime";
3409
+ import { jsx as jsx33 } from "react/jsx-runtime";
2981
3410
  var Tooltip = (props) => {
2982
- return /* @__PURE__ */ jsx34(TooltipPrimitive.Provider, { children: /* @__PURE__ */ jsx34(TooltipPrimitive.Root, { ...props }) });
3411
+ return /* @__PURE__ */ jsx33(TooltipPrimitive.Provider, { children: /* @__PURE__ */ jsx33(TooltipPrimitive.Root, { ...props }) });
2983
3412
  };
2984
3413
  Tooltip.displayName = "Tooltip";
2985
3414
  var TooltipTrigger = TooltipPrimitive.Trigger;
@@ -2993,7 +3422,7 @@ TooltipContent.displayName = "TooltipContent";
2993
3422
  import { cva } from "class-variance-authority";
2994
3423
  import { Primitive as Primitive13 } from "@radix-ui/react-primitive";
2995
3424
  import { forwardRef as forwardRef20 } from "react";
2996
- import { jsx as jsx35 } from "react/jsx-runtime";
3425
+ import { jsx as jsx34 } from "react/jsx-runtime";
2997
3426
  var buttonVariants = cva("aui-button", {
2998
3427
  variants: {
2999
3428
  variant: {
@@ -3013,7 +3442,7 @@ var buttonVariants = cva("aui-button", {
3013
3442
  });
3014
3443
  var Button = forwardRef20(
3015
3444
  ({ className, variant, size, ...props }, ref) => {
3016
- return /* @__PURE__ */ jsx35(
3445
+ return /* @__PURE__ */ jsx34(
3017
3446
  Primitive13.button,
3018
3447
  {
3019
3448
  className: buttonVariants({ variant, size, className }),
@@ -3026,77 +3455,17 @@ var Button = forwardRef20(
3026
3455
  Button.displayName = "Button";
3027
3456
 
3028
3457
  // src/ui/base/tooltip-icon-button.tsx
3029
- import { jsx as jsx36, jsxs as jsxs3 } from "react/jsx-runtime";
3458
+ import { jsx as jsx35, jsxs as jsxs2 } from "react/jsx-runtime";
3030
3459
  var TooltipIconButton = forwardRef21(({ children, tooltip, side = "bottom", ...rest }, ref) => {
3031
- return /* @__PURE__ */ jsxs3(Tooltip, { children: [
3032
- /* @__PURE__ */ jsx36(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs3(Button, { variant: "ghost", size: "icon", ...rest, ref, children: [
3460
+ return /* @__PURE__ */ jsxs2(Tooltip, { children: [
3461
+ /* @__PURE__ */ jsx35(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs2(Button, { variant: "ghost", size: "icon", ...rest, ref, children: [
3033
3462
  children,
3034
- /* @__PURE__ */ jsx36("span", { className: "aui-sr-only", children: tooltip })
3463
+ /* @__PURE__ */ jsx35("span", { className: "aui-sr-only", children: tooltip })
3035
3464
  ] }) }),
3036
- /* @__PURE__ */ jsx36(TooltipContent, { side, children: tooltip })
3465
+ /* @__PURE__ */ jsx35(TooltipContent, { side, children: tooltip })
3037
3466
  ] });
3038
- });
3039
- TooltipIconButton.displayName = "TooltipIconButton";
3040
-
3041
- // src/api/subscribable/BaseSubject.ts
3042
- var BaseSubject = class {
3043
- _subscriptions = /* @__PURE__ */ new Set();
3044
- _connection;
3045
- get isConnected() {
3046
- return !!this._connection;
3047
- }
3048
- notifySubscribers() {
3049
- for (const callback of this._subscriptions) callback();
3050
- }
3051
- _updateConnection() {
3052
- if (this._subscriptions.size > 0) {
3053
- if (this._connection) return;
3054
- this._connection = this._connect();
3055
- } else {
3056
- this._connection?.();
3057
- this._connection = void 0;
3058
- }
3059
- }
3060
- subscribe(callback) {
3061
- this._subscriptions.add(callback);
3062
- this._updateConnection();
3063
- return () => {
3064
- this._subscriptions.delete(callback);
3065
- this._updateConnection();
3066
- };
3067
- }
3068
- };
3069
-
3070
- // src/api/subscribable/NestedSubscriptionSubject.ts
3071
- var NestedSubscriptionSubject = class extends BaseSubject {
3072
- constructor(binding) {
3073
- super();
3074
- this.binding = binding;
3075
- }
3076
- getState() {
3077
- return this.binding.getState();
3078
- }
3079
- _connect() {
3080
- const callback = () => {
3081
- this.notifySubscribers();
3082
- };
3083
- let lastState = this.binding.getState();
3084
- let innerUnsubscribe = lastState.subscribe(callback);
3085
- const onRuntimeUpdate = () => {
3086
- const newState = this.binding.getState();
3087
- if (newState === lastState) return;
3088
- lastState = newState;
3089
- innerUnsubscribe?.();
3090
- innerUnsubscribe = this.binding.getState().subscribe(callback);
3091
- callback();
3092
- };
3093
- const outerUnsubscribe = this.binding.subscribe(onRuntimeUpdate);
3094
- return () => {
3095
- outerUnsubscribe?.();
3096
- innerUnsubscribe();
3097
- };
3098
- }
3099
- };
3467
+ });
3468
+ TooltipIconButton.displayName = "TooltipIconButton";
3100
3469
 
3101
3470
  // src/api/AssistantRuntime.ts
3102
3471
  var AssistantRuntime = class {
@@ -3128,245 +3497,11 @@ var AssistantRuntime = class {
3128
3497
  }
3129
3498
  };
3130
3499
 
3131
- // src/api/ContentPartRuntime.ts
3132
- var ContentPartRuntime = class {
3133
- constructor(contentBinding, messageApi, threadApi) {
3134
- this.contentBinding = contentBinding;
3135
- this.messageApi = messageApi;
3136
- this.threadApi = threadApi;
3137
- }
3138
- getState() {
3139
- return this.contentBinding.getState();
3140
- }
3141
- addToolResult(result) {
3142
- const message = this.messageApi.getState();
3143
- if (!message) throw new Error("Message is not available");
3144
- const state = this.contentBinding.getState();
3145
- if (!state) throw new Error("Content part is not available");
3146
- if (state.part.type !== "tool-call")
3147
- throw new Error("Tried to add tool result to non-tool content part");
3148
- const toolName = state.part.toolName;
3149
- const toolCallId = state.part.toolCallId;
3150
- this.threadApi.getState().addToolResult({
3151
- messageId: message.id,
3152
- toolName,
3153
- toolCallId,
3154
- result
3155
- });
3156
- }
3157
- };
3158
-
3159
- // src/api/subscribable/shallowEqual.ts
3160
- function shallowEqual(objA, objB) {
3161
- if (objA === void 0 && objB === void 0) return true;
3162
- if (objA === void 0) return false;
3163
- if (objB === void 0) return false;
3164
- for (const key of Object.keys(objA)) {
3165
- const valueA = objA[key];
3166
- const valueB = objB[key];
3167
- if (!Object.is(valueA, valueB)) return false;
3168
- }
3169
- return true;
3170
- }
3171
-
3172
- // src/api/subscribable/ShallowMemoizeSubject.ts
3173
- var ShallowMemoizeSubject = class extends BaseSubject {
3174
- constructor(binding) {
3175
- super();
3176
- this.binding = binding;
3177
- const state = binding.getState();
3178
- if (state === void 0)
3179
- throw new Error("Entry not available in the store");
3180
- this._previousState = state;
3181
- }
3182
- _previousState;
3183
- getState = () => {
3184
- if (!this.isConnected) this._syncState();
3185
- return this._previousState;
3186
- };
3187
- _syncState() {
3188
- const state = this.binding.getState();
3189
- if (state === void 0) return false;
3190
- if (shallowEqual(state, this._previousState)) return false;
3191
- this._previousState = state;
3192
- return true;
3193
- }
3194
- _connect() {
3195
- const callback = () => {
3196
- if (this._syncState()) {
3197
- this.notifySubscribers();
3198
- }
3199
- };
3200
- return this.binding.subscribe(callback);
3201
- }
3202
- };
3203
-
3204
- // src/api/MessageRuntime.ts
3205
- var MessageRuntime = class {
3206
- constructor(_core, _threadBinding) {
3207
- this._core = _core;
3208
- this._threadBinding = _threadBinding;
3209
- }
3210
- getState() {
3211
- return this._core.getState();
3212
- }
3213
- // TODO improve type
3214
- edit(message) {
3215
- const state = this._core.getState();
3216
- if (!state) throw new Error("Message is not available");
3217
- this._threadBinding.getState().append({
3218
- ...message,
3219
- parentId: state.parentId
3220
- });
3221
- }
3222
- reload() {
3223
- const state = this._core.getState();
3224
- if (!state) throw new Error("Message is not available");
3225
- this._threadBinding.getState().startRun(state.parentId);
3226
- }
3227
- speak() {
3228
- const state = this._core.getState();
3229
- if (!state) throw new Error("Message is not available");
3230
- this._threadBinding.getState().speak(state.id);
3231
- }
3232
- submitFeedback({ type }) {
3233
- const state = this._core.getState();
3234
- if (!state) throw new Error("Message is not available");
3235
- this._threadBinding.getState().submitFeedback({
3236
- messageId: state.id,
3237
- type
3238
- });
3239
- }
3240
- switchToBranch({
3241
- position,
3242
- branchId
3243
- }) {
3244
- const state = this._core.getState();
3245
- if (!state) throw new Error("Message is not available");
3246
- if (branchId && position) {
3247
- throw new Error("May not specify both branchId and position");
3248
- } else if (!branchId && !position) {
3249
- throw new Error("Must specify either branchId or position");
3250
- }
3251
- const thread = this._threadBinding.getState();
3252
- const branches = thread.getBranches(state.id);
3253
- let targetBranch = branchId;
3254
- if (position === "previous") {
3255
- targetBranch = branches[state.branchNumber - 2];
3256
- } else if (position === "next") {
3257
- targetBranch = branches[state.branchNumber];
3258
- }
3259
- if (!targetBranch) throw new Error("Branch not found");
3260
- this._threadBinding.getState().switchToBranch(targetBranch);
3261
- }
3262
- subscribe(callback) {
3263
- return this._core.subscribe(callback);
3264
- }
3265
- getContentPartByIdx(idx) {
3266
- if (idx < 0) throw new Error("Message index must be >= 0");
3267
- return new ContentPartRuntime(
3268
- new ShallowMemoizeSubject({
3269
- getState: () => {
3270
- const state = this.getState();
3271
- if (!state) return void 0;
3272
- const message = state.message;
3273
- const part = message.content[idx];
3274
- if (!part) return void 0;
3275
- return {
3276
- part,
3277
- status: toContentPartStatus(message, idx, part)
3278
- };
3279
- },
3280
- subscribe: (callback) => this._core.subscribe(callback)
3281
- }),
3282
- this._core,
3283
- this._threadBinding
3284
- );
3285
- }
3286
- };
3287
-
3288
- // src/api/ThreadComposerRuntime.ts
3289
- var getThreadComposerState = (runtime) => {
3290
- return Object.freeze({
3291
- canCancel: runtime.canCancel,
3292
- isEmpty: runtime.isEmpty,
3293
- text: runtime.text,
3294
- attachments: runtime.attachments,
3295
- attachmentAccept: runtime.attachmentAccept
3296
- });
3297
- };
3298
- var ThreadComposerRuntime = class {
3299
- constructor(_core) {
3300
- this._core = _core;
3301
- }
3302
- /**
3303
- * @deprecated Use `getState().isEmpty` instead. This will be removed in 0.6.0.
3304
- */
3305
- get isEmpty() {
3306
- return this._core.getState().isEmpty;
3307
- }
3308
- /**
3309
- * @deprecated Use `getState().canCancel` instead. This will be removed in 0.6.0.
3310
- */
3311
- get canCancel() {
3312
- return this._core.getState().canCancel;
3313
- }
3314
- /**
3315
- * @deprecated Use `getState().text` instead. This will be removed in 0.6.0.
3316
- */
3317
- get text() {
3318
- return this._core.getState().text;
3319
- }
3320
- /**
3321
- * @deprecated Use `getState().attachmentAccept` instead. This will be removed in 0.6.0.
3322
- */
3323
- get attachmentAccept() {
3324
- return this._core.getState().attachmentAccept;
3325
- }
3326
- // TODO should this instead return getAttachmentByIndex([idx]) instead?
3327
- /**
3328
- * @deprecated Use `getState().attachments` instead. This will be removed in 0.6.0.
3329
- */
3330
- get attachments() {
3331
- return this._core.getState().attachments;
3332
- }
3333
- getState() {
3334
- return getThreadComposerState(this._core.getState());
3335
- }
3336
- setText(text) {
3337
- this._core.getState().setText(text);
3338
- }
3339
- addAttachment(file) {
3340
- return this._core.getState().addAttachment(file);
3341
- }
3342
- // /**
3343
- // * @deprecated Use `getAttachmentById(id).removeAttachment` instead. This will be removed in 0.6.0.
3344
- // */
3345
- removeAttachment(attachmentId) {
3346
- return this._core.getState().removeAttachment(attachmentId);
3347
- }
3348
- /**
3349
- * @deprecated This method will be removed in 0.6.0. Submit feedback if you need this functionality.
3350
- */
3351
- reset() {
3352
- this._core.getState().reset();
3353
- }
3354
- send() {
3355
- this._core.getState().send();
3356
- }
3357
- cancel() {
3358
- this._core.getState().cancel();
3359
- }
3360
- subscribe(callback) {
3361
- return this._core.subscribe(callback);
3362
- }
3363
- };
3364
-
3365
3500
  // src/api/ThreadRuntime.ts
3366
- var toAppendMessage = (messages, message) => {
3501
+ var toAppendMessage = (messages2, message) => {
3367
3502
  if (typeof message === "string") {
3368
3503
  return {
3369
- parentId: messages.at(-1)?.id ?? null,
3504
+ parentId: messages2.at(-1)?.id ?? null,
3370
3505
  role: "user",
3371
3506
  content: [{ type: "text", text: message }],
3372
3507
  attachments: []
@@ -3376,7 +3511,7 @@ var toAppendMessage = (messages, message) => {
3376
3511
  return message;
3377
3512
  }
3378
3513
  return {
3379
- parentId: message.parentId ?? messages.at(-1)?.id ?? null,
3514
+ parentId: message.parentId ?? messages2.at(-1)?.id ?? null,
3380
3515
  role: message.role ?? "user",
3381
3516
  content: message.content,
3382
3517
  attachments: message.attachments ?? []
@@ -3389,13 +3524,10 @@ var getThreadState = (runtime) => {
3389
3524
  capabilities: runtime.capabilities,
3390
3525
  isDisabled: runtime.isDisabled,
3391
3526
  isRunning: lastMessage?.role !== "assistant" ? false : lastMessage.status.type === "running",
3392
- unstable_synchronizer: runtime.unstable_synchronizer
3527
+ messages: runtime.messages
3393
3528
  });
3394
3529
  };
3395
3530
  var ThreadRuntime = class {
3396
- constructor(_threadBinding) {
3397
- this._threadBinding = _threadBinding;
3398
- }
3399
3531
  // public path = "assistant.threads[main]"; // TODO
3400
3532
  /**
3401
3533
  * @deprecated Use `getState().threadId` instead. This will be removed in 0.6.0.
@@ -3421,13 +3553,27 @@ var ThreadRuntime = class {
3421
3553
  get capabilities() {
3422
3554
  return this.getState().capabilities;
3423
3555
  }
3424
- // TODO this should instead return getMessageByIndex([idx])
3556
+ /**
3557
+ * @deprecated Use `getState().messages` instead. This will be removed in 0.6.0.
3558
+ */
3425
3559
  get messages() {
3426
3560
  return this._threadBinding.getState().messages;
3427
3561
  }
3428
3562
  unstable_getCore() {
3429
3563
  return this._threadBinding.getState();
3430
3564
  }
3565
+ _threadBinding;
3566
+ constructor(threadBinding) {
3567
+ const stateBinding = new LazyMemoizeSubject({
3568
+ getState: () => getThreadState(threadBinding.getState()),
3569
+ subscribe: (callback) => threadBinding.subscribe(callback)
3570
+ });
3571
+ this._threadBinding = {
3572
+ getState: () => threadBinding.getState(),
3573
+ getStateState: () => stateBinding.getState(),
3574
+ subscribe: (callback) => threadBinding.subscribe(callback)
3575
+ };
3576
+ }
3431
3577
  composer = new ThreadComposerRuntime(
3432
3578
  new NestedSubscriptionSubject({
3433
3579
  getState: () => this._threadBinding.getState().composer,
@@ -3435,7 +3581,7 @@ var ThreadRuntime = class {
3435
3581
  })
3436
3582
  );
3437
3583
  getState() {
3438
- return getThreadState(this._threadBinding.getState());
3584
+ return this._threadBinding.getStateState();
3439
3585
  }
3440
3586
  append(message) {
3441
3587
  this._threadBinding.getState().append(
@@ -3484,6 +3630,18 @@ var ThreadRuntime = class {
3484
3630
  submitFeedback(options) {
3485
3631
  return this._threadBinding.getState().submitFeedback(options);
3486
3632
  }
3633
+ /**
3634
+ * @deprecated Use `getMesssageById(id).unstable_getMessageByIndex(idx).composer` instead. This will be removed in 0.6.0.
3635
+ */
3636
+ getEditComposer(messageId) {
3637
+ return this._threadBinding.getState().getEditComposer(messageId);
3638
+ }
3639
+ /**
3640
+ * @deprecated Use `getMesssageById(id).unstable_getMessageByIndex(idx).composer.beginEdit()` instead. This will be removed in 0.6.0.
3641
+ */
3642
+ beginEdit(messageId) {
3643
+ return this._threadBinding.getState().beginEdit(messageId);
3644
+ }
3487
3645
  export() {
3488
3646
  return this._threadBinding.getState().export();
3489
3647
  }
@@ -3495,15 +3653,15 @@ var ThreadRuntime = class {
3495
3653
  return new MessageRuntime(
3496
3654
  new ShallowMemoizeSubject({
3497
3655
  getState: () => {
3498
- const messages = this.messages;
3499
- const message = messages[idx];
3500
- if (!message) return void 0;
3656
+ const messages2 = this.getState().messages;
3657
+ const message = messages2[idx];
3658
+ if (!message) return SKIP_UPDATE;
3501
3659
  const branches = this._threadBinding.getState().getBranches(message.id);
3502
3660
  return {
3503
3661
  ...message,
3504
3662
  message,
3505
- isLast: idx === messages.length - 1,
3506
- parentId: messages[idx - 1]?.id ?? null,
3663
+ isLast: idx === messages2.length - 1,
3664
+ parentId: messages2[idx - 1]?.id ?? null,
3507
3665
  branches,
3508
3666
  branchNumber: branches.indexOf(message.id) + 1,
3509
3667
  branchCount: branches.length
@@ -3518,12 +3676,12 @@ var ThreadRuntime = class {
3518
3676
 
3519
3677
  // src/runtimes/edge/converters/fromLanguageModelMessages.ts
3520
3678
  var fromLanguageModelMessages = (lm, { mergeRoundtrips }) => {
3521
- const messages = [];
3679
+ const messages2 = [];
3522
3680
  for (const lmMessage of lm) {
3523
3681
  const role = lmMessage.role;
3524
3682
  switch (role) {
3525
3683
  case "system": {
3526
- messages.push({
3684
+ messages2.push({
3527
3685
  role: "system",
3528
3686
  content: [
3529
3687
  {
@@ -3535,7 +3693,7 @@ var fromLanguageModelMessages = (lm, { mergeRoundtrips }) => {
3535
3693
  break;
3536
3694
  }
3537
3695
  case "user": {
3538
- messages.push({
3696
+ messages2.push({
3539
3697
  role: "user",
3540
3698
  content: lmMessage.content.map((part) => {
3541
3699
  const type = part.type;
@@ -3555,6 +3713,9 @@ var fromLanguageModelMessages = (lm, { mergeRoundtrips }) => {
3555
3713
  }
3556
3714
  throw new Error("Only images with URL data are supported");
3557
3715
  }
3716
+ case "file": {
3717
+ throw new Error("File content parts are not supported");
3718
+ }
3558
3719
  default: {
3559
3720
  const unhandledType = type;
3560
3721
  throw new Error(`Unknown content part type: ${unhandledType}`);
@@ -3578,20 +3739,20 @@ var fromLanguageModelMessages = (lm, { mergeRoundtrips }) => {
3578
3739
  return part;
3579
3740
  });
3580
3741
  if (mergeRoundtrips) {
3581
- const previousMessage = messages[messages.length - 1];
3742
+ const previousMessage = messages2[messages2.length - 1];
3582
3743
  if (previousMessage?.role === "assistant") {
3583
3744
  previousMessage.content.push(...newContent);
3584
3745
  break;
3585
3746
  }
3586
3747
  }
3587
- messages.push({
3748
+ messages2.push({
3588
3749
  role: "assistant",
3589
3750
  content: newContent
3590
3751
  });
3591
3752
  break;
3592
3753
  }
3593
3754
  case "tool": {
3594
- const previousMessage = messages[messages.length - 1];
3755
+ const previousMessage = messages2[messages2.length - 1];
3595
3756
  if (previousMessage?.role !== "assistant")
3596
3757
  throw new Error(
3597
3758
  "A tool message must be preceded by an assistant message."
@@ -3617,7 +3778,7 @@ var fromLanguageModelMessages = (lm, { mergeRoundtrips }) => {
3617
3778
  }
3618
3779
  }
3619
3780
  }
3620
- return messages;
3781
+ return messages2;
3621
3782
  };
3622
3783
 
3623
3784
  // src/runtimes/edge/converters/fromLanguageModelTools.ts
@@ -3680,7 +3841,7 @@ var streamUtils = {
3680
3841
  };
3681
3842
 
3682
3843
  // src/runtimes/edge/useEdgeRuntime.ts
3683
- import { useState as useState11 } from "react";
3844
+ import { useState as useState10 } from "react";
3684
3845
 
3685
3846
  // src/runtimes/edge/streams/assistantDecoderStream.ts
3686
3847
  function assistantDecoderStream() {
@@ -3775,7 +3936,7 @@ var EdgeChatAdapter = class {
3775
3936
  constructor(options) {
3776
3937
  this.options = options;
3777
3938
  }
3778
- async *run({ messages, abortSignal, config }) {
3939
+ async *run({ messages: messages2, abortSignal, config }) {
3779
3940
  const headers = new Headers(this.options.headers);
3780
3941
  headers.set("Content-Type", "application/json");
3781
3942
  const result = await fetch(this.options.api, {
@@ -3784,7 +3945,7 @@ var EdgeChatAdapter = class {
3784
3945
  credentials: this.options.credentials ?? "same-origin",
3785
3946
  body: JSON.stringify({
3786
3947
  system: config.system,
3787
- messages: toCoreMessages(messages),
3948
+ messages: toCoreMessages(messages2),
3788
3949
  tools: config.tools ? toLanguageModelTools(config.tools) : [],
3789
3950
  ...config.callSettings,
3790
3951
  ...config.config,
@@ -3812,7 +3973,7 @@ var useEdgeRuntime = ({
3812
3973
  adapters,
3813
3974
  ...options
3814
3975
  }) => {
3815
- const [adapter] = useState11(() => new EdgeChatAdapter(options));
3976
+ const [adapter] = useState10(() => new EdgeChatAdapter(options));
3816
3977
  return useLocalRuntime(adapter, {
3817
3978
  initialMessages,
3818
3979
  maxToolRoundtrips,
@@ -3823,6 +3984,43 @@ var useEdgeRuntime = ({
3823
3984
  // src/runtimes/local/shouldContinue.tsx
3824
3985
  var shouldContinue = (result) => result.status?.type === "requires-action" && result.status.reason === "tool-calls" && result.content.every((c) => c.type !== "tool-call" || !!c.result);
3825
3986
 
3987
+ // src/runtimes/composer/DefaultEditComposerRuntimeCore.tsx
3988
+ var DefaultEditComposerRuntimeCore = class extends BaseComposerRuntimeCore {
3989
+ constructor(runtime, endEditCallback, { parentId, message }) {
3990
+ super();
3991
+ this.runtime = runtime;
3992
+ this.endEditCallback = endEditCallback;
3993
+ this._parentId = parentId;
3994
+ this._previousText = getThreadMessageText(message);
3995
+ this.setText(this._previousText);
3996
+ this._nonTextParts = message.content.filter(
3997
+ (part) => part.type !== "text" && part.type !== "ui"
3998
+ );
3999
+ }
4000
+ get canCancel() {
4001
+ return true;
4002
+ }
4003
+ _nonTextParts;
4004
+ _previousText;
4005
+ _parentId;
4006
+ async handleSend(message) {
4007
+ const text = getThreadMessageText(message);
4008
+ if (text !== this._previousText) {
4009
+ this.runtime.append({
4010
+ ...message,
4011
+ content: [...message.content, ...this._nonTextParts],
4012
+ parentId: this._parentId
4013
+ });
4014
+ }
4015
+ this.endEditCallback();
4016
+ this.notifySubscribers();
4017
+ }
4018
+ async cancel() {
4019
+ this.endEditCallback();
4020
+ this.notifySubscribers();
4021
+ }
4022
+ };
4023
+
3826
4024
  // src/runtimes/local/LocalThreadRuntimeCore.tsx
3827
4025
  var LocalThreadRuntimeCore = class {
3828
4026
  constructor(configProvider, adapter, { initialMessages, ...options }) {
@@ -3832,8 +4030,8 @@ var LocalThreadRuntimeCore = class {
3832
4030
  this.options = options;
3833
4031
  if (initialMessages) {
3834
4032
  let parentId = null;
3835
- const messages = fromCoreMessages(initialMessages);
3836
- for (const message of messages) {
4033
+ const messages2 = fromCoreMessages(initialMessages);
4034
+ for (const message of messages2) {
3837
4035
  this.repository.addOrUpdateMessage(parentId, message);
3838
4036
  parentId = message.id;
3839
4037
  }
@@ -3857,7 +4055,7 @@ var LocalThreadRuntimeCore = class {
3857
4055
  get messages() {
3858
4056
  return this.repository.getMessages();
3859
4057
  }
3860
- composer = new BaseThreadComposerRuntimeCore(this);
4058
+ composer = new DefaultThreadComposerRuntimeCore(this);
3861
4059
  getModelConfig() {
3862
4060
  return this.configProvider.getModelConfig();
3863
4061
  }
@@ -3886,6 +4084,23 @@ var LocalThreadRuntimeCore = class {
3886
4084
  }
3887
4085
  if (hasUpdates) this.notifySubscribers();
3888
4086
  }
4087
+ _editComposers = /* @__PURE__ */ new Map();
4088
+ getEditComposer(messageId) {
4089
+ return this._editComposers.get(messageId);
4090
+ }
4091
+ beginEdit(messageId) {
4092
+ if (this._editComposers.has(messageId))
4093
+ throw new Error("Edit already in progress");
4094
+ this._editComposers.set(
4095
+ messageId,
4096
+ new DefaultEditComposerRuntimeCore(
4097
+ this,
4098
+ () => this._editComposers.delete(messageId),
4099
+ this.repository.getMessage(messageId)
4100
+ )
4101
+ );
4102
+ this.notifySubscribers();
4103
+ }
3889
4104
  getBranches(messageId) {
3890
4105
  return this.repository.getBranches(messageId);
3891
4106
  }
@@ -3920,7 +4135,7 @@ var LocalThreadRuntimeCore = class {
3920
4135
  } while (shouldContinue(message));
3921
4136
  }
3922
4137
  async performRoundtrip(parentId, message) {
3923
- const messages = this.repository.getMessages();
4138
+ const messages2 = this.repository.getMessages();
3924
4139
  this.abortController?.abort();
3925
4140
  this.abortController = new AbortController();
3926
4141
  const initialContent = message.content;
@@ -3975,7 +4190,7 @@ var LocalThreadRuntimeCore = class {
3975
4190
  }
3976
4191
  try {
3977
4192
  const promiseOrGenerator = this.adapter.run({
3978
- messages,
4193
+ messages: messages2,
3979
4194
  abortSignal: this.abortController.signal,
3980
4195
  config: this.configProvider.getModelConfig(),
3981
4196
  onUpdate: updateMessage
@@ -4117,10 +4332,10 @@ var LocalRuntimeCore = class extends BaseAssistantRuntimeCore {
4117
4332
  } = {}) {
4118
4333
  this.switchToThread(null);
4119
4334
  if (!initialMessages) return;
4120
- const messages = fromCoreMessages(initialMessages);
4335
+ const messages2 = fromCoreMessages(initialMessages);
4121
4336
  this.thread.import({
4122
- messages: messages.map((m, idx) => ({
4123
- parentId: messages[idx - 1]?.id ?? null,
4337
+ messages: messages2.map((m, idx) => ({
4338
+ parentId: messages2[idx - 1]?.id ?? null,
4124
4339
  message: m
4125
4340
  }))
4126
4341
  });
@@ -4138,16 +4353,16 @@ var LocalRuntime = class extends AssistantRuntime {
4138
4353
  }
4139
4354
  };
4140
4355
  var useLocalRuntime = (adapter, options = {}) => {
4141
- const [runtime] = useState12(() => new LocalRuntimeCore(adapter, options));
4356
+ const [runtime] = useState11(() => new LocalRuntimeCore(adapter, options));
4142
4357
  useInsertionEffect(() => {
4143
4358
  runtime.thread.adapter = adapter;
4144
4359
  runtime.thread.options = options;
4145
4360
  });
4146
- return useMemo7(() => new LocalRuntime(runtime), [runtime]);
4361
+ return useMemo11(() => new LocalRuntime(runtime), [runtime]);
4147
4362
  };
4148
4363
 
4149
4364
  // src/runtimes/external-store/useExternalStoreRuntime.tsx
4150
- import { useEffect as useEffect15, useMemo as useMemo8, useState as useState13 } from "react";
4365
+ import { useEffect as useEffect14, useMemo as useMemo12, useState as useState12 } from "react";
4151
4366
 
4152
4367
  // src/runtimes/external-store/getExternalStoreMessage.tsx
4153
4368
  var symbolInnerMessage = Symbol("innerMessage");
@@ -4158,8 +4373,8 @@ var getExternalStoreMessage = (message) => {
4158
4373
  // src/runtimes/external-store/ThreadMessageConverter.ts
4159
4374
  var ThreadMessageConverter = class {
4160
4375
  cache = /* @__PURE__ */ new WeakMap();
4161
- convertMessages(messages, converter) {
4162
- return messages.map((m, idx) => {
4376
+ convertMessages(messages2, converter) {
4377
+ return messages2.map((m, idx) => {
4163
4378
  const cached = this.cache.get(m);
4164
4379
  const newMessage = converter(cached, m, idx);
4165
4380
  this.cache.set(m, newMessage);
@@ -4252,8 +4467,8 @@ var fromThreadMessageLike = (like, fallbackId, fallbackStatus) => {
4252
4467
  };
4253
4468
 
4254
4469
  // src/runtimes/external-store/ExternalStoreThreadRuntimeCore.tsx
4255
- var hasUpcomingMessage = (isRunning, messages) => {
4256
- return isRunning && messages[messages.length - 1]?.role !== "assistant";
4470
+ var hasUpcomingMessage = (isRunning, messages2) => {
4471
+ return isRunning && messages2[messages2.length - 1]?.role !== "assistant";
4257
4472
  };
4258
4473
  var ExternalStoreThreadRuntimeCore = class {
4259
4474
  constructor(configProvider, store) {
@@ -4281,7 +4496,24 @@ var ExternalStoreThreadRuntimeCore = class {
4281
4496
  isDisabled;
4282
4497
  converter = new ThreadMessageConverter();
4283
4498
  _store;
4284
- composer = new BaseThreadComposerRuntimeCore(this);
4499
+ composer = new DefaultThreadComposerRuntimeCore(this);
4500
+ _editComposers = /* @__PURE__ */ new Map();
4501
+ getEditComposer(messageId) {
4502
+ return this._editComposers.get(messageId);
4503
+ }
4504
+ beginEdit(messageId) {
4505
+ if (this._editComposers.has(messageId))
4506
+ throw new Error("Edit already in progress");
4507
+ this._editComposers.set(
4508
+ messageId,
4509
+ new DefaultEditComposerRuntimeCore(
4510
+ this,
4511
+ () => this._editComposers.delete(messageId),
4512
+ this.repository.getMessage(messageId)
4513
+ )
4514
+ );
4515
+ this.notifySubscribers();
4516
+ }
4285
4517
  get store() {
4286
4518
  return this._store;
4287
4519
  }
@@ -4312,7 +4544,7 @@ var ExternalStoreThreadRuntimeCore = class {
4312
4544
  return;
4313
4545
  }
4314
4546
  }
4315
- const messages = !store.convertMessage ? store.messages : this.converter.convertMessages(store.messages, (cache, m, idx) => {
4547
+ const messages2 = !store.convertMessage ? store.messages : this.converter.convertMessages(store.messages, (cache, m, idx) => {
4316
4548
  if (!store.convertMessage) return m;
4317
4549
  const isLast = idx === store.messages.length - 1;
4318
4550
  const autoStatus = getAutoStatus(isLast, isRunning);
@@ -4326,18 +4558,18 @@ var ExternalStoreThreadRuntimeCore = class {
4326
4558
  newMessage[symbolInnerMessage] = m;
4327
4559
  return newMessage;
4328
4560
  });
4329
- for (let i = 0; i < messages.length; i++) {
4330
- const message = messages[i];
4331
- const parent = messages[i - 1];
4561
+ for (let i = 0; i < messages2.length; i++) {
4562
+ const message = messages2[i];
4563
+ const parent = messages2[i - 1];
4332
4564
  this.repository.addOrUpdateMessage(parent?.id ?? null, message);
4333
4565
  }
4334
4566
  if (this.assistantOptimisticId) {
4335
4567
  this.repository.deleteMessage(this.assistantOptimisticId);
4336
4568
  this.assistantOptimisticId = null;
4337
4569
  }
4338
- if (hasUpcomingMessage(isRunning, messages)) {
4570
+ if (hasUpcomingMessage(isRunning, messages2)) {
4339
4571
  this.assistantOptimisticId = this.repository.appendOptimisticMessage(
4340
- messages.at(-1)?.id ?? null,
4572
+ messages2.at(-1)?.id ?? null,
4341
4573
  {
4342
4574
  role: "assistant",
4343
4575
  content: []
@@ -4345,7 +4577,7 @@ var ExternalStoreThreadRuntimeCore = class {
4345
4577
  );
4346
4578
  }
4347
4579
  this.repository.resetHead(
4348
- this.assistantOptimisticId ?? messages.at(-1)?.id ?? null
4580
+ this.assistantOptimisticId ?? messages2.at(-1)?.id ?? null
4349
4581
  );
4350
4582
  this.messages = this.repository.getMessages();
4351
4583
  this.notifySubscribers();
@@ -4387,19 +4619,19 @@ var ExternalStoreThreadRuntimeCore = class {
4387
4619
  this.repository.deleteMessage(this.assistantOptimisticId);
4388
4620
  this.assistantOptimisticId = null;
4389
4621
  }
4390
- let messages = this.repository.getMessages();
4391
- const previousMessage = messages[messages.length - 1];
4392
- if (previousMessage?.role === "user" && previousMessage.id === messages.at(-1)?.id) {
4622
+ let messages2 = this.repository.getMessages();
4623
+ const previousMessage = messages2[messages2.length - 1];
4624
+ if (previousMessage?.role === "user" && previousMessage.id === messages2.at(-1)?.id) {
4393
4625
  this.repository.deleteMessage(previousMessage.id);
4394
4626
  if (!this.composer.text.trim()) {
4395
4627
  this.composer.setText(getThreadMessageText(previousMessage));
4396
4628
  }
4397
- messages = this.repository.getMessages();
4629
+ messages2 = this.repository.getMessages();
4398
4630
  } else {
4399
4631
  this.notifySubscribers();
4400
4632
  }
4401
4633
  setTimeout(() => {
4402
- this.updateMessages(messages);
4634
+ this.updateMessages(messages2);
4403
4635
  }, 0);
4404
4636
  }
4405
4637
  addToolResult(options) {
@@ -4423,9 +4655,9 @@ var ExternalStoreThreadRuntimeCore = class {
4423
4655
  this._subscriptions.add(callback);
4424
4656
  return () => this._subscriptions.delete(callback);
4425
4657
  }
4426
- updateMessages = (messages) => {
4658
+ updateMessages = (messages2) => {
4427
4659
  this._store.setMessages?.(
4428
- messages.flatMap(getExternalStoreMessage).filter((m) => m != null)
4660
+ messages2.flatMap(getExternalStoreMessage).filter((m) => m != null)
4429
4661
  );
4430
4662
  };
4431
4663
  import(repository) {
@@ -4483,21 +4715,21 @@ var ExternalStoreRuntimeCore = class extends BaseAssistantRuntimeCore {
4483
4715
 
4484
4716
  // src/runtimes/external-store/useExternalStoreRuntime.tsx
4485
4717
  var useExternalStoreRuntime = (store) => {
4486
- const [runtime] = useState13(() => new ExternalStoreRuntimeCore(store));
4487
- useEffect15(() => {
4718
+ const [runtime] = useState12(() => new ExternalStoreRuntimeCore(store));
4719
+ useEffect14(() => {
4488
4720
  runtime.thread.store = store;
4489
4721
  });
4490
- return useMemo8(() => new AssistantRuntime(runtime, ThreadRuntime), [runtime]);
4722
+ return useMemo12(() => new AssistantRuntime(runtime, ThreadRuntime), [runtime]);
4491
4723
  };
4492
4724
 
4493
4725
  // src/runtimes/external-store/external-message-converter.tsx
4494
- import { useMemo as useMemo9 } from "react";
4495
- var joinExternalMessages = (messages) => {
4726
+ import { useMemo as useMemo13 } from "react";
4727
+ var joinExternalMessages = (messages2) => {
4496
4728
  const assistantMessage = {
4497
4729
  role: "assistant",
4498
4730
  content: []
4499
4731
  };
4500
- for (const output of messages) {
4732
+ for (const output of messages2) {
4501
4733
  if (output.role === "tool") {
4502
4734
  const toolCallIdx = assistantMessage.content.findIndex(
4503
4735
  (c) => c.type === "tool-call" && c.toolCallId === output.toolCallId
@@ -4574,10 +4806,10 @@ var chunkExternalMessages = (callbackResults) => {
4574
4806
  };
4575
4807
  var useExternalMessageConverter = ({
4576
4808
  callback,
4577
- messages,
4809
+ messages: messages2,
4578
4810
  isRunning
4579
4811
  }) => {
4580
- const state = useMemo9(
4812
+ const state = useMemo13(
4581
4813
  () => ({
4582
4814
  callback,
4583
4815
  callbackCache: /* @__PURE__ */ new WeakMap(),
@@ -4586,9 +4818,9 @@ var useExternalMessageConverter = ({
4586
4818
  }),
4587
4819
  [callback]
4588
4820
  );
4589
- return useMemo9(() => {
4821
+ return useMemo13(() => {
4590
4822
  const callbackResults = [];
4591
- for (const message of messages) {
4823
+ for (const message of messages2) {
4592
4824
  let result = state.callbackCache.get(message);
4593
4825
  if (!result) {
4594
4826
  const output = state.callback(message);
@@ -4626,7 +4858,7 @@ var useExternalMessageConverter = ({
4626
4858
  return newMessage;
4627
4859
  }
4628
4860
  );
4629
- }, [state, messages, isRunning]);
4861
+ }, [state, messages2, isRunning]);
4630
4862
  };
4631
4863
  var shallowArrayEqual = (a, b) => {
4632
4864
  if (a.length !== b.length) return false;
@@ -4637,20 +4869,20 @@ var shallowArrayEqual = (a, b) => {
4637
4869
  };
4638
4870
 
4639
4871
  // src/runtimes/dangerous-in-browser/useDangerousInBrowserRuntime.ts
4640
- import { useState as useState14 } from "react";
4872
+ import { useState as useState13 } from "react";
4641
4873
 
4642
4874
  // src/runtimes/dangerous-in-browser/DangerousInBrowserAdapter.ts
4643
4875
  var DangerousInBrowserAdapter = class {
4644
4876
  constructor(options) {
4645
4877
  this.options = options;
4646
4878
  }
4647
- async *run({ messages, abortSignal, config }) {
4879
+ async *run({ messages: messages2, abortSignal, config }) {
4648
4880
  const res = await getEdgeRuntimeStream({
4649
4881
  options: this.options,
4650
4882
  abortSignal,
4651
4883
  requestData: {
4652
4884
  system: config.system,
4653
- messages: toCoreMessages(messages),
4885
+ messages: toCoreMessages(messages2),
4654
4886
  tools: config.tools ? toLanguageModelTools(config.tools) : [],
4655
4887
  ...config.callSettings,
4656
4888
  ...config.config
@@ -4668,7 +4900,7 @@ var useDangerousInBrowserRuntime = ({
4668
4900
  initialMessages,
4669
4901
  ...options
4670
4902
  }) => {
4671
- const [adapter] = useState14(() => new DangerousInBrowserAdapter(options));
4903
+ const [adapter] = useState13(() => new DangerousInBrowserAdapter(options));
4672
4904
  return useLocalRuntime(adapter, { initialMessages });
4673
4905
  };
4674
4906
 
@@ -4721,12 +4953,15 @@ var SimpleImageAttachmentAdapter = class {
4721
4953
  id: state.file.name,
4722
4954
  type: "image",
4723
4955
  name: state.file.name,
4724
- file: state.file
4956
+ contentType: state.file.type,
4957
+ file: state.file,
4958
+ status: { type: "requires-action", reason: "composer-send" }
4725
4959
  };
4726
4960
  }
4727
4961
  async send(attachment) {
4728
4962
  return {
4729
4963
  ...attachment,
4964
+ status: { type: "complete" },
4730
4965
  content: [
4731
4966
  {
4732
4967
  type: "image",
@@ -4753,12 +4988,15 @@ var SimpleTextAttachmentAdapter = class {
4753
4988
  id: state.file.name,
4754
4989
  type: "document",
4755
4990
  name: state.file.name,
4756
- file: state.file
4991
+ contentType: state.file.type,
4992
+ file: state.file,
4993
+ status: { type: "requires-action", reason: "composer-send" }
4757
4994
  };
4758
4995
  }
4759
4996
  async send(attachment) {
4760
4997
  return {
4761
4998
  ...attachment,
4999
+ status: { type: "complete" },
4762
5000
  content: [
4763
5001
  {
4764
5002
  type: "text",
@@ -4841,7 +5079,14 @@ var CompositeAttachmentAdapter = class {
4841
5079
  async remove(attachment) {
4842
5080
  const adapters = this._adapters.slice();
4843
5081
  for (const adapter of adapters) {
4844
- if (fileMatchesAccept(attachment.file, adapter.accept)) {
5082
+ if (fileMatchesAccept(
5083
+ {
5084
+ name: attachment.name,
5085
+ type: attachment.contentType ?? "unknown/unknown"
5086
+ // TODO remove after 0.6.0
5087
+ },
5088
+ adapter.accept
5089
+ )) {
4845
5090
  return adapter.remove(attachment);
4846
5091
  }
4847
5092
  }
@@ -4854,7 +5099,7 @@ import {
4854
5099
  createContext as createContext7,
4855
5100
  useContext as useContext4
4856
5101
  } from "react";
4857
- import { Fragment as Fragment3, jsx as jsx37 } from "react/jsx-runtime";
5102
+ import { Fragment as Fragment3, jsx as jsx36 } from "react/jsx-runtime";
4858
5103
  var ThreadConfigContext = createContext7({});
4859
5104
  var useThreadConfig = () => {
4860
5105
  return useContext4(ThreadConfigContext);
@@ -4864,14 +5109,14 @@ var ThreadConfigProvider = ({
4864
5109
  config
4865
5110
  }) => {
4866
5111
  const hasAssistant = !!useAssistantRuntime({ optional: true });
4867
- const configProvider = config && Object.keys(config ?? {}).length > 0 ? /* @__PURE__ */ jsx37(ThreadConfigContext.Provider, { value: config, children }) : /* @__PURE__ */ jsx37(Fragment3, { children });
5112
+ const configProvider = config && Object.keys(config ?? {}).length > 0 ? /* @__PURE__ */ jsx36(ThreadConfigContext.Provider, { value: config, children }) : /* @__PURE__ */ jsx36(Fragment3, { children });
4868
5113
  if (!config?.runtime) return configProvider;
4869
5114
  if (hasAssistant) {
4870
5115
  throw new Error(
4871
5116
  "You provided a runtime to <Thread> while simulataneously using <AssistantRuntimeProvider>. This is not allowed."
4872
5117
  );
4873
5118
  }
4874
- return /* @__PURE__ */ jsx37(AssistantRuntimeProvider, { runtime: config.runtime, children: configProvider });
5119
+ return /* @__PURE__ */ jsx36(AssistantRuntimeProvider, { runtime: config.runtime, children: configProvider });
4875
5120
  };
4876
5121
  ThreadConfigProvider.displayName = "ThreadConfigProvider";
4877
5122
 
@@ -4886,7 +5131,7 @@ import {
4886
5131
  ThumbsDownIcon,
4887
5132
  ThumbsUpIcon
4888
5133
  } from "lucide-react";
4889
- import { Fragment as Fragment4, jsx as jsx38, jsxs as jsxs4 } from "react/jsx-runtime";
5134
+ import { Fragment as Fragment4, jsx as jsx37, jsxs as jsxs3 } from "react/jsx-runtime";
4890
5135
  var useAllowCopy = (ensureCapability = false) => {
4891
5136
  const { assistantMessage: { allowCopy = true } = {} } = useThreadConfig();
4892
5137
  const copySupported = useThread((t) => t.capabilities.unstable_copy);
@@ -4920,18 +5165,18 @@ var AssistantActionBar = () => {
4920
5165
  const allowFeedbackNegative = useAllowFeedbackNegative(true);
4921
5166
  if (!allowCopy && !allowReload && !allowSpeak && !allowFeedbackPositive && !allowFeedbackNegative)
4922
5167
  return null;
4923
- return /* @__PURE__ */ jsxs4(
5168
+ return /* @__PURE__ */ jsxs3(
4924
5169
  AssistantActionBarRoot,
4925
5170
  {
4926
5171
  hideWhenRunning: true,
4927
5172
  autohide: "not-last",
4928
5173
  autohideFloat: "single-branch",
4929
5174
  children: [
4930
- allowSpeak && /* @__PURE__ */ jsx38(AssistantActionBarSpeechControl, {}),
4931
- allowCopy && /* @__PURE__ */ jsx38(AssistantActionBarCopy, {}),
4932
- allowReload && /* @__PURE__ */ jsx38(AssistantActionBarReload, {}),
4933
- allowFeedbackPositive && /* @__PURE__ */ jsx38(AssistantActionBarFeedbackPositive, {}),
4934
- allowFeedbackNegative && /* @__PURE__ */ jsx38(AssistantActionBarFeedbackNegative, {})
5175
+ allowSpeak && /* @__PURE__ */ jsx37(AssistantActionBarSpeechControl, {}),
5176
+ allowCopy && /* @__PURE__ */ jsx37(AssistantActionBarCopy, {}),
5177
+ allowReload && /* @__PURE__ */ jsx37(AssistantActionBarReload, {}),
5178
+ allowFeedbackPositive && /* @__PURE__ */ jsx37(AssistantActionBarFeedbackPositive, {}),
5179
+ allowFeedbackNegative && /* @__PURE__ */ jsx37(AssistantActionBarFeedbackNegative, {})
4935
5180
  ]
4936
5181
  }
4937
5182
  );
@@ -4947,16 +5192,16 @@ var AssistantActionBarCopy = forwardRef22((props, ref) => {
4947
5192
  assistantMessage: { copy: { tooltip = "Copy" } = {} } = {}
4948
5193
  } = {}
4949
5194
  } = useThreadConfig();
4950
- return /* @__PURE__ */ jsx38(actionBar_exports.Copy, { asChild: true, children: /* @__PURE__ */ jsx38(TooltipIconButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsxs4(Fragment4, { children: [
4951
- /* @__PURE__ */ jsx38(message_exports.If, { copied: true, children: /* @__PURE__ */ jsx38(CheckIcon, {}) }),
4952
- /* @__PURE__ */ jsx38(message_exports.If, { copied: false, children: /* @__PURE__ */ jsx38(CopyIcon, {}) })
5195
+ return /* @__PURE__ */ jsx37(actionBar_exports.Copy, { asChild: true, children: /* @__PURE__ */ jsx37(TooltipIconButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsxs3(Fragment4, { children: [
5196
+ /* @__PURE__ */ jsx37(message_exports.If, { copied: true, children: /* @__PURE__ */ jsx37(CheckIcon, {}) }),
5197
+ /* @__PURE__ */ jsx37(message_exports.If, { copied: false, children: /* @__PURE__ */ jsx37(CopyIcon, {}) })
4953
5198
  ] }) }) });
4954
5199
  });
4955
5200
  AssistantActionBarCopy.displayName = "AssistantActionBarCopy";
4956
5201
  var AssistantActionBarSpeechControl = () => {
4957
- return /* @__PURE__ */ jsxs4(Fragment4, { children: [
4958
- /* @__PURE__ */ jsx38(message_exports.If, { speaking: false, children: /* @__PURE__ */ jsx38(AssistantActionBarSpeak, {}) }),
4959
- /* @__PURE__ */ jsx38(message_exports.If, { speaking: true, children: /* @__PURE__ */ jsx38(AssistantActionBarStopSpeaking, {}) })
5202
+ return /* @__PURE__ */ jsxs3(Fragment4, { children: [
5203
+ /* @__PURE__ */ jsx37(message_exports.If, { speaking: false, children: /* @__PURE__ */ jsx37(AssistantActionBarSpeak, {}) }),
5204
+ /* @__PURE__ */ jsx37(message_exports.If, { speaking: true, children: /* @__PURE__ */ jsx37(AssistantActionBarStopSpeaking, {}) })
4960
5205
  ] });
4961
5206
  };
4962
5207
  var AssistantActionBarSpeak = forwardRef22((props, ref) => {
@@ -4966,7 +5211,7 @@ var AssistantActionBarSpeak = forwardRef22((props, ref) => {
4966
5211
  } = {}
4967
5212
  } = useThreadConfig();
4968
5213
  const allowSpeak = useAllowSpeak();
4969
- return /* @__PURE__ */ jsx38(actionBar_exports.Speak, { disabled: !allowSpeak, asChild: true, children: /* @__PURE__ */ jsx38(TooltipIconButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx38(AudioLinesIcon, {}) }) });
5214
+ return /* @__PURE__ */ jsx37(actionBar_exports.Speak, { disabled: !allowSpeak, asChild: true, children: /* @__PURE__ */ jsx37(TooltipIconButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx37(AudioLinesIcon, {}) }) });
4970
5215
  });
4971
5216
  AssistantActionBarSpeak.displayName = "AssistantActionBarSpeak";
4972
5217
  var AssistantActionBarStopSpeaking = forwardRef22((props, ref) => {
@@ -4978,7 +5223,7 @@ var AssistantActionBarStopSpeaking = forwardRef22((props, ref) => {
4978
5223
  } = {}
4979
5224
  } = useThreadConfig();
4980
5225
  const allowSpeak = useAllowSpeak();
4981
- return /* @__PURE__ */ jsx38(actionBar_exports.StopSpeaking, { disabled: !allowSpeak, asChild: true, children: /* @__PURE__ */ jsx38(TooltipIconButton, { tooltip: stopTooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx38(StopCircleIcon, {}) }) });
5226
+ return /* @__PURE__ */ jsx37(actionBar_exports.StopSpeaking, { disabled: !allowSpeak, asChild: true, children: /* @__PURE__ */ jsx37(TooltipIconButton, { tooltip: stopTooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx37(StopCircleIcon, {}) }) });
4982
5227
  });
4983
5228
  AssistantActionBarStopSpeaking.displayName = "AssistantActionBarStopSpeaking";
4984
5229
  var AssistantActionBarReload = forwardRef22((props, ref) => {
@@ -4988,7 +5233,7 @@ var AssistantActionBarReload = forwardRef22((props, ref) => {
4988
5233
  } = {}
4989
5234
  } = useThreadConfig();
4990
5235
  const allowReload = useAllowReload();
4991
- return /* @__PURE__ */ jsx38(actionBar_exports.Reload, { disabled: !allowReload, asChild: true, children: /* @__PURE__ */ jsx38(TooltipIconButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx38(RefreshCwIcon, {}) }) });
5236
+ return /* @__PURE__ */ jsx37(actionBar_exports.Reload, { disabled: !allowReload, asChild: true, children: /* @__PURE__ */ jsx37(TooltipIconButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx37(RefreshCwIcon, {}) }) });
4992
5237
  });
4993
5238
  AssistantActionBarReload.displayName = "AssistantActionBarReload";
4994
5239
  var AssistantActionBarFeedbackPositive = forwardRef22((props, ref) => {
@@ -5000,13 +5245,13 @@ var AssistantActionBarFeedbackPositive = forwardRef22((props, ref) => {
5000
5245
  } = {}
5001
5246
  } = useThreadConfig();
5002
5247
  const allowFeedbackPositive = useAllowFeedbackPositive();
5003
- return /* @__PURE__ */ jsx38(
5248
+ return /* @__PURE__ */ jsx37(
5004
5249
  actionBar_exports.FeedbackPositive,
5005
5250
  {
5006
5251
  disabled: !allowFeedbackPositive,
5007
5252
  className: "aui-assistant-action-bar-feedback-positive",
5008
5253
  asChild: true,
5009
- children: /* @__PURE__ */ jsx38(TooltipIconButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx38(ThumbsUpIcon, {}) })
5254
+ children: /* @__PURE__ */ jsx37(TooltipIconButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx37(ThumbsUpIcon, {}) })
5010
5255
  }
5011
5256
  );
5012
5257
  });
@@ -5020,13 +5265,13 @@ var AssistantActionBarFeedbackNegative = forwardRef22((props, ref) => {
5020
5265
  } = {}
5021
5266
  } = useThreadConfig();
5022
5267
  const allowFeedbackNegative = useAllowFeedbackNegative();
5023
- return /* @__PURE__ */ jsx38(
5268
+ return /* @__PURE__ */ jsx37(
5024
5269
  actionBar_exports.FeedbackNegative,
5025
5270
  {
5026
5271
  disabled: !allowFeedbackNegative,
5027
5272
  className: "aui-assistant-action-bar-feedback-negative",
5028
5273
  asChild: true,
5029
- children: /* @__PURE__ */ jsx38(TooltipIconButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx38(ThumbsDownIcon, {}) })
5274
+ children: /* @__PURE__ */ jsx37(TooltipIconButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx37(ThumbsDownIcon, {}) })
5030
5275
  }
5031
5276
  );
5032
5277
  });
@@ -5047,24 +5292,24 @@ var assistant_action_bar_default = Object.assign(
5047
5292
  );
5048
5293
 
5049
5294
  // src/ui/assistant-message.tsx
5050
- import { forwardRef as forwardRef24, useMemo as useMemo10 } from "react";
5295
+ import { forwardRef as forwardRef24, useMemo as useMemo14 } from "react";
5051
5296
 
5052
5297
  // src/ui/branch-picker.tsx
5053
5298
  import { forwardRef as forwardRef23 } from "react";
5054
5299
  import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
5055
- import { jsx as jsx39, jsxs as jsxs5 } from "react/jsx-runtime";
5300
+ import { jsx as jsx38, jsxs as jsxs4 } from "react/jsx-runtime";
5056
5301
  var useAllowBranchPicker = (ensureCapability = false) => {
5057
5302
  const { branchPicker: { allowBranchPicker = true } = {} } = useThreadConfig();
5058
5303
  const branchPickerSupported = useThread((t) => t.capabilities.edit);
5059
5304
  return allowBranchPicker && (!ensureCapability || branchPickerSupported);
5060
5305
  };
5061
5306
  var BranchPicker = () => {
5062
- const allowBranchPicker = useAllowBranchPicker();
5307
+ const allowBranchPicker = useAllowBranchPicker(true);
5063
5308
  if (!allowBranchPicker) return null;
5064
- return /* @__PURE__ */ jsxs5(BranchPickerRoot, { hideWhenSingleBranch: true, children: [
5065
- /* @__PURE__ */ jsx39(BranchPickerPrevious2, {}),
5066
- /* @__PURE__ */ jsx39(BranchPickerState, {}),
5067
- /* @__PURE__ */ jsx39(BranchPickerNext, {})
5309
+ return /* @__PURE__ */ jsxs4(BranchPickerRoot, { hideWhenSingleBranch: true, children: [
5310
+ /* @__PURE__ */ jsx38(BranchPickerPrevious2, {}),
5311
+ /* @__PURE__ */ jsx38(BranchPickerState, {}),
5312
+ /* @__PURE__ */ jsx38(BranchPickerNext, {})
5068
5313
  ] });
5069
5314
  };
5070
5315
  BranchPicker.displayName = "BranchPicker";
@@ -5079,17 +5324,17 @@ var BranchPickerPrevious2 = forwardRef23((props, ref) => {
5079
5324
  } = {}
5080
5325
  } = useThreadConfig();
5081
5326
  const allowBranchPicker = useAllowBranchPicker();
5082
- return /* @__PURE__ */ jsx39(branchPicker_exports.Previous, { disabled: !allowBranchPicker, asChild: true, children: /* @__PURE__ */ jsx39(TooltipIconButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx39(ChevronLeftIcon, {}) }) });
5327
+ return /* @__PURE__ */ jsx38(branchPicker_exports.Previous, { disabled: !allowBranchPicker, asChild: true, children: /* @__PURE__ */ jsx38(TooltipIconButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx38(ChevronLeftIcon, {}) }) });
5083
5328
  });
5084
5329
  BranchPickerPrevious2.displayName = "BranchPickerPrevious";
5085
5330
  var BranchPickerStateWrapper = withDefaults("span", {
5086
5331
  className: "aui-branch-picker-state"
5087
5332
  });
5088
5333
  var BranchPickerState = forwardRef23((props, ref) => {
5089
- return /* @__PURE__ */ jsxs5(BranchPickerStateWrapper, { ...props, ref, children: [
5090
- /* @__PURE__ */ jsx39(branchPicker_exports.Number, {}),
5334
+ return /* @__PURE__ */ jsxs4(BranchPickerStateWrapper, { ...props, ref, children: [
5335
+ /* @__PURE__ */ jsx38(branchPicker_exports.Number, {}),
5091
5336
  " / ",
5092
- /* @__PURE__ */ jsx39(branchPicker_exports.Count, {})
5337
+ /* @__PURE__ */ jsx38(branchPicker_exports.Count, {})
5093
5338
  ] });
5094
5339
  });
5095
5340
  BranchPickerState.displayName = "BranchPickerState";
@@ -5098,7 +5343,7 @@ var BranchPickerNext = forwardRef23((props, ref) => {
5098
5343
  strings: { branchPicker: { next: { tooltip = "Next" } = {} } = {} } = {}
5099
5344
  } = useThreadConfig();
5100
5345
  const allowBranchPicker = useAllowBranchPicker();
5101
- return /* @__PURE__ */ jsx39(branchPicker_exports.Next, { disabled: !allowBranchPicker, asChild: true, children: /* @__PURE__ */ jsx39(TooltipIconButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx39(ChevronRightIcon, {}) }) });
5346
+ return /* @__PURE__ */ jsx38(branchPicker_exports.Next, { disabled: !allowBranchPicker, asChild: true, children: /* @__PURE__ */ jsx38(TooltipIconButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx38(ChevronRightIcon, {}) }) });
5102
5347
  });
5103
5348
  BranchPickerNext.displayName = "BranchPickerNext";
5104
5349
  var exports2 = {
@@ -5110,12 +5355,12 @@ var branch_picker_default = Object.assign(BranchPicker, exports2);
5110
5355
 
5111
5356
  // src/ui/base/avatar.tsx
5112
5357
  import * as AvatarPrimitive from "@radix-ui/react-avatar";
5113
- import { jsx as jsx40, jsxs as jsxs6 } from "react/jsx-runtime";
5358
+ import { jsx as jsx39, jsxs as jsxs5 } from "react/jsx-runtime";
5114
5359
  var Avatar = ({ src, alt, fallback }) => {
5115
5360
  if (src == null && fallback == null) return null;
5116
- return /* @__PURE__ */ jsxs6(AvatarRoot, { children: [
5117
- src != null && /* @__PURE__ */ jsx40(AvatarImage, { src, alt }),
5118
- fallback != null && /* @__PURE__ */ jsx40(AvatarFallback, { children: fallback })
5361
+ return /* @__PURE__ */ jsxs5(AvatarRoot, { children: [
5362
+ src != null && /* @__PURE__ */ jsx39(AvatarImage, { src, alt }),
5363
+ fallback != null && /* @__PURE__ */ jsx39(AvatarFallback, { children: fallback })
5119
5364
  ] });
5120
5365
  };
5121
5366
  Avatar.displayName = "Avatar";
@@ -5134,10 +5379,10 @@ AvatarFallback.displayName = "AvatarFallback";
5134
5379
 
5135
5380
  // src/ui/content-part.tsx
5136
5381
  import classNames2 from "classnames";
5137
- import { jsx as jsx41 } from "react/jsx-runtime";
5382
+ import { jsx as jsx40 } from "react/jsx-runtime";
5138
5383
  var Text = () => {
5139
5384
  const status = useSmoothStatus();
5140
- return /* @__PURE__ */ jsx41(
5385
+ return /* @__PURE__ */ jsx40(
5141
5386
  contentPart_exports.Text,
5142
5387
  {
5143
5388
  className: classNames2(
@@ -5152,19 +5397,19 @@ var exports3 = { Text: withSmoothContextProvider(Text) };
5152
5397
  var content_part_default = exports3;
5153
5398
 
5154
5399
  // src/ui/assistant-message.tsx
5155
- import { jsx as jsx42, jsxs as jsxs7 } from "react/jsx-runtime";
5400
+ import { jsx as jsx41, jsxs as jsxs6 } from "react/jsx-runtime";
5156
5401
  var AssistantMessage = () => {
5157
- return /* @__PURE__ */ jsxs7(AssistantMessageRoot, { children: [
5158
- /* @__PURE__ */ jsx42(AssistantMessageAvatar, {}),
5159
- /* @__PURE__ */ jsx42(AssistantMessageContent, {}),
5160
- /* @__PURE__ */ jsx42(branch_picker_default, {}),
5161
- /* @__PURE__ */ jsx42(assistant_action_bar_default, {})
5402
+ return /* @__PURE__ */ jsxs6(AssistantMessageRoot, { children: [
5403
+ /* @__PURE__ */ jsx41(AssistantMessageAvatar, {}),
5404
+ /* @__PURE__ */ jsx41(AssistantMessageContent, {}),
5405
+ /* @__PURE__ */ jsx41(branch_picker_default, {}),
5406
+ /* @__PURE__ */ jsx41(assistant_action_bar_default, {})
5162
5407
  ] });
5163
5408
  };
5164
5409
  AssistantMessage.displayName = "AssistantMessage";
5165
5410
  var AssistantMessageAvatar = () => {
5166
5411
  const { assistantAvatar: avatar = { fallback: "A" } } = useThreadConfig();
5167
- return /* @__PURE__ */ jsx42(Avatar, { ...avatar });
5412
+ return /* @__PURE__ */ jsx41(Avatar, { ...avatar });
5168
5413
  };
5169
5414
  var AssistantMessageRoot = withDefaults(message_exports.Root, {
5170
5415
  className: "aui-assistant-message-root"
@@ -5175,7 +5420,7 @@ var AssistantMessageContentWrapper = withDefaults("div", {
5175
5420
  });
5176
5421
  var AssistantMessageContent = forwardRef24(({ components: componentsProp, ...rest }, ref) => {
5177
5422
  const { tools, assistantMessage: { components = {} } = {} } = useThreadConfig();
5178
- const toolsComponents = useMemo10(
5423
+ const toolsComponents = useMemo14(
5179
5424
  () => ({
5180
5425
  by_name: !tools ? void 0 : Object.fromEntries(
5181
5426
  tools.map((t) => [
@@ -5188,7 +5433,7 @@ var AssistantMessageContent = forwardRef24(({ components: componentsProp, ...res
5188
5433
  // eslint-disable-next-line react-hooks/exhaustive-deps
5189
5434
  [...tools ?? [], components.ToolFallback]
5190
5435
  );
5191
- return /* @__PURE__ */ jsx42(AssistantMessageContentWrapper, { ...rest, ref, children: /* @__PURE__ */ jsx42(
5436
+ return /* @__PURE__ */ jsx41(AssistantMessageContentWrapper, { ...rest, ref, children: /* @__PURE__ */ jsx41(
5192
5437
  message_exports.Content,
5193
5438
  {
5194
5439
  components: {
@@ -5223,9 +5468,9 @@ import { forwardRef as forwardRef26 } from "react";
5223
5468
  import { PaperclipIcon, SendHorizontalIcon } from "lucide-react";
5224
5469
 
5225
5470
  // src/ui/base/CircleStopIcon.tsx
5226
- import { jsx as jsx43 } from "react/jsx-runtime";
5471
+ import { jsx as jsx42 } from "react/jsx-runtime";
5227
5472
  var CircleStopIcon = () => {
5228
- return /* @__PURE__ */ jsx43(
5473
+ return /* @__PURE__ */ jsx42(
5229
5474
  "svg",
5230
5475
  {
5231
5476
  xmlns: "http://www.w3.org/2000/svg",
@@ -5233,7 +5478,7 @@ var CircleStopIcon = () => {
5233
5478
  fill: "currentColor",
5234
5479
  width: "16",
5235
5480
  height: "16",
5236
- children: /* @__PURE__ */ jsx43("rect", { width: "10", height: "10", x: "3", y: "3", rx: "2" })
5481
+ children: /* @__PURE__ */ jsx42("rect", { width: "10", height: "10", x: "3", y: "3", rx: "2" })
5237
5482
  }
5238
5483
  );
5239
5484
  };
@@ -5242,17 +5487,17 @@ CircleStopIcon.displayName = "CircleStopIcon";
5242
5487
  // src/ui/composer-attachment.tsx
5243
5488
  import { forwardRef as forwardRef25 } from "react";
5244
5489
  import { CircleXIcon } from "lucide-react";
5245
- import { jsx as jsx44, jsxs as jsxs8 } from "react/jsx-runtime";
5490
+ import { jsx as jsx43, jsxs as jsxs7 } from "react/jsx-runtime";
5246
5491
  var ComposerAttachmentRoot = withDefaults("div", {
5247
5492
  className: "aui-composer-attachment-root"
5248
5493
  });
5249
5494
  ComposerAttachmentRoot.displayName = "ComposerAttachmentRoot";
5250
5495
  var ComposerAttachment2 = () => {
5251
- const attachment = useComposerAttachment((a) => a.attachment);
5252
- return /* @__PURE__ */ jsxs8(ComposerAttachmentRoot, { children: [
5496
+ const attachment = useThreadComposerAttachment((a) => a.attachment);
5497
+ return /* @__PURE__ */ jsxs7(ComposerAttachmentRoot, { children: [
5253
5498
  ".",
5254
5499
  attachment.name.split(".").pop(),
5255
- /* @__PURE__ */ jsx44(ComposerAttachmentRemove, {})
5500
+ /* @__PURE__ */ jsx43(ComposerAttachmentRemove, {})
5256
5501
  ] });
5257
5502
  };
5258
5503
  ComposerAttachment2.displayName = "ComposerAttachment";
@@ -5262,12 +5507,11 @@ var ComposerAttachmentRemove = forwardRef25((props, ref) => {
5262
5507
  composer: { removeAttachment: { tooltip = "Remove file" } = {} } = {}
5263
5508
  } = {}
5264
5509
  } = useThreadConfig();
5265
- const composerStore = useThreadComposerStore();
5266
- const attachmentStore = useAttachmentStore();
5510
+ const attachmentRuntime = useAttachmentRuntime();
5267
5511
  const handleRemoveAttachment = () => {
5268
- composerStore.getState().removeAttachment(attachmentStore.getState().attachment.id);
5512
+ attachmentRuntime.remove();
5269
5513
  };
5270
- return /* @__PURE__ */ jsx44(
5514
+ return /* @__PURE__ */ jsx43(
5271
5515
  TooltipIconButton,
5272
5516
  {
5273
5517
  tooltip,
@@ -5276,7 +5520,7 @@ var ComposerAttachmentRemove = forwardRef25((props, ref) => {
5276
5520
  ...props,
5277
5521
  onClick: handleRemoveAttachment,
5278
5522
  ref,
5279
- children: props.children ?? /* @__PURE__ */ jsx44(CircleXIcon, {})
5523
+ children: props.children ?? /* @__PURE__ */ jsx43(CircleXIcon, {})
5280
5524
  }
5281
5525
  );
5282
5526
  });
@@ -5291,7 +5535,7 @@ var composer_attachment_default = Object.assign(
5291
5535
  );
5292
5536
 
5293
5537
  // src/ui/composer.tsx
5294
- import { Fragment as Fragment5, jsx as jsx45, jsxs as jsxs9 } from "react/jsx-runtime";
5538
+ import { Fragment as Fragment5, jsx as jsx44, jsxs as jsxs8 } from "react/jsx-runtime";
5295
5539
  var useAllowAttachments = (ensureCapability = false) => {
5296
5540
  const { composer: { allowAttachments = true } = {} } = useThreadConfig();
5297
5541
  const attachmentsSupported = useThread((t) => t.capabilities.attachments);
@@ -5299,11 +5543,11 @@ var useAllowAttachments = (ensureCapability = false) => {
5299
5543
  };
5300
5544
  var Composer = () => {
5301
5545
  const allowAttachments = useAllowAttachments(true);
5302
- return /* @__PURE__ */ jsxs9(ComposerRoot, { children: [
5303
- allowAttachments && /* @__PURE__ */ jsx45(ComposerAttachments, {}),
5304
- allowAttachments && /* @__PURE__ */ jsx45(ComposerAddAttachment, {}),
5305
- /* @__PURE__ */ jsx45(ComposerInput, { autoFocus: true }),
5306
- /* @__PURE__ */ jsx45(ComposerAction, {})
5546
+ return /* @__PURE__ */ jsxs8(ComposerRoot, { children: [
5547
+ allowAttachments && /* @__PURE__ */ jsx44(ComposerAttachments, {}),
5548
+ allowAttachments && /* @__PURE__ */ jsx44(ComposerAddAttachment, {}),
5549
+ /* @__PURE__ */ jsx44(ComposerInput, { autoFocus: true }),
5550
+ /* @__PURE__ */ jsx44(ComposerAction, {})
5307
5551
  ] });
5308
5552
  };
5309
5553
  Composer.displayName = "Composer";
@@ -5323,7 +5567,7 @@ var ComposerInput = forwardRef26(
5323
5567
  composer: { input: { placeholder = "Write a message..." } = {} } = {}
5324
5568
  } = {}
5325
5569
  } = useThreadConfig();
5326
- return /* @__PURE__ */ jsx45(ComposerInputStyled, { placeholder, ...props, ref });
5570
+ return /* @__PURE__ */ jsx44(ComposerInputStyled, { placeholder, ...props, ref });
5327
5571
  }
5328
5572
  );
5329
5573
  ComposerInput.displayName = "ComposerInput";
@@ -5331,7 +5575,7 @@ var ComposerAttachmentsContainer = withDefaults("div", {
5331
5575
  className: "aui-composer-attachments"
5332
5576
  });
5333
5577
  var ComposerAttachments = ({ components }) => {
5334
- return /* @__PURE__ */ jsx45(ComposerAttachmentsContainer, { children: /* @__PURE__ */ jsx45(
5578
+ return /* @__PURE__ */ jsx44(ComposerAttachmentsContainer, { children: /* @__PURE__ */ jsx44(
5335
5579
  composer_exports.Attachments,
5336
5580
  {
5337
5581
  components: {
@@ -5352,14 +5596,14 @@ var ComposerAddAttachment = forwardRef26((props, ref) => {
5352
5596
  } = {}
5353
5597
  } = useThreadConfig();
5354
5598
  const allowAttachments = useAllowAttachments();
5355
- return /* @__PURE__ */ jsx45(composer_exports.AddAttachment, { disabled: !allowAttachments, asChild: true, children: /* @__PURE__ */ jsx45(
5599
+ return /* @__PURE__ */ jsx44(composer_exports.AddAttachment, { disabled: !allowAttachments, asChild: true, children: /* @__PURE__ */ jsx44(
5356
5600
  ComposerAttachButton,
5357
5601
  {
5358
5602
  tooltip,
5359
5603
  variant: "ghost",
5360
5604
  ...props,
5361
5605
  ref,
5362
- children: props.children ?? /* @__PURE__ */ jsx45(PaperclipIcon, {})
5606
+ children: props.children ?? /* @__PURE__ */ jsx44(PaperclipIcon, {})
5363
5607
  }
5364
5608
  ) });
5365
5609
  });
@@ -5370,10 +5614,10 @@ var useAllowCancel = () => {
5370
5614
  };
5371
5615
  var ComposerAction = () => {
5372
5616
  const allowCancel = useAllowCancel();
5373
- if (!allowCancel) return /* @__PURE__ */ jsx45(ComposerSend, {});
5374
- return /* @__PURE__ */ jsxs9(Fragment5, { children: [
5375
- /* @__PURE__ */ jsx45(thread_exports.If, { running: false, children: /* @__PURE__ */ jsx45(ComposerSend, {}) }),
5376
- /* @__PURE__ */ jsx45(thread_exports.If, { running: true, children: /* @__PURE__ */ jsx45(ComposerCancel, {}) })
5617
+ if (!allowCancel) return /* @__PURE__ */ jsx44(ComposerSend, {});
5618
+ return /* @__PURE__ */ jsxs8(Fragment5, { children: [
5619
+ /* @__PURE__ */ jsx44(thread_exports.If, { running: false, children: /* @__PURE__ */ jsx44(ComposerSend, {}) }),
5620
+ /* @__PURE__ */ jsx44(thread_exports.If, { running: true, children: /* @__PURE__ */ jsx44(ComposerCancel, {}) })
5377
5621
  ] });
5378
5622
  };
5379
5623
  ComposerAction.displayName = "ComposerAction";
@@ -5385,7 +5629,7 @@ var ComposerSend = forwardRef26((props, ref) => {
5385
5629
  const {
5386
5630
  strings: { composer: { send: { tooltip = "Send" } = {} } = {} } = {}
5387
5631
  } = useThreadConfig();
5388
- return /* @__PURE__ */ jsx45(composer_exports.Send, { asChild: true, children: /* @__PURE__ */ jsx45(ComposerSendButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx45(SendHorizontalIcon, {}) }) });
5632
+ return /* @__PURE__ */ jsx44(composer_exports.Send, { asChild: true, children: /* @__PURE__ */ jsx44(ComposerSendButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx44(SendHorizontalIcon, {}) }) });
5389
5633
  });
5390
5634
  ComposerSend.displayName = "ComposerSend";
5391
5635
  var ComposerCancelButton = withDefaults(TooltipIconButton, {
@@ -5396,7 +5640,7 @@ var ComposerCancel = forwardRef26((props, ref) => {
5396
5640
  const {
5397
5641
  strings: { composer: { cancel: { tooltip = "Cancel" } = {} } = {} } = {}
5398
5642
  } = useThreadConfig();
5399
- return /* @__PURE__ */ jsx45(composer_exports.Cancel, { asChild: true, children: /* @__PURE__ */ jsx45(ComposerCancelButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx45(CircleStopIcon, {}) }) });
5643
+ return /* @__PURE__ */ jsx44(composer_exports.Cancel, { asChild: true, children: /* @__PURE__ */ jsx44(ComposerCancelButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx44(CircleStopIcon, {}) }) });
5400
5644
  });
5401
5645
  ComposerCancel.displayName = "ComposerCancel";
5402
5646
  var exports6 = {
@@ -5412,14 +5656,14 @@ var composer_default = Object.assign(Composer, exports6);
5412
5656
 
5413
5657
  // src/ui/thread-welcome.tsx
5414
5658
  import { forwardRef as forwardRef27 } from "react";
5415
- import { jsx as jsx46, jsxs as jsxs10 } from "react/jsx-runtime";
5659
+ import { jsx as jsx45, jsxs as jsxs9 } from "react/jsx-runtime";
5416
5660
  var ThreadWelcome = () => {
5417
- return /* @__PURE__ */ jsxs10(ThreadWelcomeRoot, { children: [
5418
- /* @__PURE__ */ jsxs10(ThreadWelcomeCenter, { children: [
5419
- /* @__PURE__ */ jsx46(ThreadWelcomeAvatar, {}),
5420
- /* @__PURE__ */ jsx46(ThreadWelcomeMessage, {})
5661
+ return /* @__PURE__ */ jsxs9(ThreadWelcomeRoot, { children: [
5662
+ /* @__PURE__ */ jsxs9(ThreadWelcomeCenter, { children: [
5663
+ /* @__PURE__ */ jsx45(ThreadWelcomeAvatar, {}),
5664
+ /* @__PURE__ */ jsx45(ThreadWelcomeMessage, {})
5421
5665
  ] }),
5422
- /* @__PURE__ */ jsx46(ThreadWelcomeSuggestions, {})
5666
+ /* @__PURE__ */ jsx45(ThreadWelcomeSuggestions, {})
5423
5667
  ] });
5424
5668
  };
5425
5669
  ThreadWelcome.displayName = "ThreadWelcome";
@@ -5431,20 +5675,20 @@ var ThreadWelcomeCenter = withDefaults("div", {
5431
5675
  });
5432
5676
  var ThreadWelcomeRoot = forwardRef27(
5433
5677
  (props, ref) => {
5434
- return /* @__PURE__ */ jsx46(thread_exports.Empty, { children: /* @__PURE__ */ jsx46(ThreadWelcomeRootStyled, { ...props, ref }) });
5678
+ return /* @__PURE__ */ jsx45(thread_exports.Empty, { children: /* @__PURE__ */ jsx45(ThreadWelcomeRootStyled, { ...props, ref }) });
5435
5679
  }
5436
5680
  );
5437
5681
  ThreadWelcomeRoot.displayName = "ThreadWelcomeRoot";
5438
5682
  var ThreadWelcomeAvatar = () => {
5439
5683
  const { assistantAvatar: avatar = { fallback: "A" } } = useThreadConfig();
5440
- return /* @__PURE__ */ jsx46(Avatar, { ...avatar });
5684
+ return /* @__PURE__ */ jsx45(Avatar, { ...avatar });
5441
5685
  };
5442
5686
  var ThreadWelcomeMessageStyled = withDefaults("p", {
5443
5687
  className: "aui-thread-welcome-message"
5444
5688
  });
5445
5689
  var ThreadWelcomeMessage = forwardRef27(({ message: messageProp, ...rest }, ref) => {
5446
5690
  const { welcome: { message = "How can I help you today?" } = {} } = useThreadConfig();
5447
- return /* @__PURE__ */ jsx46(ThreadWelcomeMessageStyled, { ...rest, ref, children: messageProp ?? message });
5691
+ return /* @__PURE__ */ jsx45(ThreadWelcomeMessageStyled, { ...rest, ref, children: messageProp ?? message });
5448
5692
  });
5449
5693
  ThreadWelcomeMessage.displayName = "ThreadWelcomeMessage";
5450
5694
  var ThreadWelcomeSuggestionContainer = withDefaults("div", {
@@ -5456,21 +5700,21 @@ var ThreadWelcomeSuggestionStyled = withDefaults(thread_exports.Suggestion, {
5456
5700
  var ThreadWelcomeSuggestion = ({
5457
5701
  suggestion: { text, prompt }
5458
5702
  }) => {
5459
- return /* @__PURE__ */ jsx46(
5703
+ return /* @__PURE__ */ jsx45(
5460
5704
  ThreadWelcomeSuggestionStyled,
5461
5705
  {
5462
5706
  prompt,
5463
5707
  method: "replace",
5464
5708
  autoSend: true,
5465
- children: /* @__PURE__ */ jsx46("span", { className: "aui-thread-welcome-suggestion-text", children: text ?? prompt })
5709
+ children: /* @__PURE__ */ jsx45("span", { className: "aui-thread-welcome-suggestion-text", children: text ?? prompt })
5466
5710
  }
5467
5711
  );
5468
5712
  };
5469
5713
  var ThreadWelcomeSuggestions = () => {
5470
5714
  const { welcome: { suggestions } = {} } = useThreadConfig();
5471
- return /* @__PURE__ */ jsx46(ThreadWelcomeSuggestionContainer, { children: suggestions?.map((suggestion, idx) => {
5715
+ return /* @__PURE__ */ jsx45(ThreadWelcomeSuggestionContainer, { children: suggestions?.map((suggestion, idx) => {
5472
5716
  const key = `${suggestion.prompt}-${idx}`;
5473
- return /* @__PURE__ */ jsx46(ThreadWelcomeSuggestion, { suggestion }, key);
5717
+ return /* @__PURE__ */ jsx45(ThreadWelcomeSuggestion, { suggestion }, key);
5474
5718
  }) });
5475
5719
  };
5476
5720
  ThreadWelcomeSuggestions.displayName = "ThreadWelcomeSuggestions";
@@ -5490,7 +5734,7 @@ import { forwardRef as forwardRef29 } from "react";
5490
5734
  // src/ui/user-action-bar.tsx
5491
5735
  import { forwardRef as forwardRef28 } from "react";
5492
5736
  import { PencilIcon } from "lucide-react";
5493
- import { jsx as jsx47 } from "react/jsx-runtime";
5737
+ import { jsx as jsx46 } from "react/jsx-runtime";
5494
5738
  var useAllowEdit = (ensureCapability = false) => {
5495
5739
  const { userMessage: { allowEdit = true } = {} } = useThreadConfig();
5496
5740
  const editSupported = useThread((t) => t.capabilities.edit);
@@ -5499,7 +5743,7 @@ var useAllowEdit = (ensureCapability = false) => {
5499
5743
  var UserActionBar = () => {
5500
5744
  const allowEdit = useAllowEdit(true);
5501
5745
  if (!allowEdit) return null;
5502
- return /* @__PURE__ */ jsx47(UserActionBarRoot, { hideWhenRunning: true, autohide: "not-last", children: /* @__PURE__ */ jsx47(UserActionBarEdit, {}) });
5746
+ return /* @__PURE__ */ jsx46(UserActionBarRoot, { hideWhenRunning: true, autohide: "not-last", children: /* @__PURE__ */ jsx46(UserActionBarEdit, {}) });
5503
5747
  };
5504
5748
  UserActionBar.displayName = "UserActionBar";
5505
5749
  var UserActionBarRoot = withDefaults(actionBar_exports.Root, {
@@ -5511,7 +5755,7 @@ var UserActionBarEdit = forwardRef28((props, ref) => {
5511
5755
  strings: { userMessage: { edit: { tooltip = "Edit" } = {} } = {} } = {}
5512
5756
  } = useThreadConfig();
5513
5757
  const allowEdit = useAllowEdit();
5514
- return /* @__PURE__ */ jsx47(actionBar_exports.Edit, { disabled: !allowEdit, asChild: true, children: /* @__PURE__ */ jsx47(TooltipIconButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx47(PencilIcon, {}) }) });
5758
+ return /* @__PURE__ */ jsx46(actionBar_exports.Edit, { disabled: !allowEdit, asChild: true, children: /* @__PURE__ */ jsx46(TooltipIconButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx46(PencilIcon, {}) }) });
5515
5759
  });
5516
5760
  UserActionBarEdit.displayName = "UserActionBarEdit";
5517
5761
  var exports8 = {
@@ -5521,14 +5765,14 @@ var exports8 = {
5521
5765
  var user_action_bar_default = Object.assign(UserActionBar, exports8);
5522
5766
 
5523
5767
  // src/ui/user-message-attachment.tsx
5524
- import { jsxs as jsxs11 } from "react/jsx-runtime";
5768
+ import { jsxs as jsxs10 } from "react/jsx-runtime";
5525
5769
  var UserMessageAttachmentRoot = withDefaults("div", {
5526
5770
  className: "aui-user-message-attachment-root"
5527
5771
  });
5528
5772
  UserMessageAttachmentRoot.displayName = "UserMessageAttachmentRoot";
5529
5773
  var UserMessageAttachment = () => {
5530
5774
  const attachment = useAttachment((a) => a.attachment);
5531
- return /* @__PURE__ */ jsxs11(UserMessageAttachmentRoot, { children: [
5775
+ return /* @__PURE__ */ jsxs10(UserMessageAttachmentRoot, { children: [
5532
5776
  ".",
5533
5777
  attachment.name.split(".").pop()
5534
5778
  ] });
@@ -5543,13 +5787,13 @@ var user_message_attachment_default = Object.assign(
5543
5787
  );
5544
5788
 
5545
5789
  // src/ui/user-message.tsx
5546
- import { jsx as jsx48, jsxs as jsxs12 } from "react/jsx-runtime";
5790
+ import { jsx as jsx47, jsxs as jsxs11 } from "react/jsx-runtime";
5547
5791
  var UserMessage = () => {
5548
- return /* @__PURE__ */ jsxs12(UserMessageRoot, { children: [
5549
- /* @__PURE__ */ jsx48(UserMessageAttachments, {}),
5550
- /* @__PURE__ */ jsx48(user_action_bar_default, {}),
5551
- /* @__PURE__ */ jsx48(UserMessageContent, {}),
5552
- /* @__PURE__ */ jsx48(branch_picker_default, {})
5792
+ return /* @__PURE__ */ jsxs11(UserMessageRoot, { children: [
5793
+ /* @__PURE__ */ jsx47(UserMessageAttachments, {}),
5794
+ /* @__PURE__ */ jsx47(user_action_bar_default, {}),
5795
+ /* @__PURE__ */ jsx47(UserMessageContent, {}),
5796
+ /* @__PURE__ */ jsx47(branch_picker_default, {})
5553
5797
  ] });
5554
5798
  };
5555
5799
  UserMessage.displayName = "UserMessage";
@@ -5562,7 +5806,7 @@ var UserMessageContentWrapper = withDefaults("div", {
5562
5806
  });
5563
5807
  var UserMessageContent = forwardRef29(
5564
5808
  ({ components, ...props }, ref) => {
5565
- return /* @__PURE__ */ jsx48(UserMessageContentWrapper, { ...props, ref, children: /* @__PURE__ */ jsx48(
5809
+ return /* @__PURE__ */ jsx47(UserMessageContentWrapper, { ...props, ref, children: /* @__PURE__ */ jsx47(
5566
5810
  message_exports.Content,
5567
5811
  {
5568
5812
  components: {
@@ -5580,7 +5824,7 @@ var UserMessageAttachmentsContainer = withDefaults("div", {
5580
5824
  var UserMessageAttachments = ({
5581
5825
  components
5582
5826
  }) => {
5583
- return /* @__PURE__ */ jsx48(message_exports.If, { hasAttachments: true, children: /* @__PURE__ */ jsx48(UserMessageAttachmentsContainer, { children: /* @__PURE__ */ jsx48(
5827
+ return /* @__PURE__ */ jsx47(message_exports.If, { hasAttachments: true, children: /* @__PURE__ */ jsx47(UserMessageAttachmentsContainer, { children: /* @__PURE__ */ jsx47(
5584
5828
  message_exports.Attachments,
5585
5829
  {
5586
5830
  components: {
@@ -5599,13 +5843,13 @@ var user_message_default = Object.assign(UserMessage, exports10);
5599
5843
 
5600
5844
  // src/ui/edit-composer.tsx
5601
5845
  import { forwardRef as forwardRef30 } from "react";
5602
- import { jsx as jsx49, jsxs as jsxs13 } from "react/jsx-runtime";
5846
+ import { jsx as jsx48, jsxs as jsxs12 } from "react/jsx-runtime";
5603
5847
  var EditComposer = () => {
5604
- return /* @__PURE__ */ jsxs13(EditComposerRoot, { children: [
5605
- /* @__PURE__ */ jsx49(EditComposerInput, {}),
5606
- /* @__PURE__ */ jsxs13(EditComposerFooter, { children: [
5607
- /* @__PURE__ */ jsx49(EditComposerCancel, {}),
5608
- /* @__PURE__ */ jsx49(EditComposerSend, {})
5848
+ return /* @__PURE__ */ jsxs12(EditComposerRoot, { children: [
5849
+ /* @__PURE__ */ jsx48(EditComposerInput, {}),
5850
+ /* @__PURE__ */ jsxs12(EditComposerFooter, { children: [
5851
+ /* @__PURE__ */ jsx48(EditComposerCancel, {}),
5852
+ /* @__PURE__ */ jsx48(EditComposerSend, {})
5609
5853
  ] })
5610
5854
  ] });
5611
5855
  };
@@ -5629,7 +5873,7 @@ var EditComposerCancel = forwardRef30(
5629
5873
  editComposer: { cancel: { label = "Cancel" } = {} } = {}
5630
5874
  } = {}
5631
5875
  } = useThreadConfig();
5632
- return /* @__PURE__ */ jsx49(composer_exports.Cancel, { asChild: true, children: /* @__PURE__ */ jsx49(Button, { variant: "ghost", ...props, ref, children: props.children ?? label }) });
5876
+ return /* @__PURE__ */ jsx48(composer_exports.Cancel, { asChild: true, children: /* @__PURE__ */ jsx48(Button, { variant: "ghost", ...props, ref, children: props.children ?? label }) });
5633
5877
  }
5634
5878
  );
5635
5879
  EditComposerCancel.displayName = "EditComposerCancel";
@@ -5638,7 +5882,7 @@ var EditComposerSend = forwardRef30(
5638
5882
  const {
5639
5883
  strings: { editComposer: { send: { label = "Send" } = {} } = {} } = {}
5640
5884
  } = useThreadConfig();
5641
- return /* @__PURE__ */ jsx49(composer_exports.Send, { asChild: true, children: /* @__PURE__ */ jsx49(Button, { ...props, ref, children: props.children ?? label }) });
5885
+ return /* @__PURE__ */ jsx48(composer_exports.Send, { asChild: true, children: /* @__PURE__ */ jsx48(Button, { ...props, ref, children: props.children ?? label }) });
5642
5886
  }
5643
5887
  );
5644
5888
  EditComposerSend.displayName = "EditComposerSend";
@@ -5652,14 +5896,14 @@ var exports11 = {
5652
5896
  var edit_composer_default = Object.assign(EditComposer, exports11);
5653
5897
 
5654
5898
  // src/ui/thread.tsx
5655
- import { jsx as jsx50, jsxs as jsxs14 } from "react/jsx-runtime";
5899
+ import { jsx as jsx49, jsxs as jsxs13 } from "react/jsx-runtime";
5656
5900
  var Thread = (config) => {
5657
- return /* @__PURE__ */ jsx50(ThreadRoot, { config, children: /* @__PURE__ */ jsxs14(ThreadViewport, { children: [
5658
- /* @__PURE__ */ jsx50(thread_welcome_default, {}),
5659
- /* @__PURE__ */ jsx50(ThreadMessages, {}),
5660
- /* @__PURE__ */ jsxs14(ThreadViewportFooter, { children: [
5661
- /* @__PURE__ */ jsx50(ThreadScrollToBottom, {}),
5662
- /* @__PURE__ */ jsx50(composer_default, {})
5901
+ return /* @__PURE__ */ jsx49(ThreadRoot, { config, children: /* @__PURE__ */ jsxs13(ThreadViewport, { children: [
5902
+ /* @__PURE__ */ jsx49(thread_welcome_default, {}),
5903
+ /* @__PURE__ */ jsx49(ThreadMessages, {}),
5904
+ /* @__PURE__ */ jsxs13(ThreadViewportFooter, { children: [
5905
+ /* @__PURE__ */ jsx49(ThreadScrollToBottom, {}),
5906
+ /* @__PURE__ */ jsx49(composer_default, {})
5663
5907
  ] })
5664
5908
  ] }) });
5665
5909
  };
@@ -5668,7 +5912,7 @@ var ThreadRootStyled = withDefaults(thread_exports.Root, {
5668
5912
  });
5669
5913
  var ThreadRoot = forwardRef31(
5670
5914
  ({ config, ...props }, ref) => {
5671
- return /* @__PURE__ */ jsx50(ThreadConfigProvider, { config, children: /* @__PURE__ */ jsx50(ThreadRootStyled, { ...props, ref }) });
5915
+ return /* @__PURE__ */ jsx49(ThreadConfigProvider, { config, children: /* @__PURE__ */ jsx49(ThreadRootStyled, { ...props, ref }) });
5672
5916
  }
5673
5917
  );
5674
5918
  ThreadRoot.displayName = "ThreadRoot";
@@ -5682,7 +5926,7 @@ var ThreadViewportFooter = withDefaults("div", {
5682
5926
  ThreadViewportFooter.displayName = "ThreadViewportFooter";
5683
5927
  var SystemMessage = () => null;
5684
5928
  var ThreadMessages = ({ components, ...rest }) => {
5685
- return /* @__PURE__ */ jsx50(
5929
+ return /* @__PURE__ */ jsx49(
5686
5930
  thread_exports.Messages,
5687
5931
  {
5688
5932
  components: {
@@ -5706,7 +5950,7 @@ var ThreadScrollToBottom = forwardRef31((props, ref) => {
5706
5950
  thread: { scrollToBottom: { tooltip = "Scroll to bottom" } = {} } = {}
5707
5951
  } = {}
5708
5952
  } = useThreadConfig();
5709
- return /* @__PURE__ */ jsx50(thread_exports.ScrollToBottom, { asChild: true, children: /* @__PURE__ */ jsx50(ThreadScrollToBottomIconButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx50(ArrowDownIcon, {}) }) });
5953
+ return /* @__PURE__ */ jsx49(thread_exports.ScrollToBottom, { asChild: true, children: /* @__PURE__ */ jsx49(ThreadScrollToBottomIconButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx49(ArrowDownIcon, {}) }) });
5710
5954
  });
5711
5955
  ThreadScrollToBottom.displayName = "ThreadScrollToBottom";
5712
5956
  var exports12 = {
@@ -5719,20 +5963,20 @@ var exports12 = {
5719
5963
  var thread_default = Object.assign(Thread, exports12);
5720
5964
 
5721
5965
  // src/ui/assistant-modal.tsx
5722
- import { Fragment as Fragment6, jsx as jsx51, jsxs as jsxs15 } from "react/jsx-runtime";
5966
+ import { Fragment as Fragment6, jsx as jsx50, jsxs as jsxs14 } from "react/jsx-runtime";
5723
5967
  var AssistantModal = (config) => {
5724
- return /* @__PURE__ */ jsxs15(AssistantModalRoot, { config, children: [
5725
- /* @__PURE__ */ jsx51(AssistantModalTrigger, {}),
5726
- /* @__PURE__ */ jsx51(AssistantModalContent, { children: /* @__PURE__ */ jsx51(thread_default, {}) })
5968
+ return /* @__PURE__ */ jsxs14(AssistantModalRoot, { config, children: [
5969
+ /* @__PURE__ */ jsx50(AssistantModalTrigger, {}),
5970
+ /* @__PURE__ */ jsx50(AssistantModalContent, { children: /* @__PURE__ */ jsx50(thread_default, {}) })
5727
5971
  ] });
5728
5972
  };
5729
5973
  AssistantModal.displayName = "AssistantModal";
5730
5974
  var AssistantModalRoot = ({ config, ...props }) => {
5731
- return /* @__PURE__ */ jsx51(ThreadConfigProvider, { config, children: /* @__PURE__ */ jsx51(assistantModal_exports.Root, { ...props }) });
5975
+ return /* @__PURE__ */ jsx50(ThreadConfigProvider, { config, children: /* @__PURE__ */ jsx50(assistantModal_exports.Root, { ...props }) });
5732
5976
  };
5733
5977
  AssistantModalRoot.displayName = "AssistantModalRoot";
5734
5978
  var AssistantModalTrigger = forwardRef32((props, ref) => {
5735
- return /* @__PURE__ */ jsx51(AssistantModalAnchor, { children: /* @__PURE__ */ jsx51(assistantModal_exports.Trigger, { asChild: true, children: /* @__PURE__ */ jsx51(AssistantModalButton, { ...props, ref }) }) });
5979
+ return /* @__PURE__ */ jsx50(AssistantModalAnchor, { children: /* @__PURE__ */ jsx50(assistantModal_exports.Trigger, { asChild: true, children: /* @__PURE__ */ jsx50(AssistantModalButton, { ...props, ref }) }) });
5736
5980
  });
5737
5981
  AssistantModalTrigger.displayName = "AssistantModalTrigger";
5738
5982
  var AssistantModalAnchor = withDefaults(assistantModal_exports.Anchor, {
@@ -5757,7 +6001,7 @@ var AssistantModalButton = forwardRef32(({ "data-state": state, ...rest }, ref)
5757
6001
  } = {}
5758
6002
  } = useThreadConfig();
5759
6003
  const tooltip = state === "open" ? openTooltip : closedTooltip;
5760
- return /* @__PURE__ */ jsx51(
6004
+ return /* @__PURE__ */ jsx50(
5761
6005
  ModalButtonStyled,
5762
6006
  {
5763
6007
  side: "left",
@@ -5765,15 +6009,15 @@ var AssistantModalButton = forwardRef32(({ "data-state": state, ...rest }, ref)
5765
6009
  "data-state": state,
5766
6010
  ...rest,
5767
6011
  ref,
5768
- children: rest.children ?? /* @__PURE__ */ jsxs15(Fragment6, { children: [
5769
- /* @__PURE__ */ jsx51(
6012
+ children: rest.children ?? /* @__PURE__ */ jsxs14(Fragment6, { children: [
6013
+ /* @__PURE__ */ jsx50(
5770
6014
  BotIcon,
5771
6015
  {
5772
6016
  "data-state": state,
5773
6017
  className: "aui-modal-button-closed-icon"
5774
6018
  }
5775
6019
  ),
5776
- /* @__PURE__ */ jsx51(
6020
+ /* @__PURE__ */ jsx50(
5777
6021
  ChevronDownIcon,
5778
6022
  {
5779
6023
  "data-state": state,
@@ -5866,12 +6110,14 @@ export {
5866
6110
  useComposerCancel,
5867
6111
  useComposerContext,
5868
6112
  useComposerIf,
6113
+ useComposerRuntime,
5869
6114
  useComposerSend,
5870
6115
  useComposerStore,
5871
6116
  useContentPart,
5872
6117
  useContentPartContext,
5873
6118
  useContentPartDisplay,
5874
6119
  useContentPartImage,
6120
+ useContentPartRuntime,
5875
6121
  useContentPartStore,
5876
6122
  useContentPartText,
5877
6123
  useDangerousInBrowserRuntime,