@assistant-ui/react 0.5.80 → 0.5.82

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.mjs CHANGED
@@ -10,13 +10,13 @@ import {
10
10
  toLanguageModelMessages,
11
11
  toLanguageModelTools,
12
12
  toolResultStream
13
- } from "./chunk-RRW3NW2F.mjs";
13
+ } from "./chunk-TWIMAOZR.mjs";
14
14
  import {
15
15
  __export
16
16
  } from "./chunk-BJPOCE4O.mjs";
17
17
 
18
18
  // src/context/providers/AssistantRuntimeProvider.tsx
19
- import { memo, useEffect as useEffect2, useMemo as useMemo2, useState as useState2 } from "react";
19
+ import { memo, useEffect as useEffect3, useMemo as useMemo2, useState as useState3 } from "react";
20
20
 
21
21
  // src/context/react/AssistantContext.ts
22
22
  import { createContext } from "react";
@@ -120,10 +120,10 @@ var makeAssistantToolUIsStore = () => create((set) => {
120
120
  });
121
121
 
122
122
  // src/context/providers/ThreadRuntimeProvider.tsx
123
- import { useEffect, useMemo, useState } from "react";
123
+ import { useEffect as useEffect2, useMemo, useState as useState2 } from "react";
124
124
 
125
125
  // src/context/react/ThreadContext.ts
126
- import { createContext as createContext2 } from "react";
126
+ import { createContext as createContext2, useEffect, useState } from "react";
127
127
  var ThreadContext = createContext2(null);
