@letta-ai/letta-react 0.0.5 → 0.0.7
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.
@@ -35,6 +35,25 @@ function extendContent(content, nextContent) {
|
|
35
35
|
}
|
36
36
|
}
|
37
37
|
}
|
38
|
+
function dedupeMessages(messages) {
|
39
|
+
const messageIndex = new Set(messages.map((message) => `${message.id}${message.messageType}`));
|
40
|
+
return messages.filter((message) => {
|
41
|
+
// if we have seen this message before, return false
|
42
|
+
if (messageIndex.has(`${message.id}${message.messageType}`)) {
|
43
|
+
messageIndex.delete(`${message.id}${message.messageType}`);
|
44
|
+
return true;
|
45
|
+
}
|
46
|
+
return false;
|
47
|
+
}, []);
|
48
|
+
}
|
49
|
+
function messageCreateToMessageUnion(messages) {
|
50
|
+
return messages.map((message, idx) => ({
|
51
|
+
messageType: message.role === 'user' ? 'user_message' : 'system_message',
|
52
|
+
content: message.content,
|
53
|
+
date: new Date(),
|
54
|
+
id: `autogenerated_${Date.now()}_${idx}`,
|
55
|
+
}));
|
56
|
+
}
|
38
57
|
export function useAgentMessages(options) {
|
39
58
|
const { client = {}, method = 'stream', messageOptions = {}, limit = 20, agentId, } = options;
|
40
59
|
const localClient = useLettaClient(client);
|
@@ -49,26 +68,39 @@ export function useAgentMessages(options) {
|
|
49
68
|
const [sendingError, setSendingError] = useState(null);
|
50
69
|
const sendNonStreamedMessage = useCallback(function sendNonStreamedMessage(sendMessagePayload) {
|
51
70
|
return __awaiter(this, void 0, void 0, function* () {
|
71
|
+
let originalMessageState = localMessages;
|
52
72
|
try {
|
53
73
|
setIsSending(true);
|
54
74
|
setSendingError(null);
|
75
|
+
const newMessages = messageCreateToMessageUnion(sendMessagePayload.messages);
|
76
|
+
setLocalMessages((prevState) => {
|
77
|
+
originalMessageState = prevState;
|
78
|
+
return Object.assign(Object.assign({}, prevState), { messages: [...prevState.messages, ...newMessages] });
|
79
|
+
});
|
55
80
|
const response = yield localClient.agents.messages.create(agentId, Object.assign(Object.assign({}, sendMessagePayload), messageOptions));
|
56
|
-
setLocalMessages((prevState) => (Object.assign(Object.assign({}, prevState), { messages: [...
|
81
|
+
setLocalMessages((prevState) => (Object.assign(Object.assign({}, prevState), { messages: [...prevState.messages, ...response.messages] })));
|
57
82
|
}
|
58
83
|
catch (e) {
|
84
|
+
setLocalMessages(originalMessageState);
|
59
85
|
setSendingError(e);
|
60
86
|
}
|
61
87
|
finally {
|
62
88
|
setIsSending(false);
|
63
89
|
}
|
64
90
|
});
|
65
|
-
}, [localClient]);
|
91
|
+
}, [localClient, localMessages]);
|
66
92
|
const sendStreamedMessage = useCallback(function sendStreamedMessage(sendMessagePayload) {
|
67
93
|
return __awaiter(this, void 0, void 0, function* () {
|
68
94
|
var _a, e_1, _b, _c;
|
95
|
+
let originalMessageState = localMessages;
|
69
96
|
try {
|
70
97
|
setIsSending(true);
|
71
98
|
setSendingError(null);
|
99
|
+
const newMessages = messageCreateToMessageUnion(sendMessagePayload.messages);
|
100
|
+
setLocalMessages((prevState) => {
|
101
|
+
originalMessageState = prevState;
|
102
|
+
return Object.assign(Object.assign({}, prevState), { messages: [...prevState.messages, ...newMessages] });
|
103
|
+
});
|
72
104
|
const response = yield localClient.agents.messages.createStream(agentId, Object.assign(Object.assign(Object.assign({}, sendMessagePayload), messageOptions), { streamTokens: true }));
|
73
105
|
try {
|
74
106
|
for (var _d = true, response_1 = __asyncValues(response), response_1_1; response_1_1 = yield response_1.next(), _a = response_1_1.done, !_a; _d = true) {
|
@@ -156,13 +188,17 @@ export function useAgentMessages(options) {
|
|
156
188
|
});
|
157
189
|
}, [localClient]);
|
158
190
|
const sendMessage = useCallback(function sendMessage(payload) {
|
191
|
+
const filteredPayload = Object.assign(Object.assign({}, payload), { messages: payload.messages.filter((e) => !!e.content) });
|
192
|
+
if (filteredPayload.messages.length === 0) {
|
193
|
+
return;
|
194
|
+
}
|
159
195
|
if (isSending) {
|
160
196
|
return;
|
161
197
|
}
|
162
198
|
if (method === 'stream') {
|
163
|
-
return sendStreamedMessage(
|
199
|
+
return sendStreamedMessage(filteredPayload);
|
164
200
|
}
|
165
|
-
return sendNonStreamedMessage(
|
201
|
+
return sendNonStreamedMessage(filteredPayload);
|
166
202
|
}, [method, isSending, sendStreamedMessage, sendNonStreamedMessage]);
|
167
203
|
const getMessages = useCallback(function getMessages(before) {
|
168
204
|
return __awaiter(this, void 0, void 0, function* () {
|
@@ -175,7 +211,7 @@ export function useAgentMessages(options) {
|
|
175
211
|
const messages = yield localClient.agents.messages.list(agentId, Object.assign({ before, limit: limit + 1 }, messageOptions));
|
176
212
|
const messagesToAdd = messages.slice(1, messages.length);
|
177
213
|
const nextCursor = messages.length > limit ? messages[0] : undefined;
|
178
|
-
setLocalMessages((prevState) => (Object.assign(Object.assign({}, prevState), { messages: [...messagesToAdd, ...prevState.messages], nextCursor: nextCursor === null || nextCursor === void 0 ? void 0 : nextCursor.id })));
|
214
|
+
setLocalMessages((prevState) => (Object.assign(Object.assign({}, prevState), { messages: dedupeMessages([...messagesToAdd, ...prevState.messages]), nextCursor: nextCursor === null || nextCursor === void 0 ? void 0 : nextCursor.id })));
|
179
215
|
}
|
180
216
|
catch (e) {
|
181
217
|
setLoadingError(e);
|
@@ -35,6 +35,25 @@ function extendContent(content, nextContent) {
|
|
35
35
|
}
|
36
36
|
}
|
37
37
|
}
|
38
|
+
function dedupeMessages(messages) {
|
39
|
+
const messageIndex = new Set(messages.map((message) => `${message.id}${message.messageType}`));
|
40
|
+
return messages.filter((message) => {
|
41
|
+
// if we have seen this message before, return false
|
42
|
+
if (messageIndex.has(`${message.id}${message.messageType}`)) {
|
43
|
+
messageIndex.delete(`${message.id}${message.messageType}`);
|
44
|
+
return true;
|
45
|
+
}
|
46
|
+
return false;
|
47
|
+
}, []);
|
48
|
+
}
|
49
|
+
function messageCreateToMessageUnion(messages) {
|
50
|
+
return messages.map((message, idx) => ({
|
51
|
+
messageType: message.role === 'user' ? 'user_message' : 'system_message',
|
52
|
+
content: message.content,
|
53
|
+
date: new Date(),
|
54
|
+
id: `autogenerated_${Date.now()}_${idx}`,
|
55
|
+
}));
|
56
|
+
}
|
38
57
|
export function useAgentMessages(options) {
|
39
58
|
const { client = {}, method = 'stream', messageOptions = {}, limit = 20, agentId, } = options;
|
40
59
|
const localClient = useLettaClient(client);
|
@@ -49,26 +68,39 @@ export function useAgentMessages(options) {
|
|
49
68
|
const [sendingError, setSendingError] = useState(null);
|
50
69
|
const sendNonStreamedMessage = useCallback(function sendNonStreamedMessage(sendMessagePayload) {
|
51
70
|
return __awaiter(this, void 0, void 0, function* () {
|
71
|
+
let originalMessageState = localMessages;
|
52
72
|
try {
|
53
73
|
setIsSending(true);
|
54
74
|
setSendingError(null);
|
75
|
+
const newMessages = messageCreateToMessageUnion(sendMessagePayload.messages);
|
76
|
+
setLocalMessages((prevState) => {
|
77
|
+
originalMessageState = prevState;
|
78
|
+
return Object.assign(Object.assign({}, prevState), { messages: [...prevState.messages, ...newMessages] });
|
79
|
+
});
|
55
80
|
const response = yield localClient.agents.messages.create(agentId, Object.assign(Object.assign({}, sendMessagePayload), messageOptions));
|
56
|
-
setLocalMessages((prevState) => (Object.assign(Object.assign({}, prevState), { messages: [...
|
81
|
+
setLocalMessages((prevState) => (Object.assign(Object.assign({}, prevState), { messages: [...prevState.messages, ...response.messages] })));
|
57
82
|
}
|
58
83
|
catch (e) {
|
84
|
+
setLocalMessages(originalMessageState);
|
59
85
|
setSendingError(e);
|
60
86
|
}
|
61
87
|
finally {
|
62
88
|
setIsSending(false);
|
63
89
|
}
|
64
90
|
});
|
65
|
-
}, [localClient]);
|
91
|
+
}, [localClient, localMessages]);
|
66
92
|
const sendStreamedMessage = useCallback(function sendStreamedMessage(sendMessagePayload) {
|
67
93
|
return __awaiter(this, void 0, void 0, function* () {
|
68
94
|
var _a, e_1, _b, _c;
|
95
|
+
let originalMessageState = localMessages;
|
69
96
|
try {
|
70
97
|
setIsSending(true);
|
71
98
|
setSendingError(null);
|
99
|
+
const newMessages = messageCreateToMessageUnion(sendMessagePayload.messages);
|
100
|
+
setLocalMessages((prevState) => {
|
101
|
+
originalMessageState = prevState;
|
102
|
+
return Object.assign(Object.assign({}, prevState), { messages: [...prevState.messages, ...newMessages] });
|
103
|
+
});
|
72
104
|
const response = yield localClient.agents.messages.createStream(agentId, Object.assign(Object.assign(Object.assign({}, sendMessagePayload), messageOptions), { streamTokens: true }));
|
73
105
|
try {
|
74
106
|
for (var _d = true, response_1 = __asyncValues(response), response_1_1; response_1_1 = yield response_1.next(), _a = response_1_1.done, !_a; _d = true) {
|
@@ -156,13 +188,17 @@ export function useAgentMessages(options) {
|
|
156
188
|
});
|
157
189
|
}, [localClient]);
|
158
190
|
const sendMessage = useCallback(function sendMessage(payload) {
|
191
|
+
const filteredPayload = Object.assign(Object.assign({}, payload), { messages: payload.messages.filter((e) => !!e.content) });
|
192
|
+
if (filteredPayload.messages.length === 0) {
|
193
|
+
return;
|
194
|
+
}
|
159
195
|
if (isSending) {
|
160
196
|
return;
|
161
197
|
}
|
162
198
|
if (method === 'stream') {
|
163
|
-
return sendStreamedMessage(
|
199
|
+
return sendStreamedMessage(filteredPayload);
|
164
200
|
}
|
165
|
-
return sendNonStreamedMessage(
|
201
|
+
return sendNonStreamedMessage(filteredPayload);
|
166
202
|
}, [method, isSending, sendStreamedMessage, sendNonStreamedMessage]);
|
167
203
|
const getMessages = useCallback(function getMessages(before) {
|
168
204
|
return __awaiter(this, void 0, void 0, function* () {
|
@@ -175,7 +211,7 @@ export function useAgentMessages(options) {
|
|
175
211
|
const messages = yield localClient.agents.messages.list(agentId, Object.assign({ before, limit: limit + 1 }, messageOptions));
|
176
212
|
const messagesToAdd = messages.slice(1, messages.length);
|
177
213
|
const nextCursor = messages.length > limit ? messages[0] : undefined;
|
178
|
-
setLocalMessages((prevState) => (Object.assign(Object.assign({}, prevState), { messages: [...messagesToAdd, ...prevState.messages], nextCursor: nextCursor === null || nextCursor === void 0 ? void 0 : nextCursor.id })));
|
214
|
+
setLocalMessages((prevState) => (Object.assign(Object.assign({}, prevState), { messages: dedupeMessages([...messagesToAdd, ...prevState.messages]), nextCursor: nextCursor === null || nextCursor === void 0 ? void 0 : nextCursor.id })));
|
179
215
|
}
|
180
216
|
catch (e) {
|
181
217
|
setLoadingError(e);
|
package/package.json
CHANGED
@@ -6,6 +6,7 @@ import { useGlobalLettaConfig } from '../useGlobalLettaConfig/useGlobalLettaConf
|
|
6
6
|
import type { LocalMessagesState } from '../../types';
|
7
7
|
import { useCachedState } from '../useCachedState/useCachedState';
|
8
8
|
import { useLettaClient } from '../useLettaClient/useLettaClient';
|
9
|
+
import { LettaMessageUnion, MessageCreate } from '@letta-ai/letta-client/api';
|
9
10
|
|
10
11
|
interface UseAgentOptions {
|
11
12
|
client?: LettaClient.Options;
|
@@ -34,6 +35,35 @@ function extendContent(
|
|
34
35
|
}
|
35
36
|
}
|
36
37
|
|
38
|
+
function dedupeMessages(
|
39
|
+
messages: LocalMessagesState['messages']
|
40
|
+
): LocalMessagesState['messages'] {
|
41
|
+
const messageIndex = new Set(
|
42
|
+
messages.map((message) => `${message.id}${message.messageType}`)
|
43
|
+
);
|
44
|
+
|
45
|
+
return messages.filter((message) => {
|
46
|
+
// if we have seen this message before, return false
|
47
|
+
if (messageIndex.has(`${message.id}${message.messageType}`)) {
|
48
|
+
messageIndex.delete(`${message.id}${message.messageType}`);
|
49
|
+
return true;
|
50
|
+
}
|
51
|
+
|
52
|
+
return false;
|
53
|
+
}, []);
|
54
|
+
}
|
55
|
+
|
56
|
+
function messageCreateToMessageUnion(
|
57
|
+
messages: MessageCreate[]
|
58
|
+
): LettaMessageUnion[] {
|
59
|
+
return messages.map((message, idx) => ({
|
60
|
+
messageType: message.role === 'user' ? 'user_message' : 'system_message',
|
61
|
+
content: message.content,
|
62
|
+
date: new Date(),
|
63
|
+
id: `autogenerated_${Date.now()}_${idx}`,
|
64
|
+
}));
|
65
|
+
}
|
66
|
+
|
37
67
|
interface SendMessagePayload {
|
38
68
|
messages: LettaRequest['messages'];
|
39
69
|
}
|
@@ -68,10 +98,24 @@ export function useAgentMessages(options: UseAgentOptions) {
|
|
68
98
|
async function sendNonStreamedMessage(
|
69
99
|
sendMessagePayload: SendMessagePayload
|
70
100
|
) {
|
101
|
+
let originalMessageState: LocalMessagesState = localMessages;
|
71
102
|
try {
|
72
103
|
setIsSending(true);
|
73
104
|
setSendingError(null);
|
74
105
|
|
106
|
+
const newMessages = messageCreateToMessageUnion(
|
107
|
+
sendMessagePayload.messages
|
108
|
+
);
|
109
|
+
|
110
|
+
setLocalMessages((prevState) => {
|
111
|
+
originalMessageState = prevState;
|
112
|
+
|
113
|
+
return {
|
114
|
+
...prevState,
|
115
|
+
messages: [...prevState.messages, ...newMessages],
|
116
|
+
};
|
117
|
+
});
|
118
|
+
|
75
119
|
const response = await localClient.agents.messages.create(agentId, {
|
76
120
|
...sendMessagePayload,
|
77
121
|
...messageOptions,
|
@@ -79,23 +123,39 @@ export function useAgentMessages(options: UseAgentOptions) {
|
|
79
123
|
|
80
124
|
setLocalMessages((prevState) => ({
|
81
125
|
...prevState,
|
82
|
-
messages: [...
|
126
|
+
messages: [...prevState.messages, ...response.messages],
|
83
127
|
}));
|
84
128
|
} catch (e) {
|
129
|
+
setLocalMessages(originalMessageState);
|
85
130
|
setSendingError(e);
|
86
131
|
} finally {
|
87
132
|
setIsSending(false);
|
88
133
|
}
|
89
134
|
},
|
90
|
-
[localClient]
|
135
|
+
[localClient, localMessages]
|
91
136
|
);
|
92
137
|
|
93
138
|
const sendStreamedMessage = useCallback(
|
94
139
|
async function sendStreamedMessage(sendMessagePayload: SendMessagePayload) {
|
140
|
+
let originalMessageState: LocalMessagesState = localMessages;
|
141
|
+
|
95
142
|
try {
|
96
143
|
setIsSending(true);
|
97
144
|
setSendingError(null);
|
98
145
|
|
146
|
+
const newMessages = messageCreateToMessageUnion(
|
147
|
+
sendMessagePayload.messages
|
148
|
+
);
|
149
|
+
|
150
|
+
setLocalMessages((prevState) => {
|
151
|
+
originalMessageState = prevState;
|
152
|
+
|
153
|
+
return {
|
154
|
+
...prevState,
|
155
|
+
messages: [...prevState.messages, ...newMessages],
|
156
|
+
};
|
157
|
+
});
|
158
|
+
|
99
159
|
const response = await localClient.agents.messages.createStream(
|
100
160
|
agentId,
|
101
161
|
{
|
@@ -244,15 +304,24 @@ export function useAgentMessages(options: UseAgentOptions) {
|
|
244
304
|
|
245
305
|
const sendMessage = useCallback(
|
246
306
|
function sendMessage(payload: SendMessagePayload) {
|
307
|
+
const filteredPayload = {
|
308
|
+
...payload,
|
309
|
+
messages: payload.messages.filter((e) => !!e.content),
|
310
|
+
};
|
311
|
+
|
312
|
+
if (filteredPayload.messages.length === 0) {
|
313
|
+
return;
|
314
|
+
}
|
315
|
+
|
247
316
|
if (isSending) {
|
248
317
|
return;
|
249
318
|
}
|
250
319
|
|
251
320
|
if (method === 'stream') {
|
252
|
-
return sendStreamedMessage(
|
321
|
+
return sendStreamedMessage(filteredPayload);
|
253
322
|
}
|
254
323
|
|
255
|
-
return sendNonStreamedMessage(
|
324
|
+
return sendNonStreamedMessage(filteredPayload);
|
256
325
|
},
|
257
326
|
[method, isSending, sendStreamedMessage, sendNonStreamedMessage]
|
258
327
|
);
|
@@ -278,7 +347,7 @@ export function useAgentMessages(options: UseAgentOptions) {
|
|
278
347
|
|
279
348
|
setLocalMessages((prevState) => ({
|
280
349
|
...prevState,
|
281
|
-
messages: [...messagesToAdd, ...prevState.messages],
|
350
|
+
messages: dedupeMessages([...messagesToAdd, ...prevState.messages]),
|
282
351
|
nextCursor: nextCursor?.id,
|
283
352
|
}));
|
284
353
|
} catch (e) {
|