@assistant-ui/react 0.5.80 → 0.5.82

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