@assistant-ui/react 0.5.66 → 0.5.68

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