@assistant-ui/react 0.5.23 → 0.5.24

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.mjs CHANGED
@@ -2144,6 +2144,13 @@ var MessageRepository = class {
2144
2144
  }
2145
2145
  }
2146
2146
  if (operation !== "cut") {
2147
+ for (let current = newParent; current; current = current.prev) {
2148
+ if (current.current.id === child.current.id) {
2149
+ throw new Error(
2150
+ "MessageRepository(performOp/link): A message with the same id already exists in the parent tree. This error occurs if the same message id is found multiple times. This is likely an internal bug in assistant-ui."
2151
+ );
2152
+ }
2153
+ }
2147
2154
  newParentOrRoot.children = [
2148
2155
  ...newParentOrRoot.children,
2149
2156
  child.current.id
@@ -2893,18 +2900,12 @@ var useLocalRuntime = (adapter, options) => {
2893
2900
  return runtime;
2894
2901
  };
2895
2902
 
2896
- // src/runtimes/external-store/ExternalStoreThreadRuntime.tsx
2897
- import { create as create15 } from "zustand";
2898
-
2899
2903
  // src/runtimes/external-store/getExternalStoreMessage.tsx
2900
2904
  var symbolInnerMessage = Symbol("innerMessage");
2901
2905
  var getExternalStoreMessage = (message) => {
2902
2906
  return message[symbolInnerMessage];
2903
2907
  };
2904
2908
 
2905
- // src/runtimes/external-store/useExternalStoreSync.tsx
2906
- import { useEffect as useEffect11, useInsertionEffect as useInsertionEffect4, useMemo as useMemo4, useRef as useRef6 } from "react";
2907
-
2908
2909
  // src/runtimes/external-store/ThreadMessageConverter.ts
2909
2910
  var ThreadMessageConverter = class {
2910
2911
  cache = /* @__PURE__ */ new WeakMap();
@@ -2925,6 +2926,7 @@ var AUTO_STATUS_COMPLETE = Object.freeze({
2925
2926
  type: "complete",
2926
2927
  reason: "unknown"
2927
2928
  });
2929
+ var isAutoStatus = (status) => status === AUTO_STATUS_RUNNING || status === AUTO_STATUS_COMPLETE;
2928
2930
  var getAutoStatus = (isLast, isRunning) => isLast && isRunning ? AUTO_STATUS_RUNNING : AUTO_STATUS_COMPLETE;
2929
2931
 
2930
2932
  // src/runtimes/external-store/ThreadMessageLike.tsx
@@ -2995,106 +2997,114 @@ var fromThreadMessageLike = (like, fallbackId, fallbackStatus) => {
2995
2997
  }
2996
2998
  };
2997
2999
 
2998
- // src/runtimes/external-store/useExternalStoreSync.tsx
2999
- var useExternalStoreSync = (adapter, updateData) => {
3000
- const adapterRef = useRef6(adapter);
3001
- useInsertionEffect4(() => {
3002
- adapterRef.current = adapter;
3003
- });
3004
- const [converter, convertCallback] = useMemo4(() => {
3005
- const converter2 = adapter.convertMessage ?? ((m) => m);
3006
- const convertCallback2 = (cache, m, idx) => {
3007
- const autoStatus = getAutoStatus(
3008
- adapterRef.current.messages.at(-1) === m,
3009
- adapterRef.current.isRunning ?? false
3010
- );
3011
- if (cache && (cache.role !== "assistant" || cache.status === autoStatus))
3012
- return cache;
3013
- const newMessage = fromThreadMessageLike(
3014
- converter2(m, idx),
3015
- idx.toString(),
3016
- autoStatus
3017
- );
3018
- newMessage[symbolInnerMessage] = m;
3019
- return newMessage;
3020
- };
3021
- return [new ThreadMessageConverter(), convertCallback2];
3022
- }, [adapter.convertMessage]);
3023
- useEffect11(() => {
3024
- updateData(
3025
- adapter.isDisabled ?? false,
3026
- adapter.isRunning ?? false,
3027
- converter.convertMessages(adapter.messages, convertCallback)
3028
- );
3029
- }, [
3030
- updateData,
3031
- converter,
3032
- convertCallback,
3033
- adapter.isDisabled,
3034
- adapter.isRunning,
3035
- adapter.messages
3036
- ]);
3037
- };
3038
-
3039
3000
  // src/runtimes/external-store/ExternalStoreThreadRuntime.tsx
3040
3001
  var hasUpcomingMessage = (isRunning, messages) => {
3041
3002
  return isRunning && messages[messages.length - 1]?.role !== "assistant";
3042
3003
  };
3043
3004
  var ExternalStoreThreadRuntime = class {
3044
- constructor(store) {
3045
- this.store = store;
3046
- this.updateData(
3047
- store.isDisabled ?? false,
3048
- store.isRunning ?? false,
3049
- store.messages
3050
- );
3051
- this.useStore = create15(() => ({
3052
- store
3053
- }));
3054
- }
3055
3005
  _subscriptions = /* @__PURE__ */ new Set();
3056
3006
  repository = new MessageRepository();
3057
3007
  assistantOptimisticId = null;
3058
- useStore;
3059
3008
  get capabilities() {
3060
3009
  return {
3061
- switchToBranch: this.store.setMessages !== void 0,
3062
- edit: this.store.onEdit !== void 0,
3063
- reload: this.store.onReload !== void 0,
3064
- cancel: this.store.onCancel !== void 0,
3065
- copy: this.store.onCopy !== null
3010
+ switchToBranch: this._store.setMessages !== void 0,
3011
+ edit: this._store.onEdit !== void 0,
3012
+ reload: this._store.onReload !== void 0,
3013
+ cancel: this._store.onCancel !== void 0,
3014
+ copy: this._store.onCopy !== null
3066
3015
  };
3067
3016
  }
3068
3017
  messages = [];
3069
3018
  isDisabled = false;
3070
3019
  isRunning = false;
3020
+ converter = new ThreadMessageConverter();
3021
+ _store;
3022
+ constructor(store) {
3023
+ this.store = store;
3024
+ }
3025
+ set store(store) {
3026
+ const oldStore = this._store;
3027
+ if (oldStore) {
3028
+ if (oldStore.convertMessage !== store.convertMessage) {
3029
+ this.converter = new ThreadMessageConverter();
3030
+ } else if (oldStore.isDisabled === store.isDisabled && oldStore.isRunning === store.isRunning && oldStore.messages === store.messages) {
3031
+ return;
3032
+ }
3033
+ }
3034
+ this._store = store;
3035
+ const isRunning = store.isRunning ?? false;
3036
+ const isDisabled = store.isDisabled ?? false;
3037
+ const convertCallback = (cache, m, idx) => {
3038
+ if (!store.convertMessage) return m;
3039
+ const isLast = idx === store.messages.length - 1;
3040
+ const autoStatus = getAutoStatus(isLast, isRunning);
3041
+ if (cache && (cache.role !== "assistant" || !isAutoStatus(cache.status) || cache.status === autoStatus))
3042
+ return cache;
3043
+ const newMessage = fromThreadMessageLike(
3044
+ store.convertMessage(m, idx),
3045
+ idx.toString(),
3046
+ autoStatus
3047
+ );
3048
+ newMessage[symbolInnerMessage] = m;
3049
+ return newMessage;
3050
+ };
3051
+ const messages = this.converter.convertMessages(
3052
+ store.messages,
3053
+ convertCallback
3054
+ );
3055
+ for (let i = 0; i < messages.length; i++) {
3056
+ const message = messages[i];
3057
+ const parent = messages[i - 1];
3058
+ this.repository.addOrUpdateMessage(parent?.id ?? null, message);
3059
+ }
3060
+ if (this.assistantOptimisticId) {
3061
+ this.repository.deleteMessage(this.assistantOptimisticId);
3062
+ this.assistantOptimisticId = null;
3063
+ }
3064
+ if (hasUpcomingMessage(isRunning, messages)) {
3065
+ this.assistantOptimisticId = this.repository.appendOptimisticMessage(
3066
+ messages.at(-1)?.id ?? null,
3067
+ {
3068
+ role: "assistant",
3069
+ content: []
3070
+ }
3071
+ );
3072
+ }
3073
+ this.repository.resetHead(
3074
+ this.assistantOptimisticId ?? messages.at(-1)?.id ?? null
3075
+ );
3076
+ this.messages = this.repository.getMessages();
3077
+ this.isDisabled = isDisabled;
3078
+ this.isRunning = isRunning;
3079
+ for (const callback of this._subscriptions) callback();
3080
+ }
3071
3081
  getBranches(messageId) {
3072
3082
  return this.repository.getBranches(messageId);
3073
3083
  }
3074
3084
  switchToBranch(branchId) {
3075
- if (!this.store.setMessages)
3085
+ if (!this._store.setMessages)
3076
3086
  throw new Error("Runtime does not support switching branches.");
3077
3087
  this.repository.switchToBranch(branchId);
3078
3088
  this.updateMessages(this.repository.getMessages());
3079
3089
  }
3080
3090
  async append(message) {
3081
3091
  if (message.parentId !== (this.messages.at(-1)?.id ?? null)) {
3082
- if (!this.store.onEdit)
3092
+ if (!this._store.onEdit)
3083
3093
  throw new Error("Runtime does not support editing messages.");
3084
- await this.store.onEdit(message);
3094
+ await this._store.onEdit(message);
3085
3095
  } else {
3086
- await this.store.onNew(message);
3096
+ await this._store.onNew(message);
3087
3097
  }
3088
3098
  }
3089
3099
  async startRun(parentId) {
3090
- if (!this.store.onReload)
3100
+ if (!this._store.onReload)
3091
3101
  throw new Error("Runtime does not support reloading messages.");
3092
- await this.store.onReload(parentId);
3102
+ await this._store.onReload(parentId);
3093
3103
  }
3094
3104
  cancelRun() {
3095
- if (!this.store.onCancel)
3105
+ if (!this._store.onCancel)
3096
3106
  throw new Error("Runtime does not support cancelling runs.");
3097
- this.store.onCancel();
3107
+ this._store.onCancel();
3098
3108
  if (this.assistantOptimisticId) {
3099
3109
  this.repository.deleteMessage(this.assistantOptimisticId);
3100
3110
  this.assistantOptimisticId = null;
@@ -3109,51 +3119,14 @@ var ExternalStoreThreadRuntime = class {
3109
3119
  return () => this._subscriptions.delete(callback);
3110
3120
  }
3111
3121
  updateMessages = (messages) => {
3112
- this.store.setMessages?.(
3122
+ this._store.setMessages?.(
3113
3123
  messages.flatMap(getExternalStoreMessage).filter((m) => m != null)
3114
3124
  );
3115
3125
  };
3116
- onStoreUpdated() {
3117
- if (this.useStore.getState().store !== this.store) {
3118
- this.useStore.setState({ store: this.store });
3119
- }
3120
- }
3121
- updateData = (isDisabled, isRunning, vm) => {
3122
- for (let i = 0; i < vm.length; i++) {
3123
- const message = vm[i];
3124
- const parent = vm[i - 1];
3125
- this.repository.addOrUpdateMessage(parent?.id ?? null, message);
3126
- }
3127
- if (this.assistantOptimisticId) {
3128
- this.repository.deleteMessage(this.assistantOptimisticId);
3129
- this.assistantOptimisticId = null;
3130
- }
3131
- if (hasUpcomingMessage(isRunning, vm)) {
3132
- this.assistantOptimisticId = this.repository.appendOptimisticMessage(
3133
- vm.at(-1)?.id ?? null,
3134
- {
3135
- role: "assistant",
3136
- content: []
3137
- }
3138
- );
3139
- }
3140
- this.repository.resetHead(
3141
- this.assistantOptimisticId ?? vm.at(-1)?.id ?? null
3142
- );
3143
- this.messages = this.repository.getMessages();
3144
- this.isDisabled = isDisabled;
3145
- this.isRunning = isRunning;
3146
- for (const callback of this._subscriptions) callback();
3147
- };
3148
- unstable_synchronizer = () => {
3149
- const { store } = this.useStore();
3150
- useExternalStoreSync(store, this.updateData);
3151
- return null;
3152
- };
3153
3126
  addToolResult(options) {
3154
- if (!this.store.onAddToolResult)
3127
+ if (!this._store.onAddToolResult)
3155
3128
  throw new Error("Runtime does not support tool results.");
3156
- this.store.onAddToolResult(options);
3129
+ this._store.onAddToolResult(options);
3157
3130
  }
3158
3131
  };
3159
3132
 
@@ -3166,9 +3139,6 @@ var ExternalStoreRuntime = class extends BaseAssistantRuntime {
3166
3139
  set store(store) {
3167
3140
  this.thread.store = store;
3168
3141
  }
3169
- onStoreUpdated() {
3170
- return this.thread.onStoreUpdated();
3171
- }
3172
3142
  getModelConfig() {
3173
3143
  return this._proxyConfigProvider.getModelConfig();
3174
3144
  }
@@ -3189,15 +3159,12 @@ var ExternalStoreRuntime = class extends BaseAssistantRuntime {
3189
3159
  };
3190
3160
 
3191
3161
  // src/runtimes/external-store/useExternalStoreRuntime.tsx
3192
- import { useEffect as useEffect12, useInsertionEffect as useInsertionEffect5, useState as useState10 } from "react";
3162
+ import { useInsertionEffect as useInsertionEffect4, useState as useState10 } from "react";
3193
3163
  var useExternalStoreRuntime = (store) => {
3194
3164
  const [runtime] = useState10(() => new ExternalStoreRuntime(store));
3195
- useInsertionEffect5(() => {
3165
+ useInsertionEffect4(() => {
3196
3166
  runtime.store = store;
3197
3167
  });
3198
- useEffect12(() => {
3199
- runtime.onStoreUpdated();
3200
- });
3201
3168
  return runtime;
3202
3169
  };
3203
3170