@assistant-ui/react 0.5.23 → 0.5.25
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/index.d.mts +13 -10
- package/dist/index.d.ts +13 -10
- package/dist/index.js +152 -182
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +113 -143
- package/dist/index.mjs.map +1 -1
- package/dist/styles/index.css +11 -4
- package/dist/styles/index.css.map +1 -1
- package/dist/styles/tailwindcss/base-components.css +1 -1
- package/package.json +7 -7
- package/README.md +0 -34
package/dist/index.mjs
CHANGED
@@ -159,11 +159,23 @@ var makeComposerStore = (useThreadMessages, useThreadActions) => {
|
|
159
159
|
|
160
160
|
// src/context/stores/Thread.ts
|
161
161
|
import { create as create4 } from "zustand";
|
162
|
+
var getThreadStateFromRuntime = (runtime) => {
|
163
|
+
const lastMessage = runtime.messages.at(-1);
|
164
|
+
if (lastMessage?.role !== "assistant")
|
165
|
+
return Object.freeze({
|
166
|
+
isDisabled: runtime.isDisabled,
|
167
|
+
isRunning: false,
|
168
|
+
unstable_canAppendNew: runtime.isDisabled
|
169
|
+
});
|
170
|
+
return Object.freeze({
|
171
|
+
isDisabled: runtime.isDisabled,
|
172
|
+
isRunning: lastMessage.status.type === "running",
|
173
|
+
unstable_canAppendNew: !runtime.isDisabled && lastMessage.status.type !== "running" && lastMessage.status.type !== "requires-action"
|
174
|
+
});
|
175
|
+
};
|
162
176
|
var makeThreadStore = (runtimeRef) => {
|
163
|
-
|
164
|
-
|
165
|
-
isRunning: runtimeRef.getState().isRunning
|
166
|
-
}));
|
177
|
+
const runtime = runtimeRef.getState();
|
178
|
+
return create4(() => getThreadStateFromRuntime(runtime));
|
167
179
|
};
|
168
180
|
|
169
181
|
// src/context/stores/ThreadViewport.tsx
|
@@ -260,13 +272,11 @@ var ThreadProvider = ({
|
|
260
272
|
useCallback2(
|
261
273
|
(thread) => {
|
262
274
|
const onThreadUpdate = () => {
|
263
|
-
const
|
264
|
-
|
275
|
+
const oldState = context.useThread.getState();
|
276
|
+
const state = getThreadStateFromRuntime(thread);
|
277
|
+
if (oldState.isDisabled !== state.isDisabled || oldState.isRunning !== state.isRunning || oldState.unstable_canAppendNew !== state.unstable_canAppendNew) {
|
265
278
|
context.useThread.setState(
|
266
|
-
|
267
|
-
isRunning: thread.isRunning,
|
268
|
-
isDisabled: thread.isDisabled
|
269
|
-
}),
|
279
|
+
getThreadStateFromRuntime(thread),
|
270
280
|
true
|
271
281
|
);
|
272
282
|
}
|
@@ -520,8 +530,8 @@ var useCombinedStore = (stores, selector) => {
|
|
520
530
|
return useCombined(selector);
|
521
531
|
};
|
522
532
|
|
523
|
-
// src/utils/
|
524
|
-
var
|
533
|
+
// src/utils/getThreadMessageText.tsx
|
534
|
+
var getThreadMessageText = (message) => {
|
525
535
|
const textParts = message.content.filter(
|
526
536
|
(part) => part.type === "text"
|
527
537
|
);
|
@@ -543,7 +553,7 @@ var useActionBarCopy = ({
|
|
543
553
|
const { message } = useMessage.getState();
|
544
554
|
const { setIsCopied } = useMessageUtils.getState();
|
545
555
|
const { isEditing, value: composerValue } = useEditComposer.getState();
|
546
|
-
const valueToCopy = isEditing ? composerValue :
|
556
|
+
const valueToCopy = isEditing ? composerValue : getThreadMessageText(message);
|
547
557
|
navigator.clipboard.writeText(valueToCopy).then(() => {
|
548
558
|
setIsCopied(true);
|
549
559
|
setTimeout(() => setIsCopied(false), copiedDuration);
|
@@ -670,7 +680,7 @@ var useComposerSend = () => {
|
|
670
680
|
const { useComposer } = useComposerContext();
|
671
681
|
const disabled = useCombinedStore(
|
672
682
|
[useThread, useComposer],
|
673
|
-
(t, c) => t.
|
683
|
+
(t, c) => !t.unstable_canAppendNew || !c.isEditing || c.value.length === 0
|
674
684
|
);
|
675
685
|
const callback = useCallback11(() => {
|
676
686
|
const composerState = useComposer.getState();
|
@@ -1568,8 +1578,8 @@ var ComposerPrimitiveInput = forwardRef12(
|
|
1568
1578
|
const handleKeyPress = (e) => {
|
1569
1579
|
if (isDisabled) return;
|
1570
1580
|
if (e.key === "Enter" && e.shiftKey === false) {
|
1571
|
-
const
|
1572
|
-
if (
|
1581
|
+
const { unstable_canAppendNew } = useThread.getState();
|
1582
|
+
if (unstable_canAppendNew) {
|
1573
1583
|
e.preventDefault();
|
1574
1584
|
textareaRef.current?.closest("form")?.requestSubmit();
|
1575
1585
|
}
|
@@ -1902,7 +1912,7 @@ var useMessageContext2 = (messageIndex) => {
|
|
1902
1912
|
throw new Error(
|
1903
1913
|
"Tried to edit a non-user message. Editing is only supported for user messages. This is likely an internal bug in assistant-ui."
|
1904
1914
|
);
|
1905
|
-
const text =
|
1915
|
+
const text = getThreadMessageText(message);
|
1906
1916
|
return text;
|
1907
1917
|
},
|
1908
1918
|
onSend: (text) => {
|
@@ -2144,6 +2154,13 @@ var MessageRepository = class {
|
|
2144
2154
|
}
|
2145
2155
|
}
|
2146
2156
|
if (operation !== "cut") {
|
2157
|
+
for (let current = newParent; current; current = current.prev) {
|
2158
|
+
if (current.current.id === child.current.id) {
|
2159
|
+
throw new Error(
|
2160
|
+
"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."
|
2161
|
+
);
|
2162
|
+
}
|
2163
|
+
}
|
2147
2164
|
newParentOrRoot.children = [
|
2148
2165
|
...newParentOrRoot.children,
|
2149
2166
|
child.current.id
|
@@ -2702,9 +2719,6 @@ var LocalThreadRuntime = class {
|
|
2702
2719
|
get messages() {
|
2703
2720
|
return this.repository.getMessages();
|
2704
2721
|
}
|
2705
|
-
get isRunning() {
|
2706
|
-
return this.abortController != null;
|
2707
|
-
}
|
2708
2722
|
getBranches(messageId) {
|
2709
2723
|
return this.repository.getBranches(messageId);
|
2710
2724
|
}
|
@@ -2793,8 +2807,6 @@ var LocalThreadRuntime = class {
|
|
2793
2807
|
updateMessage({
|
2794
2808
|
status: { type: "complete", reason: "unknown" }
|
2795
2809
|
});
|
2796
|
-
} else {
|
2797
|
-
this.notifySubscribers();
|
2798
2810
|
}
|
2799
2811
|
} catch (e) {
|
2800
2812
|
this.abortController = null;
|
@@ -2893,18 +2905,12 @@ var useLocalRuntime = (adapter, options) => {
|
|
2893
2905
|
return runtime;
|
2894
2906
|
};
|
2895
2907
|
|
2896
|
-
// src/runtimes/external-store/ExternalStoreThreadRuntime.tsx
|
2897
|
-
import { create as create15 } from "zustand";
|
2898
|
-
|
2899
2908
|
// src/runtimes/external-store/getExternalStoreMessage.tsx
|
2900
2909
|
var symbolInnerMessage = Symbol("innerMessage");
|
2901
2910
|
var getExternalStoreMessage = (message) => {
|
2902
2911
|
return message[symbolInnerMessage];
|
2903
2912
|
};
|
2904
2913
|
|
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
2914
|
// src/runtimes/external-store/ThreadMessageConverter.ts
|
2909
2915
|
var ThreadMessageConverter = class {
|
2910
2916
|
cache = /* @__PURE__ */ new WeakMap();
|
@@ -2925,6 +2931,7 @@ var AUTO_STATUS_COMPLETE = Object.freeze({
|
|
2925
2931
|
type: "complete",
|
2926
2932
|
reason: "unknown"
|
2927
2933
|
});
|
2934
|
+
var isAutoStatus = (status) => status === AUTO_STATUS_RUNNING || status === AUTO_STATUS_COMPLETE;
|
2928
2935
|
var getAutoStatus = (isLast, isRunning) => isLast && isRunning ? AUTO_STATUS_RUNNING : AUTO_STATUS_COMPLETE;
|
2929
2936
|
|
2930
2937
|
// src/runtimes/external-store/ThreadMessageLike.tsx
|
@@ -2995,106 +3002,112 @@ var fromThreadMessageLike = (like, fallbackId, fallbackStatus) => {
|
|
2995
3002
|
}
|
2996
3003
|
};
|
2997
3004
|
|
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
3005
|
// src/runtimes/external-store/ExternalStoreThreadRuntime.tsx
|
3040
3006
|
var hasUpcomingMessage = (isRunning, messages) => {
|
3041
3007
|
return isRunning && messages[messages.length - 1]?.role !== "assistant";
|
3042
3008
|
};
|
3043
3009
|
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
3010
|
_subscriptions = /* @__PURE__ */ new Set();
|
3056
3011
|
repository = new MessageRepository();
|
3057
3012
|
assistantOptimisticId = null;
|
3058
|
-
useStore;
|
3059
3013
|
get capabilities() {
|
3060
3014
|
return {
|
3061
|
-
switchToBranch: this.
|
3062
|
-
edit: this.
|
3063
|
-
reload: this.
|
3064
|
-
cancel: this.
|
3065
|
-
copy: this.
|
3015
|
+
switchToBranch: this._store.setMessages !== void 0,
|
3016
|
+
edit: this._store.onEdit !== void 0,
|
3017
|
+
reload: this._store.onReload !== void 0,
|
3018
|
+
cancel: this._store.onCancel !== void 0,
|
3019
|
+
copy: this._store.onCopy !== null
|
3066
3020
|
};
|
3067
3021
|
}
|
3068
3022
|
messages = [];
|
3069
3023
|
isDisabled = false;
|
3070
|
-
|
3024
|
+
converter = new ThreadMessageConverter();
|
3025
|
+
_store;
|
3026
|
+
constructor(store) {
|
3027
|
+
this.store = store;
|
3028
|
+
}
|
3029
|
+
set store(store) {
|
3030
|
+
const oldStore = this._store;
|
3031
|
+
if (oldStore) {
|
3032
|
+
if (oldStore.convertMessage !== store.convertMessage) {
|
3033
|
+
this.converter = new ThreadMessageConverter();
|
3034
|
+
} else if (oldStore.isDisabled === store.isDisabled && oldStore.isRunning === store.isRunning && oldStore.messages === store.messages) {
|
3035
|
+
return;
|
3036
|
+
}
|
3037
|
+
}
|
3038
|
+
this._store = store;
|
3039
|
+
const isRunning = store.isRunning ?? false;
|
3040
|
+
const isDisabled = store.isDisabled ?? false;
|
3041
|
+
const convertCallback = (cache, m, idx) => {
|
3042
|
+
if (!store.convertMessage) return m;
|
3043
|
+
const isLast = idx === store.messages.length - 1;
|
3044
|
+
const autoStatus = getAutoStatus(isLast, isRunning);
|
3045
|
+
if (cache && (cache.role !== "assistant" || !isAutoStatus(cache.status) || cache.status === autoStatus))
|
3046
|
+
return cache;
|
3047
|
+
const newMessage = fromThreadMessageLike(
|
3048
|
+
store.convertMessage(m, idx),
|
3049
|
+
idx.toString(),
|
3050
|
+
autoStatus
|
3051
|
+
);
|
3052
|
+
newMessage[symbolInnerMessage] = m;
|
3053
|
+
return newMessage;
|
3054
|
+
};
|
3055
|
+
const messages = this.converter.convertMessages(
|
3056
|
+
store.messages,
|
3057
|
+
convertCallback
|
3058
|
+
);
|
3059
|
+
for (let i = 0; i < messages.length; i++) {
|
3060
|
+
const message = messages[i];
|
3061
|
+
const parent = messages[i - 1];
|
3062
|
+
this.repository.addOrUpdateMessage(parent?.id ?? null, message);
|
3063
|
+
}
|
3064
|
+
if (this.assistantOptimisticId) {
|
3065
|
+
this.repository.deleteMessage(this.assistantOptimisticId);
|
3066
|
+
this.assistantOptimisticId = null;
|
3067
|
+
}
|
3068
|
+
if (hasUpcomingMessage(isRunning, messages)) {
|
3069
|
+
this.assistantOptimisticId = this.repository.appendOptimisticMessage(
|
3070
|
+
messages.at(-1)?.id ?? null,
|
3071
|
+
{
|
3072
|
+
role: "assistant",
|
3073
|
+
content: []
|
3074
|
+
}
|
3075
|
+
);
|
3076
|
+
}
|
3077
|
+
this.repository.resetHead(
|
3078
|
+
this.assistantOptimisticId ?? messages.at(-1)?.id ?? null
|
3079
|
+
);
|
3080
|
+
this.messages = this.repository.getMessages();
|
3081
|
+
this.isDisabled = isDisabled;
|
3082
|
+
for (const callback of this._subscriptions) callback();
|
3083
|
+
}
|
3071
3084
|
getBranches(messageId) {
|
3072
3085
|
return this.repository.getBranches(messageId);
|
3073
3086
|
}
|
3074
3087
|
switchToBranch(branchId) {
|
3075
|
-
if (!this.
|
3088
|
+
if (!this._store.setMessages)
|
3076
3089
|
throw new Error("Runtime does not support switching branches.");
|
3077
3090
|
this.repository.switchToBranch(branchId);
|
3078
3091
|
this.updateMessages(this.repository.getMessages());
|
3079
3092
|
}
|
3080
3093
|
async append(message) {
|
3081
3094
|
if (message.parentId !== (this.messages.at(-1)?.id ?? null)) {
|
3082
|
-
if (!this.
|
3095
|
+
if (!this._store.onEdit)
|
3083
3096
|
throw new Error("Runtime does not support editing messages.");
|
3084
|
-
await this.
|
3097
|
+
await this._store.onEdit(message);
|
3085
3098
|
} else {
|
3086
|
-
await this.
|
3099
|
+
await this._store.onNew(message);
|
3087
3100
|
}
|
3088
3101
|
}
|
3089
3102
|
async startRun(parentId) {
|
3090
|
-
if (!this.
|
3103
|
+
if (!this._store.onReload)
|
3091
3104
|
throw new Error("Runtime does not support reloading messages.");
|
3092
|
-
await this.
|
3105
|
+
await this._store.onReload(parentId);
|
3093
3106
|
}
|
3094
3107
|
cancelRun() {
|
3095
|
-
if (!this.
|
3108
|
+
if (!this._store.onCancel)
|
3096
3109
|
throw new Error("Runtime does not support cancelling runs.");
|
3097
|
-
this.
|
3110
|
+
this._store.onCancel();
|
3098
3111
|
if (this.assistantOptimisticId) {
|
3099
3112
|
this.repository.deleteMessage(this.assistantOptimisticId);
|
3100
3113
|
this.assistantOptimisticId = null;
|
@@ -3109,51 +3122,14 @@ var ExternalStoreThreadRuntime = class {
|
|
3109
3122
|
return () => this._subscriptions.delete(callback);
|
3110
3123
|
}
|
3111
3124
|
updateMessages = (messages) => {
|
3112
|
-
this.
|
3125
|
+
this._store.setMessages?.(
|
3113
3126
|
messages.flatMap(getExternalStoreMessage).filter((m) => m != null)
|
3114
3127
|
);
|
3115
3128
|
};
|
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
3129
|
addToolResult(options) {
|
3154
|
-
if (!this.
|
3130
|
+
if (!this._store.onAddToolResult)
|
3155
3131
|
throw new Error("Runtime does not support tool results.");
|
3156
|
-
this.
|
3132
|
+
this._store.onAddToolResult(options);
|
3157
3133
|
}
|
3158
3134
|
};
|
3159
3135
|
|
@@ -3166,9 +3142,6 @@ var ExternalStoreRuntime = class extends BaseAssistantRuntime {
|
|
3166
3142
|
set store(store) {
|
3167
3143
|
this.thread.store = store;
|
3168
3144
|
}
|
3169
|
-
onStoreUpdated() {
|
3170
|
-
return this.thread.onStoreUpdated();
|
3171
|
-
}
|
3172
3145
|
getModelConfig() {
|
3173
3146
|
return this._proxyConfigProvider.getModelConfig();
|
3174
3147
|
}
|
@@ -3189,15 +3162,12 @@ var ExternalStoreRuntime = class extends BaseAssistantRuntime {
|
|
3189
3162
|
};
|
3190
3163
|
|
3191
3164
|
// src/runtimes/external-store/useExternalStoreRuntime.tsx
|
3192
|
-
import {
|
3165
|
+
import { useInsertionEffect as useInsertionEffect4, useState as useState10 } from "react";
|
3193
3166
|
var useExternalStoreRuntime = (store) => {
|
3194
3167
|
const [runtime] = useState10(() => new ExternalStoreRuntime(store));
|
3195
|
-
|
3168
|
+
useInsertionEffect4(() => {
|
3196
3169
|
runtime.store = store;
|
3197
3170
|
});
|
3198
|
-
useEffect12(() => {
|
3199
|
-
runtime.onStoreUpdated();
|
3200
|
-
});
|
3201
3171
|
return runtime;
|
3202
3172
|
};
|
3203
3173
|
|