128
128
  var useThreadContext = createContextHook(
129
129
  ThreadContext,
@@ -156,6 +156,15 @@ var {
156
156
  useViewport: useThreadViewport,
157
157
  useViewportStore: useThreadViewportStore
158
158
  } = createContextStoreHook(useThreadContext, "useViewport");
159
+ function useThreadModelConfig(options) {
160
+ const [, rerender] = useState({});
161
+ const runtime = useThreadRuntime(options);
162
+ useEffect(() => {
163
+ return runtime?.unstable_on("model-config-update", () => rerender({}));
164
+ }, [runtime]);
165
+ if (!runtime) return null;
166
+ return runtime?.getModelConfig();
167
+ }
159
168
 
160
169
  // src/context/stores/ThreadViewport.tsx
161
170
  import { create as create2 } from "zustand";
@@ -186,15 +195,15 @@ var writableStore = (store) => {
186
195
  import { create as create3 } from "zustand";
187
196
  import { jsx } from "react/jsx-runtime";
188
197
  var useThreadRuntimeStore2 = (runtime) => {
189
- const [store] = useState(() => create3(() => runtime));
190
- useEffect(() => {
198
+ const [store] = useState2(() => create3(() => runtime));
199
+ useEffect2(() => {
191
200
  writableStore(store).setState(runtime, true);
192
201
  }, [runtime, store]);
193
202
  return store;
194
203
  };
195
204
  var useThreadStore2 = (runtime) => {
196
- const [store] = useState(() => create3(() => runtime.getState()));
197
- useEffect(() => {
205
+ const [store] = useState2(() => create3(() => runtime.getState()));
206
+ useEffect2(() => {
198
207
  const updateState = () => writableStore(store).setState(runtime.getState(), true);
199
208
  updateState();
200
209
  return runtime.subscribe(updateState);
@@ -202,8 +211,8 @@ var useThreadStore2 = (runtime) => {
202
211
  return store;
203
212
  };
204
213
  var useThreadMessagesStore2 = (runtime) => {
205
- const [store] = useState(() => create3(() => runtime.messages));
206
- useEffect(() => {
214
+ const [store] = useState2(() => create3(() => runtime.messages));
215
+ useEffect2(() => {
207
216
  const updateState = () => writableStore(store).setState(runtime.messages, true);
208
217
  updateState();
209
218
  return runtime.subscribe(updateState);
@@ -211,8 +220,8 @@ var useThreadMessagesStore2 = (runtime) => {
211
220
  return store;
212
221
  };
213
222
  var useThreadComposerStore2 = (runtime) => {
214
- const [store] = useState(() => create3(() => runtime.getState()));
215
- useEffect(() => {
223
+ const [store] = useState2(() => create3(() => runtime.getState()));
224
+ useEffect2(() => {
216
225
  const updateState = () => writableStore(store).setState(runtime.getState(), true);
217
226
  updateState();
218
227
  return runtime.subscribe(updateState);
@@ -242,8 +251,8 @@ var ThreadRuntimeProvider = ({ children, runtime }) => {
242
251
  import { create as create4 } from "zustand";
243
252
  import { jsx as jsx2 } from "react/jsx-runtime";
244
253
  var useAssistantRuntimeStore2 = (runtime) => {
245
- const [store] = useState2(() => create4(() => runtime));
246
- useEffect2(() => {
254
+ const [store] = useState3(() => create4(() => runtime));
255
+ useEffect3(() => {
247
256
  writableStore(store).setState(runtime, true);
248
257
  }, [runtime, store]);
249
258
  return store;
@@ -266,7 +275,7 @@ var AssistantRuntimeProviderImpl = ({ children, runtime }) => {
266
275
  var AssistantRuntimeProvider = memo(AssistantRuntimeProviderImpl);
267
276
 
268
277
  // src/context/providers/TextContentPartProvider.tsx
269
- import { useEffect as useEffect3, useState as useState3 } from "react";
278
+ import { useEffect as useEffect4, useState as useState4 } from "react";
270
279
  import { create as create5 } from "zustand";
271
280
 
272
281
  // src/context/react/ContentPartContext.ts
@@ -295,6 +304,9 @@ var ContentPartRuntimeImpl = class {
295
304
  this.messageApi = messageApi;
296
305
  this.threadApi = threadApi;
297
306
  }
307
+ get path() {
308
+ return this.contentBinding.path;
309
+ }
298
310
  getState() {
299
311
  return this.contentBinding.getState();
300
312
  }
@@ -328,7 +340,7 @@ var RUNNING_STATUS = {
328
340
  type: "running"
329
341
  };
330
342
  var TextContentPartProvider = ({ children, text, isRunning }) => {
331
- const [context] = useState3(() => {
343
+ const [context] = useState4(() => {
332
344
  const useContentPartRuntime2 = create5(
333
345
  // TODO
334
346
  () => new ContentPartRuntimeImpl(null, null, null)
@@ -341,7 +353,7 @@ var TextContentPartProvider = ({ children, text, isRunning }) => {
341
353
  }));
342
354
  return { useContentPartRuntime: useContentPartRuntime2, useContentPart: useContentPart2 };
343
355
  });
344
- useEffect3(() => {
356
+ useEffect4(() => {
345
357
  const state = context.useContentPart.getState();
346
358
  const textUpdated = state.text !== text;
347
359
  const targetStatus = isRunning ? RUNNING_STATUS : COMPLETE_STATUS;
@@ -432,11 +444,11 @@ var useSwitchToNewThread = () => {
432
444
  };
433
445
 
434
446
  // src/model-config/useAssistantTool.tsx
435
- import { useEffect as useEffect4 } from "react";
447
+ import { useEffect as useEffect5 } from "react";
436
448
  var useAssistantTool = (tool) => {
437
449
  const assistantRuntime = useAssistantRuntime();
438
450
  const toolUIsStore = useToolUIsStore();
439
- useEffect4(() => {
451
+ useEffect5(() => {
440
452
  const { toolName, render, ...rest } = tool;
441
453
  const config = {
442
454
  tools: {
@@ -465,10 +477,10 @@ var makeAssistantTool = (tool) => {
465
477
  };
466
478
 
467
479
  // src/model-config/useAssistantToolUI.tsx
468
- import { useEffect as useEffect5 } from "react";
480
+ import { useEffect as useEffect6 } from "react";
469
481
  var useAssistantToolUI = (tool) => {
470
482
  const toolUIsStore = useToolUIsStore();
471
- useEffect5(() => {
483
+ useEffect6(() => {
472
484
  if (!tool) return;
473
485
  const { toolName, render } = tool;
474
486
  return toolUIsStore.getState().setToolUI(toolName, render);
@@ -486,10 +498,10 @@ var makeAssistantToolUI = (tool) => {
486
498
  };
487
499
 
488
500
  // src/model-config/useAssistantInstructions.tsx
489
- import { useEffect as useEffect6 } from "react";
501
+ import { useEffect as useEffect7 } from "react";
490
502
  var useAssistantInstructions = (instruction) => {
491
503
  const assistantRuntime = useAssistantRuntime();
492
- useEffect6(() => {
504
+ useEffect7(() => {
493
505
  const config = {
494
506
  system: instruction
495
507
  };
@@ -501,64 +513,23 @@ var useAssistantInstructions = (instruction) => {
501
513
 
502
514
  // src/primitive-hooks/actionBar/useActionBarCopy.tsx
503
515
  import { useCallback as useCallback3 } from "react";
504
-
505
- // src/utils/combined/useCombinedStore.ts
506
- import { useMemo as useMemo4 } from "react";
507
-
508
- // src/utils/combined/createCombinedStore.ts
509
- import { useSyncExternalStore } from "react";
510
- var createCombinedStore = (stores) => {
511
- const subscribe = (callback) => {
512
- const unsubscribes = stores.map((store) => store.subscribe(callback));
513
- return () => {
514
- for (const unsub of unsubscribes) {
515
- unsub();
516
- }
517
- };
518
- };
519
- return (selector) => {
520
- const getSnapshot = () => selector(...stores.map((store) => store.getState()));
521
- return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
522
- };
523
- };
524
-
525
- // src/utils/combined/useCombinedStore.ts
526
- var useCombinedStore = (stores, selector) => {
527
- const useCombined = useMemo4(() => createCombinedStore(stores), stores);
528
- return useCombined(selector);
529
- };
530
-
531
- // src/utils/getThreadMessageText.tsx
532
- var getThreadMessageText = (message) => {
533
- const textParts = message.content.filter(
534
- (part) => part.type === "text"
535
- );
536
- return textParts.map((part) => part.text).join("\n\n");
537
- };
538
-
539
- // src/primitive-hooks/actionBar/useActionBarCopy.tsx
540
516
  var useActionBarCopy = ({
541
517
  copiedDuration = 3e3
542
518
  } = {}) => {
543
519
  const messageRuntime = useMessageRuntime();
544
520
  const composerRuntime = useComposerRuntime();
545
- const messageUtilsStore = useMessageUtilsStore();
546
- const hasCopyableContent = useCombinedStore(
547
- [messageRuntime, composerRuntime],
548
- (message, c) => {
549
- return !c.isEditing && (message.role !== "assistant" || message.status.type !== "running") && message.content.some((c2) => c2.type === "text" && c2.text.length > 0);
550
- }
551
- );
521
+ const setIsCopied = useMessageUtils((s) => s.setIsCopied);
522
+ const hasCopyableContent = useMessage((message) => {
523
+ return (message.role !== "assistant" || message.status.type !== "running") && message.content.some((c) => c.type === "text" && c.text.length > 0);
524
+ });
552
525
  const callback = useCallback3(() => {
553
- const message = messageRuntime.getState();
554
- const { setIsCopied } = messageUtilsStore.getState();
555
526
  const { isEditing, text: composerValue } = composerRuntime.getState();
556
- const valueToCopy = isEditing ? composerValue : getThreadMessageText(message);
527
+ const valueToCopy = isEditing ? composerValue : messageRuntime.unstable_getCopyText();
557
528
  navigator.clipboard.writeText(valueToCopy).then(() => {
558
529
  setIsCopied(true);
559
530
  setTimeout(() => setIsCopied(false), copiedDuration);
560
531
  });
561
- }, [messageRuntime, messageUtilsStore, composerRuntime, copiedDuration]);
532
+ }, [messageRuntime, setIsCopied, composerRuntime, copiedDuration]);
562
533
  if (!hasCopyableContent) return null;
563
534
  return callback;
564
535
  };
@@ -577,6 +548,34 @@ var useActionBarEdit = () => {
577
548
 
578
549
  // src/primitive-hooks/actionBar/useActionBarReload.tsx
579
550
  import { useCallback as useCallback5 } from "react";
551
+
552
+ // src/utils/combined/useCombinedStore.ts
553
+ import { useMemo as useMemo4 } from "react";
554
+
555
+ // src/utils/combined/createCombinedStore.ts
556
+ import { useSyncExternalStore } from "react";
557
+ var createCombinedStore = (stores) => {
558
+ const subscribe = (callback) => {
559
+ const unsubscribes = stores.map((store) => store.subscribe(callback));
560
+ return () => {
561
+ for (const unsub of unsubscribes) {
562
+ unsub();
563
+ }
564
+ };
565
+ };
566
+ return (selector) => {
567
+ const getSnapshot = () => selector(...stores.map((store) => store.getState()));
568
+ return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
569
+ };
570
+ };
571
+
572
+ // src/utils/combined/useCombinedStore.ts
573
+ var useCombinedStore = (stores, selector) => {
574
+ const useCombined = useMemo4(() => createCombinedStore(stores), stores);
575
+ return useCombined(selector);
576
+ };
577
+
578
+ // src/primitive-hooks/actionBar/useActionBarReload.tsx
580
579
  var useActionBarReload = () => {
581
580
  const messageRuntime = useMessageRuntime();
582
581
  const threadRuntime = useThreadRuntime();
@@ -1084,7 +1083,7 @@ __export(assistantModal_exports, {
1084
1083
  });
1085
1084
 
1086
1085
  // src/primitives/assistantModal/AssistantModalRoot.tsx
1087
- import { useEffect as useEffect7, useState as useState4 } from "react";
1086
+ import { useEffect as useEffect8, useState as useState5 } from "react";
1088
1087
  import * as PopoverPrimitive2 from "@radix-ui/react-popover";
1089
1088
  import { composeEventHandlers as composeEventHandlers6 } from "@radix-ui/primitive";
1090
1089
 
@@ -1098,10 +1097,10 @@ var useAssistantModalOpenState = ({
1098
1097
  defaultOpen = false,
1099
1098
  unstable_openOnRunStart = true
1100
1099
  }) => {
1101
- const state = useState4(defaultOpen);
1100
+ const state = useState5(defaultOpen);
1102
1101
  const [, setOpen] = state;
1103
1102
  const threadRuntime = useThreadRuntime();
1104
- useEffect7(() => {
1103
+ useEffect8(() => {
1105
1104
  if (!unstable_openOnRunStart) return void 0;
1106
1105
  return threadRuntime.unstable_on("run-start", () => {
1107
1106
  setOpen(true);
@@ -1434,19 +1433,19 @@ MessagePrimitiveIf.displayName = "MessagePrimitive.If";
1434
1433
  import { memo as memo2, useMemo as useMemo6 } from "react";
1435
1434
 
1436
1435
  // src/context/providers/ContentPartRuntimeProvider.tsx
1437
- import { useEffect as useEffect8, useState as useState5 } from "react";
1436
+ import { useEffect as useEffect9, useState as useState6 } from "react";
1438
1437
  import { create as create6 } from "zustand";
1439
1438
  import { jsx as jsx19 } from "react/jsx-runtime";
1440
1439
  var useContentPartRuntimeStore = (runtime) => {
1441
- const [store] = useState5(() => create6(() => runtime));
1442
- useEffect8(() => {
1440
+ const [store] = useState6(() => create6(() => runtime));
1441
+ useEffect9(() => {
1443
1442
  writableStore(store).setState(runtime, true);
1444
1443
  }, [runtime, store]);
1445
1444
  return store;
1446
1445
  };
1447
1446
  var useContentPartStore2 = (runtime) => {
1448
- const [store] = useState5(() => create6(() => runtime.getState()));
1449
- useEffect8(() => {
1447
+ const [store] = useState6(() => create6(() => runtime.getState()));
1448
+ useEffect9(() => {
1450
1449
  const updateState = () => writableStore(store).setState(runtime.getState(), true);
1451
1450
  updateState();
1452
1451
  return runtime.subscribe(updateState);
@@ -1459,7 +1458,7 @@ var ContentPartRuntimeProvider = ({
1459
1458
  }) => {
1460
1459
  const useContentPartRuntime2 = useContentPartRuntimeStore(runtime);
1461
1460
  const useContentPart2 = useContentPartStore2(runtime);
1462
- const [context] = useState5(() => {
1461
+ const [context] = useState6(() => {
1463
1462
  return { useContentPartRuntime: useContentPartRuntime2, useContentPart: useContentPart2 };
1464
1463
  });
1465
1464
  return /* @__PURE__ */ jsx19(ContentPartContext.Provider, { value: context, children });
@@ -1471,7 +1470,7 @@ import {
1471
1470
  } from "react";
1472
1471
 
1473
1472
  // src/utils/smooth/useSmooth.tsx
1474
- import { useEffect as useEffect9, useMemo as useMemo5, useRef as useRef2, useState as useState7 } from "react";
1473
+ import { useEffect as useEffect10, useMemo as useMemo5, useRef as useRef2, useState as useState8 } from "react";
1475
1474
  import { useCallbackRef } from "@radix-ui/react-use-callback-ref";
1476
1475
 
1477
1476
  // src/utils/smooth/SmoothContext.tsx
@@ -1479,7 +1478,7 @@ import {
1479
1478
  createContext as createContext6,
1480
1479
  forwardRef as forwardRef13,
1481
1480
  useContext as useContext3,
1482
- useState as useState6
1481
+ useState as useState7
1483
1482
  } from "react";
1484
1483
  import { create as create7 } from "zustand";
1485
1484
  import { jsx as jsx20 } from "react/jsx-runtime";
@@ -1491,7 +1490,7 @@ var makeSmoothContext = (initialState) => {
1491
1490
  var SmoothContextProvider = ({ children }) => {
1492
1491
  const outer = useSmoothContext({ optional: true });
1493
1492
  const contentPartStore = useContentPartStore();
1494
- const [context] = useState6(
1493
+ const [context] = useState7(
1495
1494
  () => makeSmoothContext(contentPartStore.getState().status)
1496
1495
  );
1497
1496
  if (outer) return children;
@@ -1572,7 +1571,7 @@ var useSmooth = (state, smooth = false) => {
1572
1571
  selector: (m) => m.id
1573
1572
  });
1574
1573
  const idRef = useRef2(id);
1575
- const [displayedText, setDisplayedText] = useState7(text);
1574
+ const [displayedText, setDisplayedText] = useState8(text);
1576
1575
  const smoothStatusStore = useSmoothStatusStore({ optional: true });
1577
1576
  const setText = useCallbackRef((text2) => {
1578
1577
  setDisplayedText(text2);
@@ -1582,17 +1581,17 @@ var useSmooth = (state, smooth = false) => {
1582
1581
  );
1583
1582
  }
1584
1583
  });
1585
- useEffect9(() => {
1584
+ useEffect10(() => {
1586
1585
  if (smoothStatusStore) {
1587
1586
  writableStore(smoothStatusStore).setState(
1588
1587
  text !== state.text ? SMOOTH_STATUS : state.status
1589
1588
  );
1590
1589
  }
1591
1590
  }, [smoothStatusStore, text, displayedText, state.status, state.text]);
1592
- const [animatorRef] = useState7(
1591
+ const [animatorRef] = useState8(
1593
1592
  new TextStreamAnimator(text, setText)
1594
1593
  );
1595
- useEffect9(() => {
1594
+ useEffect10(() => {
1596
1595
  if (!smooth) {
1597
1596
  animatorRef.stop();
1598
1597
  return;
@@ -1608,7 +1607,7 @@ var useSmooth = (state, smooth = false) => {
1608
1607
  animatorRef.targetText = text;
1609
1608
  animatorRef.start();
1610
1609
  }, [setText, animatorRef, id, smooth, text]);
1611
- useEffect9(() => {
1610
+ useEffect10(() => {
1612
1611
  return () => {
1613
1612
  animatorRef.stop();
1614
1613
  };
@@ -1656,11 +1655,22 @@ var ContentPartPrimitiveInProgress = ({ children }) => {
1656
1655
  };
1657
1656
  ContentPartPrimitiveInProgress.displayName = "ContentPartPrimitive.InProgress";
1658
1657
 
1658
+ // src/utils/getThreadMessageText.tsx
1659
+ var getThreadMessageText = (message) => {
1660
+ const textParts = message.content.filter(
1661
+ (part) => part.type === "text"
1662
+ );
1663
+ return textParts.map((part) => part.text).join("\n\n");
1664
+ };
1665
+
1659
1666
  // src/api/AttachmentRuntime.ts
1660
1667
  var AttachmentRuntimeImpl = class {
1661
1668
  constructor(_core) {
1662
1669
  this._core = _core;
1663
1670
  }
1671
+ get path() {
1672
+ return this._core.path;
1673
+ }
1664
1674
  getState() {
1665
1675
  return this._core.getState();
1666
1676
  }
@@ -1739,6 +1749,9 @@ var LazyMemoizeSubject = class extends BaseSubject {
1739
1749
  super();
1740
1750
  this.binding = binding;
1741
1751
  }
1752
+ get path() {
1753
+ return this.binding.path;
1754
+ }
1742
1755
  _previousStateDirty = true;
1743
1756
  _previousState;
1744
1757
  getState = () => {
@@ -1785,6 +1798,9 @@ var ShallowMemoizeSubject = class extends BaseSubject {
1785
1798
  throw new Error("Entry not available in the store");
1786
1799
  this._previousState = state;
1787
1800
  }
1801
+ get path() {
1802
+ return this.binding.path;
1803
+ }
1788
1804
  _previousState;
1789
1805
  getState = () => {
1790
1806
  if (!this.isConnected) this._syncState();
@@ -1851,6 +1867,9 @@ var ComposerRuntimeImpl = class {
1851
1867
  constructor(_core) {
1852
1868
  this._core = _core;
1853
1869
  }
1870
+ get path() {
1871
+ return this._core.path;
1872
+ }
1854
1873
  /**
1855
1874
  * @deprecated Use `getState().isEditing` instead. This will be removed in 0.6.0.
1856
1875
  */
@@ -1936,16 +1955,21 @@ var ComposerRuntimeImpl = class {
1936
1955
  }
1937
1956
  };
1938
1957
  var ThreadComposerRuntimeImpl = class extends ComposerRuntimeImpl {
1958
+ get path() {
1959
+ return this._core.path;
1960
+ }
1939
1961
  get type() {
1940
1962
  return "thread";
1941
1963
  }
1942
1964
  _getState;
1943
1965
  constructor(core) {
1944
1966
  const stateBinding = new LazyMemoizeSubject({
1967
+ path: core.path,
1945
1968
  getState: () => getThreadComposerState(core.getState()),
1946
1969
  subscribe: (callback) => core.subscribe(callback)
1947
1970
  });
1948
1971
  super({
1972
+ path: core.path,
1949
1973
  getState: () => core.getState(),
1950
1974
  subscribe: (callback) => stateBinding.subscribe(callback)
1951
1975
  });
@@ -1960,6 +1984,12 @@ var ThreadComposerRuntimeImpl = class extends ComposerRuntimeImpl {
1960
1984
  getAttachmentByIndex(idx) {
1961
1985
  return new ThreadComposerAttachmentRuntimeImpl(
1962
1986
  new ShallowMemoizeSubject({
1987
+ path: {
1988
+ ...this.path,
1989
+ attachmentSource: "thread-composer",
1990
+ attachmentSelector: { type: "index", index: idx },
1991
+ ref: this.path.ref + `${this.path.ref}.attachments[${idx}]`
1992
+ },
1963
1993
  getState: () => {
1964
1994
  const attachments = this.getState().attachments;
1965
1995
  const attachment = attachments[idx];
@@ -1979,16 +2009,21 @@ var ThreadComposerRuntimeImpl = class extends ComposerRuntimeImpl {
1979
2009
  var EditComposerRuntimeImpl = class extends ComposerRuntimeImpl {
1980
2010
  constructor(core, _beginEdit) {
1981
2011
  const stateBinding = new LazyMemoizeSubject({
2012
+ path: core.path,
1982
2013
  getState: () => getEditComposerState(core.getState(), this._beginEdit),
1983
2014
  subscribe: (callback) => core.subscribe(callback)
1984
2015
  });
1985
2016
  super({
2017
+ path: core.path,
1986
2018
  getState: () => core.getState(),
1987
2019
  subscribe: (callback) => stateBinding.subscribe(callback)
1988
2020
  });
1989
2021
  this._beginEdit = _beginEdit;
1990
2022
  this._getState = stateBinding.getState.bind(stateBinding);
1991
2023
  }
2024
+ get path() {
2025
+ return this._core.path;
2026
+ }
1992
2027
  get type() {
1993
2028
  return "edit";
1994
2029
  }
@@ -2008,6 +2043,12 @@ var EditComposerRuntimeImpl = class extends ComposerRuntimeImpl {
2008
2043
  getAttachmentByIndex(idx) {
2009
2044
  return new EditComposerAttachmentRuntimeImpl(
2010
2045
  new ShallowMemoizeSubject({
2046
+ path: {
2047
+ ...this.path,
2048
+ attachmentSource: "edit-composer",
2049
+ attachmentSelector: { type: "index", index: idx },
2050
+ ref: this.path.ref + `${this.path.ref}.attachments[${idx}]`
2051
+ },
2011
2052
  getState: () => {
2012
2053
  const attachments = this.getState().attachments;
2013
2054
  const attachment = attachments[idx];
@@ -2031,6 +2072,9 @@ var NestedSubscriptionSubject = class extends BaseSubject {
2031
2072
  super();
2032
2073
  this.binding = binding;
2033
2074
  }
2075
+ get path() {
2076
+ return this.binding.path;
2077
+ }
2034
2078
  getState() {
2035
2079
  return this.binding.getState();
2036
2080
  }
@@ -2097,14 +2141,23 @@ var MessageRuntimeImpl = class {
2097
2141
  constructor(_core, _threadBinding) {
2098
2142
  this._core = _core;
2099
2143
  this._threadBinding = _threadBinding;
2144
+ this.composer = new EditComposerRuntimeImpl(
2145
+ new NestedSubscriptionSubject({
2146
+ path: {
2147
+ ...this.path,
2148
+ ref: this.path.ref + `${this.path.ref}.composer`,
2149
+ composerSource: "edit"
2150
+ },
2151
+ getState: () => this._threadBinding.getState().getEditComposer(this._core.getState().id),
2152
+ subscribe: (callback) => this._threadBinding.subscribe(callback)
2153
+ }),
2154
+ () => this._threadBinding.getState().beginEdit(this._core.getState().id)
2155
+ );
2100
2156
  }
2101
- composer = new EditComposerRuntimeImpl(
2102
- new NestedSubscriptionSubject({
2103
- getState: () => this._threadBinding.getState().getEditComposer(this._core.getState().id),
2104
- subscribe: (callback) => this._threadBinding.subscribe(callback)
2105
- }),
2106
- () => this._threadBinding.getState().beginEdit(this._core.getState().id)
2107
- );
2157
+ get path() {
2158
+ return this._core.path;
2159
+ }
2160
+ composer;
2108
2161
  getState() {
2109
2162
  return this._core.getState();
2110
2163
  }
@@ -2160,13 +2213,21 @@ var MessageRuntimeImpl = class {
2160
2213
  if (!targetBranch) throw new Error("Branch not found");
2161
2214
  this._threadBinding.getState().switchToBranch(targetBranch);
2162
2215
  }
2216
+ unstable_getCopyText() {
2217
+ return getThreadMessageText(this.getState());
2218
+ }
2163
2219
  subscribe(callback) {
2164
2220
  return this._core.subscribe(callback);
2165
2221
  }
2166
2222
  getContentPartByIndex(idx) {
2167
- if (idx < 0) throw new Error("Message index must be >= 0");
2223
+ if (idx < 0) throw new Error("Content part index must be >= 0");
2168
2224
  return new ContentPartRuntimeImpl(
2169
2225
  new ShallowMemoizeSubject({
2226
+ path: {
2227
+ ...this.path,
2228
+ ref: this.path.ref + `${this.path.ref}.content[${idx}]`,
2229
+ contentPartSelector: { type: "index", index: idx }
2230
+ },
2170
2231
  getState: () => {
2171
2232
  return getContentPartState(this.getState(), idx);
2172
2233
  },
@@ -2176,9 +2237,37 @@ var MessageRuntimeImpl = class {
2176
2237
  this._threadBinding
2177
2238
  );
2178
2239
  }
2240
+ getContentPartByToolCallId(toolCallId) {
2241
+ return new ContentPartRuntimeImpl(
2242
+ new ShallowMemoizeSubject({
2243
+ path: {
2244
+ ...this.path,
2245
+ ref: this.path.ref + `${this.path.ref}.content[toolCallId=${JSON.stringify(toolCallId)}]`,
2246
+ contentPartSelector: { type: "toolCallId", toolCallId }
2247
+ },
2248
+ getState: () => {
2249
+ const state = this._core.getState();
2250
+ const idx = state.content.findIndex(
2251
+ (part) => part.type === "tool-call" && part.toolCallId === toolCallId
2252
+ );
2253
+ if (idx === -1) return SKIP_UPDATE;
2254
+ return getContentPartState(state, idx);
2255
+ },
2256
+ subscribe: (callback) => this._core.subscribe(callback)
2257
+ }),
2258
+ this._core,
2259
+ this._threadBinding
2260
+ );
2261
+ }
2179
2262
  getAttachmentByIndex(idx) {
2180
2263
  return new MessageAttachmentRuntimeImpl(
2181
2264
  new ShallowMemoizeSubject({
2265
+ path: {
2266
+ ...this.path,
2267
+ ref: this.path.ref + `${this.path.ref}.attachments[${idx}]`,
2268
+ attachmentSource: "message",
2269
+ attachmentSelector: { type: "index", index: idx }
2270
+ },
2182
2271
  getState: () => {
2183
2272
  const attachments = this.getState().attachments;
2184
2273
  const attachment = attachments?.[idx];
@@ -2285,22 +2374,22 @@ import { memo as memo3, useMemo as useMemo8 } from "react";
2285
2374
 
2286
2375
  // src/context/providers/AttachmentRuntimeProvider.tsx
2287
2376
  import {
2288
- useEffect as useEffect10,
2377
+ useEffect as useEffect11,
2289
2378
  useMemo as useMemo7,
2290
- useState as useState8
2379
+ useState as useState9
2291
2380
  } from "react";
2292
2381
  import { create as create8 } from "zustand";
2293
2382
  import { jsx as jsx24 } from "react/jsx-runtime";
2294
2383
  var useAttachmentRuntimeStore = (runtime) => {
2295
- const [store] = useState8(() => create8(() => runtime));
2296
- useEffect10(() => {
2384
+ const [store] = useState9(() => create8(() => runtime));
2385
+ useEffect11(() => {
2297
2386
  writableStore(store).setState(runtime, true);
2298
2387
  }, [runtime, store]);
2299
2388
  return store;
2300
2389
  };
2301
2390
  var useAttachmentStore = (runtime) => {
2302
- const [store] = useState8(() => create8(() => runtime.getState()));
2303
- useEffect10(() => {
2391
+ const [store] = useState9(() => create8(() => runtime.getState()));
2392
+ useEffect11(() => {
2304
2393
  const updateState = () => writableStore(store).setState(runtime.getState(), true);
2305
2394
  updateState();
2306
2395
  return runtime.subscribe(updateState);
@@ -2426,7 +2515,7 @@ import { Slot } from "@radix-ui/react-slot";
2426
2515
  import {
2427
2516
  forwardRef as forwardRef18,
2428
2517
  useCallback as useCallback20,
2429
- useEffect as useEffect12,
2518
+ useEffect as useEffect13,
2430
2519
  useRef as useRef3
2431
2520
  } from "react";
2432
2521
  import TextareaAutosize from "react-textarea-autosize";
@@ -2434,11 +2523,11 @@ import { useEscapeKeydown as useEscapeKeydown2 } from "@radix-ui/react-use-escap
2434
2523
 
2435
2524
  // src/utils/hooks/useOnScrollToBottom.tsx
2436
2525
  import { useCallbackRef as useCallbackRef2 } from "@radix-ui/react-use-callback-ref";
2437
- import { useEffect as useEffect11 } from "react";
2526
+ import { useEffect as useEffect12 } from "react";
2438
2527
  var useOnScrollToBottom = (callback) => {
2439
2528
  const callbackRef = useCallbackRef2(callback);
2440
2529
  const onScrollToBottom = useThreadViewport((vp) => vp.onScrollToBottom);
2441
- useEffect11(() => {
2530
+ useEffect12(() => {
2442
2531
  return onScrollToBottom(callbackRef);
2443
2532
  }, [onScrollToBottom, callbackRef]);
2444
2533
  };
@@ -2497,18 +2586,18 @@ var ComposerPrimitiveInput = forwardRef18(
2497
2586
  textareaRef.current.value.length
2498
2587
  );
2499
2588
  }, [autoFocusEnabled]);
2500
- useEffect12(() => focus2(), [focus2]);
2589
+ useEffect13(() => focus2(), [focus2]);
2501
2590
  useOnScrollToBottom(() => {
2502
2591
  if (composerRuntime.type === "thread" && unstable_focusOnScrollToBottom) {
2503
2592
  focus2();
2504
2593
  }
2505
2594
  });
2506
- useEffect12(() => {
2595
+ useEffect13(() => {
2507
2596
  if (composerRuntime.type !== "thread" || !unstable_focusOnRunStart)
2508
2597
  return void 0;
2509
2598
  return threadRuntime.unstable_on("run-start", focus2);
2510
2599
  }, [unstable_focusOnRunStart]);
2511
- useEffect12(() => {
2600
+ useEffect13(() => {
2512
2601
  if (composerRuntime.type !== "thread" || !unstable_focusOnThreadSwitched)
2513
2602
  return void 0;
2514
2603
  return threadRuntime.unstable_on("switched-to", focus2);
@@ -2665,7 +2754,7 @@ import { forwardRef as forwardRef20 } from "react";
2665
2754
 
2666
2755
  // src/primitive-hooks/thread/useThreadViewportAutoScroll.tsx
2667
2756
  import { useComposedRefs as useComposedRefs3 } from "@radix-ui/react-compose-refs";
2668
- import { useEffect as useEffect13, useRef as useRef4 } from "react";
2757
+ import { useEffect as useEffect14, useRef as useRef4 } from "react";
2669
2758
 
2670
2759
  // src/utils/hooks/useOnResizeContent.tsx
2671
2760
  import { useCallbackRef as useCallbackRef3 } from "@radix-ui/react-use-callback-ref";
@@ -2757,7 +2846,7 @@ var useThreadViewportAutoScroll = ({
2757
2846
  scrollToBottom("auto");
2758
2847
  });
2759
2848
  const threadRuntime = useThreadRuntime();
2760
- useEffect13(() => {
2849
+ useEffect14(() => {
2761
2850
  if (!unstable_scrollToBottomOnRunStart) return void 0;
2762
2851
  return threadRuntime.unstable_on("run-start", focus);
2763
2852
  }, [unstable_scrollToBottomOnRunStart]);
@@ -2779,7 +2868,7 @@ ThreadPrimitiveViewport.displayName = "ThreadPrimitive.Viewport";
2779
2868
  import { memo as memo5, useMemo as useMemo10 } from "react";
2780
2869
 
2781
2870
  // src/context/providers/MessageRuntimeProvider.tsx
2782
- import { useEffect as useEffect14, useState as useState9 } from "react";
2871
+ import { useEffect as useEffect15, useState as useState10 } from "react";
2783
2872
  import { create as create10 } from "zustand";
2784
2873
 
2785
2874
  // src/context/stores/MessageUtils.ts
@@ -2800,15 +2889,15 @@ var makeMessageUtilsStore = () => create9((set) => {
2800
2889
  // src/context/providers/MessageRuntimeProvider.tsx
2801
2890
  import { jsx as jsx32 } from "react/jsx-runtime";
2802
2891
  var useMessageRuntimeStore = (runtime) => {
2803
- const [store] = useState9(() => create10(() => runtime));
2804
- useEffect14(() => {
2892
+ const [store] = useState10(() => create10(() => runtime));
2893
+ useEffect15(() => {
2805
2894
  writableStore(store).setState(runtime, true);
2806
2895
  }, [runtime, store]);
2807
2896
  return store;
2808
2897
  };
2809
2898
  var useMessageStore2 = (runtime) => {
2810
- const [store] = useState9(() => create10(() => runtime.getState()));
2811
- useEffect14(() => {
2899
+ const [store] = useState10(() => create10(() => runtime.getState()));
2900
+ useEffect15(() => {
2812
2901
  const updateState = () => writableStore(store).setState(runtime.getState(), true);
2813
2902
  updateState();
2814
2903
  return runtime.subscribe(updateState);
@@ -2816,13 +2905,13 @@ var useMessageStore2 = (runtime) => {
2816
2905
  return store;
2817
2906
  };
2818
2907
  var useMessageUtilsStore2 = () => {
2819
- const [store] = useState9(() => makeMessageUtilsStore());
2908
+ const [store] = useState10(() => makeMessageUtilsStore());
2820
2909
  return store;
2821
2910
  };
2822
2911
  var useEditComposerStore2 = (useMessageRuntime2) => {
2823
2912
  const runtime = useMessageRuntime2.getState().composer;
2824
- const [store] = useState9(() => create10(() => runtime.getState()));
2825
- useEffect14(() => {
2913
+ const [store] = useState10(() => create10(() => runtime.getState()));
2914
+ useEffect15(() => {
2826
2915
  const updateState = () => writableStore(store).setState(runtime.getState());
2827
2916
  updateState();
2828
2917
  return runtime.subscribe(updateState);
@@ -2837,7 +2926,7 @@ var MessageRuntimeProvider = ({
2837
2926
  const useMessage2 = useMessageStore2(runtime);
2838
2927
  const useMessageUtils2 = useMessageUtilsStore2();
2839
2928
  const useEditComposer2 = useEditComposerStore2(useMessageRuntime2);
2840
- const [context] = useState9(() => {
2929
+ const [context] = useState10(() => {
2841
2930
  return { useMessageRuntime: useMessageRuntime2, useMessage: useMessage2, useMessageUtils: useMessageUtils2, useEditComposer: useEditComposer2 };
2842
2931
  });
2843
2932
  return /* @__PURE__ */ jsx32(MessageContext.Provider, { value: context, children });
@@ -2944,7 +3033,7 @@ var subscribeToMainThread = (runtime, callback) => {
2944
3033
  };
2945
3034
 
2946
3035
  // src/runtimes/local/useLocalRuntime.tsx
2947
- import { useInsertionEffect, useMemo as useMemo11, useState as useState11 } from "react";
3036
+ import { useInsertionEffect, useMemo as useMemo11, useState as useState12 } from "react";
2948
3037
 
2949
3038
  // src/runtimes/core/BaseAssistantRuntimeCore.tsx
2950
3039
  var BaseAssistantRuntimeCore = class {
@@ -3110,10 +3199,24 @@ var ProxyConfigProvider = class {
3110
3199
  }
3111
3200
  registerModelConfigProvider(provider) {
3112
3201
  this._providers.add(provider);
3202
+ const unsubscribe = provider.subscribe?.(() => {
3203
+ this.notifySubscribers();
3204
+ });
3205
+ this.notifySubscribers();
3113
3206
  return () => {
3114
3207
  this._providers.delete(provider);
3208
+ unsubscribe?.();
3209
+ this.notifySubscribers();
3115
3210
  };
3116
3211
  }
3212
+ _subscribers = /* @__PURE__ */ new Set();
3213
+ notifySubscribers() {
3214
+ for (const callback of this._subscribers) callback();
3215
+ }
3216
+ subscribe(callback) {
3217
+ this._subscribers.add(callback);
3218
+ return () => this._subscribers.delete(callback);
3219
+ }
3117
3220
  };
3118
3221
 
3119
3222
  // src/utils/idUtils.tsx
@@ -3495,7 +3598,9 @@ var getThreadState = (runtime) => {
3495
3598
  });
3496
3599
  };
3497
3600
  var ThreadRuntimeImpl = class {
3498
- // public path = "assistant.threads[main]"; // TODO
3601
+ get path() {
3602
+ return this._threadBinding.path;
3603
+ }
3499
3604
  /**
3500
3605
  * @deprecated Use `getState().threadId` instead. This will be removed in 0.6.0.
3501
3606
  */
@@ -3550,22 +3655,30 @@ var ThreadRuntimeImpl = class {
3550
3655
  _threadBinding;
3551
3656
  constructor(threadBinding) {
3552
3657
  const stateBinding = new LazyMemoizeSubject({
3658
+ path: threadBinding.path,
3553
3659
  getState: () => getThreadState(threadBinding.getState()),
3554
3660
  subscribe: (callback) => threadBinding.subscribe(callback)
3555
3661
  });
3556
3662
  this._threadBinding = {
3663
+ path: threadBinding.path,
3557
3664
  getState: () => threadBinding.getState(),
3558
3665
  getStateState: () => stateBinding.getState(),
3559
3666
  outerSubscribe: (callback) => threadBinding.outerSubscribe(callback),
3560
3667
  subscribe: (callback) => threadBinding.subscribe(callback)
3561
3668
  };
3669
+ this.composer = new ThreadComposerRuntimeImpl(
3670
+ new NestedSubscriptionSubject({
3671
+ path: {
3672
+ ...this.path,
3673
+ ref: this.path.ref + `${this.path.ref}.composer`,
3674
+ composerSource: "thread"
3675
+ },
3676
+ getState: () => this._threadBinding.getState().composer,
3677
+ subscribe: (callback) => this._threadBinding.subscribe(callback)
3678
+ })
3679
+ );
3562
3680
  }
3563
- composer = new ThreadComposerRuntimeImpl(
3564
- new NestedSubscriptionSubject({
3565
- getState: () => this._threadBinding.getState().composer,
3566
- subscribe: (callback) => this._threadBinding.subscribe(callback)
3567
- })
3568
- );
3681
+ composer;
3569
3682
  getState() {
3570
3683
  return this._threadBinding.getStateState();
3571
3684
  }
@@ -3643,20 +3756,49 @@ var ThreadRuntimeImpl = class {
3643
3756
  }
3644
3757
  getMesssageByIndex(idx) {
3645
3758
  if (idx < 0) throw new Error("Message index must be >= 0");
3759
+ return this._getMessageRuntime(
3760
+ {
3761
+ ...this.path,
3762
+ ref: this.path.ref + `${this.path.ref}.messages[${idx}]`,
3763
+ messageSelector: { type: "index", index: idx }
3764
+ },
3765
+ () => {
3766
+ const messages2 = this._threadBinding.getState().messages;
3767
+ const message = messages2[idx];
3768
+ if (!message) return void 0;
3769
+ return {
3770
+ message,
3771
+ parentId: messages2[idx - 1]?.id ?? null
3772
+ };
3773
+ }
3774
+ );
3775
+ }
3776
+ getMesssageById(messageId) {
3777
+ return this._getMessageRuntime(
3778
+ {
3779
+ ...this.path,
3780
+ ref: this.path.ref + `${this.path.ref}.messages[messageId=${JSON.stringify(messageId)}]`,
3781
+ messageSelector: { type: "messageId", messageId }
3782
+ },
3783
+ () => this._threadBinding.getState().getMessageById(messageId)
3784
+ );
3785
+ }
3786
+ _getMessageRuntime(path, callback) {
3646
3787
  return new MessageRuntimeImpl(
3647
3788
  new ShallowMemoizeSubject({
3789
+ path,
3648
3790
  getState: () => {
3649
- const { messages: messages2, speech: speechState } = this.getState();
3650
- const message = messages2[idx];
3651
- if (!message) return SKIP_UPDATE;
3791
+ const { message, parentId } = callback() ?? {};
3792
+ const { messages: messages2, speech: speechState } = this._threadBinding.getState();
3793
+ if (!message || parentId === void 0) return SKIP_UPDATE;
3652
3794
  const thread = this._threadBinding.getState();
3653
3795
  const branches = thread.getBranches(message.id);
3654
3796
  const submittedFeedback = thread.getSubmittedFeedback(message.id);
3655
3797
  return {
3656
3798
  ...message,
3657
3799
  message,
3658
- isLast: idx === messages2.length - 1,
3659
- parentId: messages2[idx - 1]?.id ?? null,
3800
+ isLast: messages2.at(-1)?.id === message.id,
3801
+ parentId,
3660
3802
  branches,
3661
3803
  branchNumber: branches.indexOf(message.id) + 1,
3662
3804
  branchCount: branches.length,
@@ -3664,7 +3806,7 @@ var ThreadRuntimeImpl = class {
3664
3806
  submittedFeedback
3665
3807
  };
3666
3808
  },
3667
- subscribe: (callback) => this._threadBinding.subscribe(callback)
3809
+ subscribe: (callback2) => this._threadBinding.subscribe(callback2)
3668
3810
  }),
3669
3811
  this._threadBinding
3670
3812
  );
@@ -3674,6 +3816,7 @@ var ThreadRuntimeImpl = class {
3674
3816
  let subject = this._eventListenerNestedSubscriptions.get(event);
3675
3817
  if (!subject) {
3676
3818
  subject = new NestedSubscriptionSubject({
3819
+ path: this.path,
3677
3820
  getState: () => ({
3678
3821
  subscribe: (callback2) => this._threadBinding.getState().unstable_on(event, callback2)
3679
3822
  }),
@@ -3703,16 +3846,19 @@ var AssistantRuntimeImpl = class _AssistantRuntimeImpl {
3703
3846
  registerModelConfigProvider(provider) {
3704
3847
  return this._core.registerModelConfigProvider(provider);
3705
3848
  }
3706
- // TODO events for thread switching
3707
3849
  /**
3708
3850
  * @deprecated Thread is now static and never gets updated. This will be removed in 0.6.0.
3709
3851
  */
3710
3852
  subscribe(callback) {
3711
3853
  return this._core.subscribe(callback);
3712
3854
  }
3713
- static createThreadRuntime(_core, CustomThreadRuntime = ThreadRuntimeImpl) {
3855
+ static createMainThreadRuntime(_core, CustomThreadRuntime = ThreadRuntimeImpl) {
3714
3856
  return new CustomThreadRuntime(
3715
3857
  new NestedSubscriptionSubject({
3858
+ path: {
3859
+ ref: "threads.main",
3860
+ threadSelector: { type: "main" }
3861
+ },
3716
3862
  getState: () => _core.thread,
3717
3863
  subscribe: (callback) => _core.subscribe(callback)
3718
3864
  })
@@ -3721,7 +3867,7 @@ var AssistantRuntimeImpl = class _AssistantRuntimeImpl {
3721
3867
  static create(_core, CustomThreadRuntime = ThreadRuntimeImpl) {
3722
3868
  return new _AssistantRuntimeImpl(
3723
3869
  _core,
3724
- _AssistantRuntimeImpl.createThreadRuntime(_core, CustomThreadRuntime)
3870
+ _AssistantRuntimeImpl.createMainThreadRuntime(_core, CustomThreadRuntime)
3725
3871
  );
3726
3872
  }
3727
3873
  };
@@ -3893,7 +4039,7 @@ var streamUtils = {
3893
4039
  };
3894
4040
 
3895
4041
  // src/runtimes/edge/useEdgeRuntime.ts
3896
- import { useState as useState10 } from "react";
4042
+ import { useState as useState11 } from "react";
3897
4043
 
3898
4044
  // src/runtimes/edge/streams/assistantDecoderStream.ts
3899
4045
  function assistantDecoderStream() {
@@ -3923,6 +4069,13 @@ function assistantDecoderStream() {
3923
4069
  const { toolCallId: id, toolName: name } = value;
3924
4070
  toolCallNames.set(id, name);
3925
4071
  currentToolCall = { id, name, argsText: "" };
4072
+ controller.enqueue({
4073
+ type: "tool-call-delta",
4074
+ toolCallType: "function",
4075
+ toolCallId: id,
4076
+ toolName: name,
4077
+ argsTextDelta: ""
4078
+ });
3926
4079
  break;
3927
4080
  }
3928
4081
  case "c" /* ToolCallDelta */: {
@@ -4067,7 +4220,7 @@ var splitLocalRuntimeOptions = (options) => {
4067
4220
  // src/runtimes/edge/useEdgeRuntime.ts
4068
4221
  var useEdgeRuntime = (options) => {
4069
4222
  const { localRuntimeOptions, otherOptions } = splitLocalRuntimeOptions(options);
4070
- const [adapter] = useState10(() => new EdgeChatAdapter(otherOptions));
4223
+ const [adapter] = useState11(() => new EdgeChatAdapter(otherOptions));
4071
4224
  return useLocalRuntime(adapter, localRuntimeOptions);
4072
4225
  };
4073
4226
 
@@ -4119,6 +4272,9 @@ var DefaultEditComposerRuntimeCore = class extends BaseComposerRuntimeCore {
4119
4272
  var BaseThreadRuntimeCore = class {
4120
4273
  constructor(configProvider) {
4121
4274
  this.configProvider = configProvider;
4275
+ this.configProvider.subscribe?.(() => {
4276
+ this._notifyEventSubscribers("model-config-update");
4277
+ });
4122
4278
  }
4123
4279
  _subscriptions = /* @__PURE__ */ new Set();
4124
4280
  repository = new MessageRepository();
@@ -4146,6 +4302,9 @@ var BaseThreadRuntimeCore = class {
4146
4302
  );
4147
4303
  this._notifySubscribers();
4148
4304
  }
4305
+ getMessageById(messageId) {
4306
+ return this.repository.getMessage(messageId);
4307
+ }
4149
4308
  getBranches(messageId) {
4150
4309
  return this.repository.getBranches(messageId);
4151
4310
  }
@@ -4184,7 +4343,7 @@ var BaseThreadRuntimeCore = class {
4184
4343
  if (!adapter) throw new Error("Speech adapter not configured");
4185
4344
  const { message } = this.repository.getMessage(messageId);
4186
4345
  this._stopSpeaking?.();
4187
- const utterance = adapter.speak(message);
4346
+ const utterance = adapter.speak(getThreadMessageText(message));
4188
4347
  const unsub = utterance.subscribe(() => {
4189
4348
  if (utterance.status.type === "ended") {
4190
4349
  this._stopSpeaking = void 0;
@@ -4490,12 +4649,12 @@ var LocalRuntimeImpl = class _LocalRuntimeImpl extends AssistantRuntimeImpl {
4490
4649
  static create(_core) {
4491
4650
  return new _LocalRuntimeImpl(
4492
4651
  _core,
4493
- AssistantRuntimeImpl.createThreadRuntime(_core, ThreadRuntimeImpl)
4652
+ AssistantRuntimeImpl.createMainThreadRuntime(_core, ThreadRuntimeImpl)
4494
4653
  );
4495
4654
  }
4496
4655
  };
4497
4656
  var useLocalRuntime = (adapter, options = {}) => {
4498
- const [runtime] = useState11(() => new LocalRuntimeCore(adapter, options));
4657
+ const [runtime] = useState12(() => new LocalRuntimeCore(adapter, options));
4499
4658
  useInsertionEffect(() => {
4500
4659
  runtime.thread.adapter = adapter;
4501
4660
  runtime.thread.options = options;
@@ -4504,7 +4663,7 @@ var useLocalRuntime = (adapter, options = {}) => {
4504
4663
  };
4505
4664
 
4506
4665
  // src/runtimes/external-store/useExternalStoreRuntime.tsx
4507
- import { useEffect as useEffect15, useMemo as useMemo12, useState as useState12 } from "react";
4666
+ import { useEffect as useEffect16, useMemo as useMemo12, useState as useState13 } from "react";
4508
4667
 
4509
4668
  // src/runtimes/external-store/getExternalStoreMessage.tsx
4510
4669
  var symbolInnerMessage = Symbol("innerMessage");
@@ -4823,8 +4982,8 @@ var ExternalStoreRuntimeCore = class extends BaseAssistantRuntimeCore {
4823
4982
 
4824
4983
  // src/runtimes/external-store/useExternalStoreRuntime.tsx
4825
4984
  var useExternalStoreRuntime = (store) => {
4826
- const [runtime] = useState12(() => new ExternalStoreRuntimeCore(store));
4827
- useEffect15(() => {
4985
+ const [runtime] = useState13(() => new ExternalStoreRuntimeCore(store));
4986
+ useEffect16(() => {
4828
4987
  runtime.thread.store = store;
4829
4988
  });
4830
4989
  return useMemo12(
@@ -4980,7 +5139,7 @@ var shallowArrayEqual = (a, b) => {
4980
5139
  };
4981
5140
 
4982
5141
  // src/runtimes/dangerous-in-browser/useDangerousInBrowserRuntime.ts
4983
- import { useState as useState13 } from "react";
5142
+ import { useState as useState14 } from "react";
4984
5143
 
4985
5144
  // src/runtimes/dangerous-in-browser/DangerousInBrowserAdapter.ts
4986
5145
  var DangerousInBrowserAdapter = class {
@@ -5009,14 +5168,13 @@ var DangerousInBrowserAdapter = class {
5009
5168
  // src/runtimes/dangerous-in-browser/useDangerousInBrowserRuntime.ts
5010
5169
  var useDangerousInBrowserRuntime = (options) => {
5011
5170
  const { localRuntimeOptions, otherOptions } = splitLocalRuntimeOptions(options);
5012
- const [adapter] = useState13(() => new DangerousInBrowserAdapter(otherOptions));
5171
+ const [adapter] = useState14(() => new DangerousInBrowserAdapter(otherOptions));
5013
5172
  return useLocalRuntime(adapter, localRuntimeOptions);
5014
5173
  };
5015
5174
 
5016
5175
  // src/runtimes/speech/WebSpeechSynthesisAdapter.ts
5017
5176
  var WebSpeechSynthesisAdapter = class {
5018
- speak(message) {
5019
- const text = getThreadMessageText(message);
5177
+ speak(text) {
5020
5178
  const utterance = new SpeechSynthesisUtterance(text);
5021
5179
  const subscribers = /* @__PURE__ */ new Set();
5022
5180
  const handleEnd = (reason, error) => {
@@ -5596,8 +5754,8 @@ CircleStopIcon.displayName = "CircleStopIcon";
5596
5754
  // src/ui/attachment.tsx
5597
5755
  import {
5598
5756
  forwardRef as forwardRef28,
5599
- useEffect as useEffect16,
5600
- useState as useState14
5757
+ useEffect as useEffect17,
5758
+ useState as useState15
5601
5759
  } from "react";
5602
5760
  import { CircleXIcon, FileIcon } from "lucide-react";
5603
5761
 
@@ -5640,8 +5798,8 @@ var AttachmentRoot = withDefaults(attachment_exports.Root, {
5640
5798
  });
5641
5799
  AttachmentRoot.displayName = "AttachmentRoot";
5642
5800
  var useFileSrc = (file) => {
5643
- const [src, setSrc] = useState14(void 0);
5644
- useEffect16(() => {
5801
+ const [src, setSrc] = useState15(void 0);
5802
+ useEffect17(() => {
5645
5803
  if (!file) {
5646
5804
  setSrc(void 0);
5647
5805
  return;
@@ -5665,7 +5823,7 @@ var useAttachmentSrc = () => {
5665
5823
  return useFileSrc(file) ?? src;
5666
5824
  };
5667
5825
  var AttachmentPreview = ({ src }) => {
5668
- const [isLoaded, setIsLoaded] = useState14(false);
5826
+ const [isLoaded, setIsLoaded] = useState15(false);
5669
5827
  return (
5670
5828
  // eslint-disable-next-line @next/next/no-img-element
5671
5829
  /* @__PURE__ */ jsx46(
@@ -6366,6 +6524,7 @@ export {
6366
6524
  useThreadIf,
6367
6525
  useThreadMessages,
6368
6526
  useThreadMessagesStore,
6527
+ useThreadModelConfig,
6369
6528
  useThreadRuntime,
6370
6529
  useThreadRuntimeStore,
6371
6530
  useThreadScrollToBottom,