@assistant-ui/eve 0.0.7 → 0.0.9
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/convertEveMessages.d.ts +32 -3
- package/dist/convertEveMessages.d.ts.map +1 -1
- package/dist/convertEveMessages.js +75 -4
- package/dist/convertEveMessages.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/useEveAgentRuntime.d.ts.map +1 -1
- package/dist/useEveAgentRuntime.js +63 -16
- package/dist/useEveAgentRuntime.js.map +1 -1
- package/package.json +14 -10
- package/src/convertEveMessages.test.ts +1041 -5
- package/src/convertEveMessages.ts +155 -6
- package/src/index.ts +5 -1
- package/src/useEveAgentRuntime.test.tsx +622 -0
- package/src/useEveAgentRuntime.ts +90 -24
- package/LICENSE +0 -21
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { useMemo, useRef, useState } from "react";
|
|
3
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
4
4
|
import {
|
|
5
5
|
fromThreadMessageLike,
|
|
6
6
|
generateId,
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
type EveMessageData,
|
|
25
25
|
type UseEveAgentOptions,
|
|
26
26
|
} from "eve/react";
|
|
27
|
+
import type { SendTurnPayload } from "eve/client";
|
|
27
28
|
import {
|
|
28
29
|
convertEveMessages,
|
|
29
30
|
getEveMessageContent,
|
|
@@ -35,15 +36,27 @@ const USER_STAGED_STATUS = {
|
|
|
35
36
|
reason: "unknown",
|
|
36
37
|
} as const;
|
|
37
38
|
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
39
|
+
const hasRunConfig = (
|
|
40
|
+
runConfig: AppendMessage["runConfig"],
|
|
41
|
+
): runConfig is NonNullable<AppendMessage["runConfig"]> =>
|
|
42
|
+
runConfig?.custom !== undefined && Object.keys(runConfig.custom).length > 0;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Only the `custom` bag crosses the wire. Eve reads `clientContext` as its own
|
|
46
|
+
* namespace and serializes it into a model-visible context message, so sending
|
|
47
|
+
* the assistant-ui envelope would surface a literal `"custom"` key in the
|
|
48
|
+
* prompt and to every eve-side handler.
|
|
49
|
+
*/
|
|
50
|
+
const toEveClientContext = (
|
|
51
|
+
runConfig: AppendMessage["runConfig"],
|
|
52
|
+
): Pick<SendTurnPayload, "clientContext"> =>
|
|
53
|
+
hasRunConfig(runConfig)
|
|
54
|
+
? {
|
|
55
|
+
clientContext: runConfig.custom as NonNullable<
|
|
56
|
+
SendTurnPayload["clientContext"]
|
|
57
|
+
>,
|
|
58
|
+
}
|
|
59
|
+
: {};
|
|
47
60
|
|
|
48
61
|
export type UseEveAgentRuntimeOptions = Omit<
|
|
49
62
|
UseEveAgentOptions<EveMessageData>,
|
|
@@ -117,6 +130,7 @@ export const useEveAgentRuntime = (options: UseEveAgentRuntimeOptions = {}) => {
|
|
|
117
130
|
|
|
118
131
|
return convertEveMessages(agent.data, {
|
|
119
132
|
isRunning,
|
|
133
|
+
error: agent.error,
|
|
120
134
|
getCreatedAt: (message) => {
|
|
121
135
|
const existing = createdAtByMessageId.get(message.id);
|
|
122
136
|
if (existing) return existing;
|
|
@@ -126,12 +140,38 @@ export const useEveAgentRuntime = (options: UseEveAgentRuntimeOptions = {}) => {
|
|
|
126
140
|
return createdAt;
|
|
127
141
|
},
|
|
128
142
|
});
|
|
129
|
-
}, [agent.data, isRunning]);
|
|
143
|
+
}, [agent.data, agent.error, isRunning]);
|
|
130
144
|
|
|
131
145
|
const messages = stagedMessages ?? convertedMessages;
|
|
132
146
|
const messagesRef = useRef(messages);
|
|
133
147
|
messagesRef.current = messages;
|
|
134
148
|
|
|
149
|
+
useEffect(() => {
|
|
150
|
+
if (stagedInputsRef.current.size === 0) return;
|
|
151
|
+
const baseIds = new Set(convertedMessages.map((message) => message.id));
|
|
152
|
+
const remaining = messagesRef.current.filter(
|
|
153
|
+
(message) =>
|
|
154
|
+
stagedInputsRef.current.has(message.id) && !baseIds.has(message.id),
|
|
155
|
+
);
|
|
156
|
+
setStagedMessages(
|
|
157
|
+
remaining.length > 0 ? [...convertedMessages, ...remaining] : null,
|
|
158
|
+
);
|
|
159
|
+
}, [convertedMessages]);
|
|
160
|
+
|
|
161
|
+
const getStagedRun = (parentId: string | null) => {
|
|
162
|
+
if (!parentId || !stagedInputsRef.current.has(parentId)) return null;
|
|
163
|
+
const staged: {
|
|
164
|
+
message: ThreadMessage;
|
|
165
|
+
input: { message: AppendMessage; runConfig: AppendMessage["runConfig"] };
|
|
166
|
+
}[] = [];
|
|
167
|
+
for (const message of messagesRef.current) {
|
|
168
|
+
const input = stagedInputsRef.current.get(message.id);
|
|
169
|
+
if (input) staged.push({ message, input });
|
|
170
|
+
if (message.id === parentId) break;
|
|
171
|
+
}
|
|
172
|
+
return staged;
|
|
173
|
+
};
|
|
174
|
+
|
|
135
175
|
const stageUserMessage = (message: AppendMessage) => {
|
|
136
176
|
const threadMessage = fromThreadMessageLike(
|
|
137
177
|
message,
|
|
@@ -142,10 +182,9 @@ export const useEveAgentRuntime = (options: UseEveAgentRuntimeOptions = {}) => {
|
|
|
142
182
|
message,
|
|
143
183
|
runConfig: message.runConfig,
|
|
144
184
|
});
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
]);
|
|
185
|
+
const nextMessages = [...messagesRef.current, threadMessage];
|
|
186
|
+
messagesRef.current = nextMessages;
|
|
187
|
+
setStagedMessages(nextMessages);
|
|
149
188
|
};
|
|
150
189
|
|
|
151
190
|
return useExternalStoreRuntime({
|
|
@@ -166,19 +205,46 @@ export const useEveAgentRuntime = (options: UseEveAgentRuntimeOptions = {}) => {
|
|
|
166
205
|
stageUserMessage(message);
|
|
167
206
|
return;
|
|
168
207
|
}
|
|
169
|
-
await agent.send({
|
|
208
|
+
await agent.send({
|
|
209
|
+
message: getEveMessageContent(message),
|
|
210
|
+
...toEveClientContext(message.runConfig),
|
|
211
|
+
});
|
|
170
212
|
},
|
|
171
213
|
...(stagedMessages
|
|
172
214
|
? {
|
|
173
|
-
onReload: async (parentId: string | null) => {
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
: null;
|
|
177
|
-
if (!staged)
|
|
215
|
+
onReload: async (parentId: string | null, config) => {
|
|
216
|
+
const stagedRun = getStagedRun(parentId);
|
|
217
|
+
if (!stagedRun)
|
|
178
218
|
throw new Error("Runtime does not support reloading messages.");
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
219
|
+
for (const { message: stagedMessage, input } of stagedRun) {
|
|
220
|
+
const previousMessages = messagesRef.current;
|
|
221
|
+
stagedInputsRef.current.delete(stagedMessage.id);
|
|
222
|
+
const nextMessages = previousMessages.filter(
|
|
223
|
+
(message) => message.id !== stagedMessage.id,
|
|
224
|
+
);
|
|
225
|
+
messagesRef.current = nextMessages;
|
|
226
|
+
setStagedMessages(
|
|
227
|
+
stagedInputsRef.current.size > 0 ? nextMessages : null,
|
|
228
|
+
);
|
|
229
|
+
// The reload config belongs to the message being reloaded; the
|
|
230
|
+
// drafts promoted ahead of it keep the config they were staged
|
|
231
|
+
// with, or reloading the tail would rewrite their context too.
|
|
232
|
+
const runConfig =
|
|
233
|
+
stagedMessage.id === parentId && hasRunConfig(config.runConfig)
|
|
234
|
+
? config.runConfig
|
|
235
|
+
: input.runConfig;
|
|
236
|
+
try {
|
|
237
|
+
await agent.send({
|
|
238
|
+
message: getEveMessageContent(input.message),
|
|
239
|
+
...toEveClientContext(runConfig),
|
|
240
|
+
});
|
|
241
|
+
} catch (error) {
|
|
242
|
+
stagedInputsRef.current.set(stagedMessage.id, input);
|
|
243
|
+
messagesRef.current = previousMessages;
|
|
244
|
+
setStagedMessages(previousMessages);
|
|
245
|
+
throw error;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
182
248
|
},
|
|
183
249
|
}
|
|
184
250
|
: {}),
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 AgentbaseAI Inc.
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|