@assistant-ui/react 0.5.1 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.mjs CHANGED
@@ -1178,7 +1178,7 @@ var COMPLETE_STATUS = {
1178
1178
  };
1179
1179
  var toContentPartStatus = (message, partIndex, part) => {
1180
1180
  if (message.role !== "assistant") return COMPLETE_STATUS;
1181
- const isLastPart = partIndex === message.content.length - 1;
1181
+ const isLastPart = partIndex === Math.max(0, message.content.length - 1);
1182
1182
  if (part.type !== "tool-call") {
1183
1183
  if ("reason" in message.status && message.status.reason === "tool-calls" && isLastPart)
1184
1184
  throw new Error(
@@ -1191,9 +1191,16 @@ var toContentPartStatus = (message, partIndex, part) => {
1191
1191
  }
1192
1192
  return message.status;
1193
1193
  };
1194
+ var EMPTY_CONTENT = Object.freeze({ type: "text", text: "" });
1194
1195
  var syncContentPart = ({ message }, useContentPart, partIndex) => {
1195
- const part = message.content[partIndex];
1196
- if (!part) return;
1196
+ let part = message.content[partIndex];
1197
+ if (!part) {
1198
+ if (message.content.length === 0 && partIndex === 0) {
1199
+ part = EMPTY_CONTENT;
1200
+ } else {
1201
+ return;
1202
+ }
1203
+ }
1197
1204
  const status = toContentPartStatus(message, partIndex, part);
1198
1205
  const currentState = useContentPart.getState();
1199
1206
  if (currentState.part === part && currentState.status === status) return;
@@ -1319,7 +1326,7 @@ var ContentPartPrimitiveText = forwardRef7(({ smooth = true, ...rest }, forwarde
1319
1326
  part: { text }
1320
1327
  } = useContentPartText();
1321
1328
  const smoothText = useSmooth(text, smooth);
1322
- return /* @__PURE__ */ jsx14(Primitive4.span, { "data-status": status, ...rest, ref: forwardedRef, children: smoothText });
1329
+ return /* @__PURE__ */ jsx14(Primitive4.span, { "data-status": status.type, ...rest, ref: forwardedRef, children: smoothText });
1323
1330
  });
1324
1331
  ContentPartPrimitiveText.displayName = "ContentPartPrimitive.Text";
1325
1332
 
@@ -1425,7 +1432,7 @@ var MessagePrimitiveContent = ({
1425
1432
  components
1426
1433
  }) => {
1427
1434
  const { useMessage } = useMessageContext();
1428
- const contentLength = useMessage((s) => s.message.content.length);
1435
+ const contentLength = useMessage((s) => s.message.content.length) || 1;
1429
1436
  return new Array(contentLength).fill(null).map((_, idx) => {
1430
1437
  const partIndex = idx;
1431
1438
  return /* @__PURE__ */ jsx16(
@@ -1729,7 +1736,7 @@ var useThreadViewportAutoScroll = ({
1729
1736
  const div = divRef.current;
1730
1737
  if (!div) return;
1731
1738
  const isAtBottom = useViewport.getState().isAtBottom;
1732
- const newIsAtBottom = div.scrollHeight - div.scrollTop <= div.clientHeight;
1739
+ const newIsAtBottom = div.scrollHeight - div.scrollTop <= div.clientHeight + 1;
1733
1740
  if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {
1734
1741
  } else {
1735
1742
  if (newIsAtBottom) {
@@ -1965,26 +1972,6 @@ var ThreadPrimitiveSuggestion = createActionButton(
1965
1972
  // src/runtimes/local/useLocalRuntime.tsx
1966
1973
  import { useInsertionEffect as useInsertionEffect3, useState as useState8 } from "react";
1967
1974
 
1968
- // src/utils/idUtils.tsx
1969
- import { customAlphabet } from "nanoid/non-secure";
1970
- var generateId = customAlphabet(
1971
- "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
1972
- 7
1973
- );
1974
- var optimisticPrefix = "__optimistic__";
1975
- var generateOptimisticId = () => `${optimisticPrefix}${generateId()}`;
1976
-
1977
- // src/internal.ts
1978
- var internal_exports = {};
1979
- __export(internal_exports, {
1980
- BaseAssistantRuntime: () => BaseAssistantRuntime,
1981
- MessageRepository: () => MessageRepository,
1982
- ProxyConfigProvider: () => ProxyConfigProvider,
1983
- TooltipIconButton: () => TooltipIconButton,
1984
- generateId: () => generateId,
1985
- useSmooth: () => useSmooth
1986
- });
1987
-
1988
1975
  // src/runtimes/core/BaseAssistantRuntime.tsx
1989
1976
  var BaseAssistantRuntime = class {
1990
1977
  constructor(_thread) {
@@ -2008,101 +1995,25 @@ var BaseAssistantRuntime = class {
2008
1995
  };
2009
1996
  };
2010
1997
 
2011
- // src/ui/base/tooltip-icon-button.tsx
2012
- import { forwardRef as forwardRef17 } from "react";
2013
-
2014
- // src/ui/base/tooltip.tsx
2015
- import * as TooltipPrimitive from "@radix-ui/react-tooltip";
2016
-
2017
- // src/ui/utils/withDefaults.tsx
2018
- import {
2019
- forwardRef as forwardRef15
2020
- } from "react";
2021
- import classNames from "classnames";
2022
- import { jsx as jsx25 } from "react/jsx-runtime";
2023
- var withDefaultProps = ({
2024
- className,
2025
- ...defaultProps
2026
- }) => ({ className: classNameProp, ...props }) => {
2027
- return {
2028
- className: classNames(className, classNameProp),
2029
- ...defaultProps,
2030
- ...props
2031
- };
2032
- };
2033
- var withDefaults = (Component, defaultProps) => {
2034
- const getProps = withDefaultProps(defaultProps);
2035
- const WithDefaults = forwardRef15(
2036
- (props, ref) => {
2037
- const ComponentAsAny = Component;
2038
- return /* @__PURE__ */ jsx25(ComponentAsAny, { ...getProps(props), ref });
2039
- }
2040
- );
2041
- WithDefaults.displayName = "withDefaults(" + (typeof Component === "string" ? Component : Component.displayName) + ")";
2042
- return WithDefaults;
2043
- };
2044
-
2045
- // src/ui/base/tooltip.tsx
2046
- import { jsx as jsx26 } from "react/jsx-runtime";
2047
- var Tooltip = (props) => {
2048
- return /* @__PURE__ */ jsx26(TooltipPrimitive.Provider, { children: /* @__PURE__ */ jsx26(TooltipPrimitive.Root, { ...props }) });
2049
- };
2050
- Tooltip.displayName = "Tooltip";
2051
- var TooltipTrigger = TooltipPrimitive.Trigger;
2052
- var TooltipContent = withDefaults(TooltipPrimitive.Content, {
2053
- sideOffset: 4,
2054
- className: "aui-tooltip-content"
1998
+ // src/internal.ts
1999
+ var internal_exports = {};
2000
+ __export(internal_exports, {
2001
+ BaseAssistantRuntime: () => BaseAssistantRuntime,
2002
+ MessageRepository: () => MessageRepository,
2003
+ ProxyConfigProvider: () => ProxyConfigProvider,
2004
+ TooltipIconButton: () => TooltipIconButton,
2005
+ generateId: () => generateId,
2006
+ useSmooth: () => useSmooth
2055
2007
  });
2056
- TooltipContent.displayName = "TooltipContent";
2057
2008
 
2058
- // src/ui/base/button.tsx
2059
- import { cva } from "class-variance-authority";
2060
- import { Primitive as Primitive11 } from "@radix-ui/react-primitive";
2061
- import { forwardRef as forwardRef16 } from "react";
2062
- import { jsx as jsx27 } from "react/jsx-runtime";
2063
- var buttonVariants = cva("aui-button", {
2064
- variants: {
2065
- variant: {
2066
- default: "aui-button-primary",
2067
- outline: "aui-button-outline",
2068
- ghost: "aui-button-ghost"
2069
- },
2070
- size: {
2071
- default: "aui-button-medium",
2072
- icon: "aui-button-icon"
2073
- }
2074
- },
2075
- defaultVariants: {
2076
- variant: "default",
2077
- size: "default"
2078
- }
2079
- });
2080
- var Button = forwardRef16(
2081
- ({ className, variant, size, ...props }, ref) => {
2082
- return /* @__PURE__ */ jsx27(
2083
- Primitive11.button,
2084
- {
2085
- className: buttonVariants({ variant, size, className }),
2086
- ...props,
2087
- ref
2088
- }
2089
- );
2090
- }
2009
+ // src/utils/idUtils.tsx
2010
+ import { customAlphabet } from "nanoid/non-secure";
2011
+ var generateId = customAlphabet(
2012
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
2013
+ 7
2091
2014
  );
2092
- Button.displayName = "Button";
2093
-
2094
- // src/ui/base/tooltip-icon-button.tsx
2095
- import { jsx as jsx28, jsxs as jsxs4 } from "react/jsx-runtime";
2096
- var TooltipIconButton = forwardRef17(({ children, tooltip, side = "bottom", ...rest }, ref) => {
2097
- return /* @__PURE__ */ jsxs4(Tooltip, { children: [
2098
- /* @__PURE__ */ jsx28(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs4(Button, { variant: "ghost", size: "icon", ...rest, ref, children: [
2099
- children,
2100
- /* @__PURE__ */ jsx28("span", { className: "aui-sr-only", children: tooltip })
2101
- ] }) }),
2102
- /* @__PURE__ */ jsx28(TooltipContent, { side, children: tooltip })
2103
- ] });
2104
- });
2105
- TooltipIconButton.displayName = "TooltipIconButton";
2015
+ var optimisticPrefix = "__optimistic__";
2016
+ var generateOptimisticId = () => `${optimisticPrefix}${generateId()}`;
2106
2017
 
2107
2018
  // src/runtimes/edge/converters/fromCoreMessage.ts
2108
2019
  var fromCoreMessages = (message) => {
@@ -2315,6 +2226,102 @@ var MessageRepository = class {
2315
2226
  }
2316
2227
  };
2317
2228
 
2229
+ // src/ui/base/tooltip-icon-button.tsx
2230
+ import { forwardRef as forwardRef17 } from "react";
2231
+
2232
+ // src/ui/base/tooltip.tsx
2233
+ import * as TooltipPrimitive from "@radix-ui/react-tooltip";
2234
+
2235
+ // src/ui/utils/withDefaults.tsx
2236
+ import {
2237
+ forwardRef as forwardRef15
2238
+ } from "react";
2239
+ import classNames from "classnames";
2240
+ import { jsx as jsx25 } from "react/jsx-runtime";
2241
+ var withDefaultProps = ({
2242
+ className,
2243
+ ...defaultProps
2244
+ }) => ({ className: classNameProp, ...props }) => {
2245
+ return {
2246
+ className: classNames(className, classNameProp),
2247
+ ...defaultProps,
2248
+ ...props
2249
+ };
2250
+ };
2251
+ var withDefaults = (Component, defaultProps) => {
2252
+ const getProps = withDefaultProps(defaultProps);
2253
+ const WithDefaults = forwardRef15(
2254
+ (props, ref) => {
2255
+ const ComponentAsAny = Component;
2256
+ return /* @__PURE__ */ jsx25(ComponentAsAny, { ...getProps(props), ref });
2257
+ }
2258
+ );
2259
+ WithDefaults.displayName = "withDefaults(" + (typeof Component === "string" ? Component : Component.displayName) + ")";
2260
+ return WithDefaults;
2261
+ };
2262
+
2263
+ // src/ui/base/tooltip.tsx
2264
+ import { jsx as jsx26 } from "react/jsx-runtime";
2265
+ var Tooltip = (props) => {
2266
+ return /* @__PURE__ */ jsx26(TooltipPrimitive.Provider, { children: /* @__PURE__ */ jsx26(TooltipPrimitive.Root, { ...props }) });
2267
+ };
2268
+ Tooltip.displayName = "Tooltip";
2269
+ var TooltipTrigger = TooltipPrimitive.Trigger;
2270
+ var TooltipContent = withDefaults(TooltipPrimitive.Content, {
2271
+ sideOffset: 4,
2272
+ className: "aui-tooltip-content"
2273
+ });
2274
+ TooltipContent.displayName = "TooltipContent";
2275
+
2276
+ // src/ui/base/button.tsx
2277
+ import { cva } from "class-variance-authority";
2278
+ import { Primitive as Primitive11 } from "@radix-ui/react-primitive";
2279
+ import { forwardRef as forwardRef16 } from "react";
2280
+ import { jsx as jsx27 } from "react/jsx-runtime";
2281
+ var buttonVariants = cva("aui-button", {
2282
+ variants: {
2283
+ variant: {
2284
+ default: "aui-button-primary",
2285
+ outline: "aui-button-outline",
2286
+ ghost: "aui-button-ghost"
2287
+ },
2288
+ size: {
2289
+ default: "aui-button-medium",
2290
+ icon: "aui-button-icon"
2291
+ }
2292
+ },
2293
+ defaultVariants: {
2294
+ variant: "default",
2295
+ size: "default"
2296
+ }
2297
+ });
2298
+ var Button = forwardRef16(
2299
+ ({ className, variant, size, ...props }, ref) => {
2300
+ return /* @__PURE__ */ jsx27(
2301
+ Primitive11.button,
2302
+ {
2303
+ className: buttonVariants({ variant, size, className }),
2304
+ ...props,
2305
+ ref
2306
+ }
2307
+ );
2308
+ }
2309
+ );
2310
+ Button.displayName = "Button";
2311
+
2312
+ // src/ui/base/tooltip-icon-button.tsx
2313
+ import { jsx as jsx28, jsxs as jsxs4 } from "react/jsx-runtime";
2314
+ var TooltipIconButton = forwardRef17(({ children, tooltip, side = "bottom", ...rest }, ref) => {
2315
+ return /* @__PURE__ */ jsxs4(Tooltip, { children: [
2316
+ /* @__PURE__ */ jsx28(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs4(Button, { variant: "ghost", size: "icon", ...rest, ref, children: [
2317
+ children,
2318
+ /* @__PURE__ */ jsx28("span", { className: "aui-sr-only", children: tooltip })
2319
+ ] }) }),
2320
+ /* @__PURE__ */ jsx28(TooltipContent, { side, children: tooltip })
2321
+ ] });
2322
+ });
2323
+ TooltipIconButton.displayName = "TooltipIconButton";
2324
+
2318
2325
  // src/runtimes/edge/converters/toLanguageModelMessages.ts
2319
2326
  var assistantMessageSplitter = () => {
2320
2327
  const stash = [];
@@ -3323,9 +3330,7 @@ var EdgeChatAdapter = class {
3323
3330
  signal: abortSignal
3324
3331
  });
3325
3332
  if (result.status !== 200) {
3326
- throw new Error(
3327
- `Edge runtime returned status ${result.status}: ${await result.text()}`
3328
- );
3333
+ throw new Error(`Status ${result.status}: ${await result.text()}`);
3329
3334
  }
3330
3335
  const stream = result.body.pipeThrough(new TextDecoderStream()).pipeThrough(chunkByLineStream()).pipeThrough(assistantDecoderStream()).pipeThrough(toolResultStream(config.tools)).pipeThrough(runResultStream());
3331
3336
  let update;
@@ -3347,31 +3352,10 @@ var useEdgeRuntime = ({
3347
3352
  return useLocalRuntime(adapter, { initialMessages });
3348
3353
  };
3349
3354
 
3350
- // src/runtimes/local/LocalRuntime.tsx
3355
+ // src/runtimes/local/shouldContinue.tsx
3351
3356
  var shouldContinue = (result) => result.status?.type === "requires-action" && result.status.reason === "tool-calls" && result.content.every((c) => c.type !== "tool-call" || !!c.result);
3352
- var LocalRuntime = class extends BaseAssistantRuntime {
3353
- _proxyConfigProvider;
3354
- constructor(adapter, options) {
3355
- const proxyConfigProvider = new ProxyConfigProvider();
3356
- super(new LocalThreadRuntime(proxyConfigProvider, adapter, options));
3357
- this._proxyConfigProvider = proxyConfigProvider;
3358
- }
3359
- set adapter(adapter) {
3360
- this.thread.adapter = adapter;
3361
- }
3362
- registerModelConfigProvider(provider) {
3363
- return this._proxyConfigProvider.registerModelConfigProvider(provider);
3364
- }
3365
- switchToThread(threadId) {
3366
- if (threadId) {
3367
- throw new Error("LocalRuntime does not yet support switching threads");
3368
- }
3369
- return this.thread = new LocalThreadRuntime(
3370
- this._proxyConfigProvider,
3371
- this.thread.adapter
3372
- );
3373
- }
3374
- };
3357
+
3358
+ // src/runtimes/local/LocalThreadRuntime.tsx
3375
3359
  var CAPABILITIES = Object.freeze({
3376
3360
  edit: true,
3377
3361
  reload: true,
@@ -3431,7 +3415,7 @@ var LocalThreadRuntime = class {
3431
3415
  id,
3432
3416
  role: "assistant",
3433
3417
  status: { type: "running" },
3434
- content: [{ type: "text", text: "" }],
3418
+ content: [],
3435
3419
  createdAt: /* @__PURE__ */ new Date()
3436
3420
  };
3437
3421
  do {
@@ -3543,6 +3527,31 @@ var LocalThreadRuntime = class {
3543
3527
  }
3544
3528
  };
3545
3529
 
3530
+ // src/runtimes/local/LocalRuntime.tsx
3531
+ var LocalRuntime = class extends BaseAssistantRuntime {
3532
+ _proxyConfigProvider;
3533
+ constructor(adapter, options) {
3534
+ const proxyConfigProvider = new ProxyConfigProvider();
3535
+ super(new LocalThreadRuntime(proxyConfigProvider, adapter, options));
3536
+ this._proxyConfigProvider = proxyConfigProvider;
3537
+ }
3538
+ set adapter(adapter) {
3539
+ this.thread.adapter = adapter;
3540
+ }
3541
+ registerModelConfigProvider(provider) {
3542
+ return this._proxyConfigProvider.registerModelConfigProvider(provider);
3543
+ }
3544
+ switchToThread(threadId) {
3545
+ if (threadId) {
3546
+ throw new Error("LocalRuntime does not yet support switching threads");
3547
+ }
3548
+ return this.thread = new LocalThreadRuntime(
3549
+ this._proxyConfigProvider,
3550
+ this.thread.adapter
3551
+ );
3552
+ }
3553
+ };
3554
+
3546
3555
  // src/runtimes/local/useLocalRuntime.tsx
3547
3556
  var useLocalRuntime = (adapter, options) => {
3548
3557
  const [runtime] = useState8(() => new LocalRuntime(adapter, options));
@@ -3552,6 +3561,213 @@ var useLocalRuntime = (adapter, options) => {
3552
3561
  return runtime;
3553
3562
  };
3554
3563
 
3564
+ // src/runtimes/external-store/ExternalStoreThreadRuntime.tsx
3565
+ import { create as create14 } from "zustand";
3566
+
3567
+ // src/runtimes/external-store/getExternalStoreMessage.tsx
3568
+ var symbolInnerMessage = Symbol("innerMessage");
3569
+ var getExternalStoreMessage = (message) => {
3570
+ return message[symbolInnerMessage];
3571
+ };
3572
+
3573
+ // src/runtimes/external-store/useExternalStoreSync.tsx
3574
+ import { useEffect as useEffect11, useMemo as useMemo3 } from "react";
3575
+
3576
+ // src/runtimes/external-store/ThreadMessageConverter.ts
3577
+ var ThreadMessageConverter = class {
3578
+ cache = /* @__PURE__ */ new WeakMap();
3579
+ convertMessages(messages, converter, keyMapper = (key) => key) {
3580
+ return messages.map((m, idx) => {
3581
+ const key = keyMapper(m);
3582
+ const cached = this.cache.get(key);
3583
+ const newMessage = converter(cached, m, idx);
3584
+ this.cache.set(key, newMessage);
3585
+ return newMessage;
3586
+ });
3587
+ }
3588
+ };
3589
+
3590
+ // src/runtimes/external-store/useExternalStoreSync.tsx
3591
+ var useExternalStoreSync = (adapter, updateData) => {
3592
+ const [converter, convertCallback] = useMemo3(() => {
3593
+ const converter2 = adapter.convertMessage ?? ((m) => m);
3594
+ const convertCallback2 = (cache, m, idx) => {
3595
+ if (cache) return cache;
3596
+ const newMessage = converter2(m, idx);
3597
+ newMessage[symbolInnerMessage] = m;
3598
+ return newMessage;
3599
+ };
3600
+ return [new ThreadMessageConverter(), convertCallback2];
3601
+ }, [adapter.convertMessage]);
3602
+ useEffect11(() => {
3603
+ updateData(
3604
+ adapter.isRunning ?? false,
3605
+ converter.convertMessages(adapter.messages, convertCallback)
3606
+ );
3607
+ }, [
3608
+ updateData,
3609
+ converter,
3610
+ convertCallback,
3611
+ adapter.messages,
3612
+ adapter.isRunning
3613
+ ]);
3614
+ };
3615
+
3616
+ // src/runtimes/external-store/ExternalStoreThreadRuntime.tsx
3617
+ var hasUpcomingMessage = (isRunning, messages) => {
3618
+ return isRunning && messages[messages.length - 1]?.role !== "assistant";
3619
+ };
3620
+ var ExternalStoreThreadRuntime = class {
3621
+ constructor(store) {
3622
+ this.store = store;
3623
+ this.useStore = create14(() => ({
3624
+ store
3625
+ }));
3626
+ }
3627
+ _subscriptions = /* @__PURE__ */ new Set();
3628
+ repository = new MessageRepository();
3629
+ assistantOptimisticId = null;
3630
+ useStore;
3631
+ get capabilities() {
3632
+ return {
3633
+ edit: this.store.onEdit !== void 0,
3634
+ reload: this.store.onReload !== void 0,
3635
+ cancel: this.store.onCancel !== void 0,
3636
+ copy: true
3637
+ };
3638
+ }
3639
+ messages = [];
3640
+ isRunning = false;
3641
+ getBranches(messageId) {
3642
+ return this.repository.getBranches(messageId);
3643
+ }
3644
+ switchToBranch(branchId) {
3645
+ this.repository.switchToBranch(branchId);
3646
+ this.updateMessages(this.repository.getMessages());
3647
+ }
3648
+ async append(message) {
3649
+ if (message.parentId !== (this.messages.at(-1)?.id ?? null)) {
3650
+ if (!this.store.onEdit)
3651
+ throw new Error("Runtime does not support editing messages.");
3652
+ await this.store.onEdit(message);
3653
+ } else {
3654
+ await this.store.onNew(message);
3655
+ }
3656
+ }
3657
+ async startRun(parentId) {
3658
+ if (!this.store.onReload)
3659
+ throw new Error("Runtime does not support reloading messages.");
3660
+ await this.store.onReload(parentId);
3661
+ }
3662
+ cancelRun() {
3663
+ if (!this.store.onCancel)
3664
+ throw new Error("Runtime does not support cancelling runs.");
3665
+ this.store.onCancel();
3666
+ if (this.assistantOptimisticId) {
3667
+ this.repository.deleteMessage(this.assistantOptimisticId);
3668
+ this.assistantOptimisticId = null;
3669
+ }
3670
+ let messages = this.repository.getMessages();
3671
+ setTimeout(() => {
3672
+ this.updateMessages(messages);
3673
+ }, 0);
3674
+ }
3675
+ subscribe(callback) {
3676
+ this._subscriptions.add(callback);
3677
+ return () => this._subscriptions.delete(callback);
3678
+ }
3679
+ updateMessages = (messages) => {
3680
+ this.store.setMessages?.(
3681
+ messages.flatMap(getExternalStoreMessage).filter((m) => m != null)
3682
+ );
3683
+ };
3684
+ onStoreUpdated() {
3685
+ if (this.useStore.getState().store !== this.store) {
3686
+ this.useStore.setState({ store: this.store });
3687
+ }
3688
+ }
3689
+ updateData = (isRunning, vm) => {
3690
+ for (let i = 0; i < vm.length; i++) {
3691
+ const message = vm[i];
3692
+ const parent = vm[i - 1];
3693
+ this.repository.addOrUpdateMessage(parent?.id ?? null, message);
3694
+ }
3695
+ if (this.assistantOptimisticId) {
3696
+ this.repository.deleteMessage(this.assistantOptimisticId);
3697
+ this.assistantOptimisticId = null;
3698
+ }
3699
+ if (hasUpcomingMessage(isRunning, vm)) {
3700
+ this.assistantOptimisticId = this.repository.appendOptimisticMessage(
3701
+ vm.at(-1)?.id ?? null,
3702
+ {
3703
+ role: "assistant",
3704
+ content: []
3705
+ }
3706
+ );
3707
+ }
3708
+ this.repository.resetHead(
3709
+ this.assistantOptimisticId ?? vm.at(-1)?.id ?? null
3710
+ );
3711
+ this.messages = this.repository.getMessages();
3712
+ this.isRunning = isRunning;
3713
+ for (const callback of this._subscriptions) callback();
3714
+ };
3715
+ unstable_synchronizer = () => {
3716
+ const { store } = this.useStore();
3717
+ useExternalStoreSync(store, this.updateData);
3718
+ return null;
3719
+ };
3720
+ addToolResult(options) {
3721
+ if (!this.store.onAddToolResult)
3722
+ throw new Error("Runtime does not support tool results.");
3723
+ this.store.onAddToolResult(options);
3724
+ }
3725
+ };
3726
+
3727
+ // src/runtimes/external-store/ExternalStoreRuntime.tsx
3728
+ var ExternalStoreRuntime = class extends BaseAssistantRuntime {
3729
+ _proxyConfigProvider = new ProxyConfigProvider();
3730
+ constructor(store) {
3731
+ super(new ExternalStoreThreadRuntime(store));
3732
+ }
3733
+ set store(store) {
3734
+ this.thread.store = store;
3735
+ }
3736
+ onStoreUpdated() {
3737
+ return this.thread.onStoreUpdated();
3738
+ }
3739
+ getModelConfig() {
3740
+ return this._proxyConfigProvider.getModelConfig();
3741
+ }
3742
+ registerModelConfigProvider(provider) {
3743
+ return this._proxyConfigProvider.registerModelConfigProvider(provider);
3744
+ }
3745
+ switchToThread(threadId) {
3746
+ if (threadId) {
3747
+ if (!this.store.onSwitchThread)
3748
+ throw new Error("Runtime does not support switching threads.");
3749
+ return this.store.onSwitchThread(threadId);
3750
+ } else {
3751
+ if (!this.store.onNewThread)
3752
+ throw new Error("Runtime does not support switching to new threads.");
3753
+ return this.store.onNewThread();
3754
+ }
3755
+ }
3756
+ };
3757
+
3758
+ // src/runtimes/external-store/useExternalStoreRuntime.tsx
3759
+ import { useEffect as useEffect12, useInsertionEffect as useInsertionEffect4, useState as useState9 } from "react";
3760
+ var useExternalStoreRuntime = (store) => {
3761
+ const [runtime] = useState9(() => new ExternalStoreRuntime(store));
3762
+ useInsertionEffect4(() => {
3763
+ runtime.store = store;
3764
+ });
3765
+ useEffect12(() => {
3766
+ runtime.onStoreUpdated();
3767
+ });
3768
+ return runtime;
3769
+ };
3770
+
3555
3771
  // src/ui/thread-config.tsx
3556
3772
  import { createContext as createContext5, useContext as useContext5 } from "react";
3557
3773
  import { Fragment as Fragment3, jsx as jsx29 } from "react/jsx-runtime";
@@ -4252,6 +4468,7 @@ export {
4252
4468
  contentPart_exports as ContentPartPrimitive,
4253
4469
  EdgeChatAdapter,
4254
4470
  edit_composer_default as EditComposer,
4471
+ ExternalStoreRuntime,
4255
4472
  internal_exports as INTERNAL,
4256
4473
  message_exports as MessagePrimitive,
4257
4474
  thread_default as Thread,
@@ -4264,6 +4481,7 @@ export {
4264
4481
  fromCoreMessages,
4265
4482
  fromLanguageModelMessages,
4266
4483
  fromLanguageModelTools,
4484
+ getExternalStoreMessage,
4267
4485
  makeAssistantTool,
4268
4486
  makeAssistantToolUI,
4269
4487
  toCoreMessage,
@@ -4291,6 +4509,7 @@ export {
4291
4509
  useContentPartImage,
4292
4510
  useContentPartText,
4293
4511
  useEdgeRuntime,
4512
+ useExternalStoreRuntime,
4294
4513
  useLocalRuntime,
4295
4514
  useMessageContext,
4296
4515
  useMessageIf,