@mastra/upstash 1.0.4 → 1.0.5
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/CHANGELOG.md +22 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-memory-working-memory.md +4 -4
- package/dist/docs/references/docs-rag-retrieval.md +12 -12
- package/dist/docs/references/reference-storage-upstash.md +2 -2
- package/dist/docs/references/reference-vectors-upstash.md +1 -1
- package/dist/index.cjs +328 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +329 -50
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/background-tasks/index.d.ts +18 -0
- package/dist/storage/domains/background-tasks/index.d.ts.map +1 -0
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts +2 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/package.json +12 -12
package/dist/index.cjs
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
var storage = require('@mastra/core/storage');
|
|
4
4
|
var redis = require('@upstash/redis');
|
|
5
|
-
var agent = require('@mastra/core/agent');
|
|
6
5
|
var error = require('@mastra/core/error');
|
|
6
|
+
var agent = require('@mastra/core/agent');
|
|
7
7
|
var evals = require('@mastra/core/evals');
|
|
8
8
|
var crypto$1 = require('crypto');
|
|
9
9
|
var vector = require('@mastra/core/vector');
|
|
@@ -140,7 +140,164 @@ var UpstashDB = class {
|
|
|
140
140
|
}
|
|
141
141
|
};
|
|
142
142
|
|
|
143
|
-
// src/storage/domains/
|
|
143
|
+
// src/storage/domains/background-tasks/index.ts
|
|
144
|
+
function toStorageRecord(task) {
|
|
145
|
+
return {
|
|
146
|
+
id: task.id,
|
|
147
|
+
tool_call_id: task.toolCallId,
|
|
148
|
+
tool_name: task.toolName,
|
|
149
|
+
agent_id: task.agentId,
|
|
150
|
+
thread_id: task.threadId ?? null,
|
|
151
|
+
resource_id: task.resourceId ?? null,
|
|
152
|
+
run_id: task.runId,
|
|
153
|
+
status: task.status,
|
|
154
|
+
args: task.args,
|
|
155
|
+
result: task.result ?? null,
|
|
156
|
+
error: task.error ?? null,
|
|
157
|
+
retry_count: task.retryCount,
|
|
158
|
+
max_retries: task.maxRetries,
|
|
159
|
+
timeout_ms: task.timeoutMs,
|
|
160
|
+
createdAt: task.createdAt.toISOString(),
|
|
161
|
+
startedAt: task.startedAt?.toISOString() ?? null,
|
|
162
|
+
completedAt: task.completedAt?.toISOString() ?? null
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
function fromStorageRecord(record) {
|
|
166
|
+
return {
|
|
167
|
+
id: record.id,
|
|
168
|
+
status: record.status,
|
|
169
|
+
toolName: record.tool_name,
|
|
170
|
+
toolCallId: record.tool_call_id,
|
|
171
|
+
args: record.args ?? {},
|
|
172
|
+
agentId: record.agent_id,
|
|
173
|
+
threadId: record.thread_id ?? void 0,
|
|
174
|
+
resourceId: record.resource_id ?? void 0,
|
|
175
|
+
runId: record.run_id ?? "",
|
|
176
|
+
result: record.result ?? void 0,
|
|
177
|
+
error: record.error ?? void 0,
|
|
178
|
+
retryCount: Number(record.retry_count ?? 0),
|
|
179
|
+
maxRetries: Number(record.max_retries ?? 0),
|
|
180
|
+
timeoutMs: Number(record.timeout_ms ?? 3e5),
|
|
181
|
+
createdAt: new Date(record.createdAt),
|
|
182
|
+
startedAt: record.startedAt ? new Date(record.startedAt) : void 0,
|
|
183
|
+
completedAt: record.completedAt ? new Date(record.completedAt) : void 0
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
var BackgroundTasksUpstash = class extends storage.BackgroundTasksStorage {
|
|
187
|
+
client;
|
|
188
|
+
#db;
|
|
189
|
+
constructor(config) {
|
|
190
|
+
super();
|
|
191
|
+
const client = resolveUpstashConfig(config);
|
|
192
|
+
this.client = client;
|
|
193
|
+
this.#db = new UpstashDB({ client });
|
|
194
|
+
}
|
|
195
|
+
async dangerouslyClearAll() {
|
|
196
|
+
await this.#db.deleteData({ tableName: storage.TABLE_BACKGROUND_TASKS });
|
|
197
|
+
}
|
|
198
|
+
async createTask(task) {
|
|
199
|
+
const record = toStorageRecord(task);
|
|
200
|
+
const { key, processedRecord } = processRecord(storage.TABLE_BACKGROUND_TASKS, record);
|
|
201
|
+
await this.client.set(key, processedRecord);
|
|
202
|
+
}
|
|
203
|
+
async updateTask(taskId, update) {
|
|
204
|
+
const existing = await this.getTask(taskId);
|
|
205
|
+
if (!existing) return;
|
|
206
|
+
const merged = { ...existing };
|
|
207
|
+
if ("status" in update) merged.status = update.status;
|
|
208
|
+
if ("result" in update) merged.result = update.result;
|
|
209
|
+
if ("error" in update) merged.error = update.error;
|
|
210
|
+
if ("retryCount" in update) merged.retryCount = update.retryCount;
|
|
211
|
+
if ("startedAt" in update) merged.startedAt = update.startedAt;
|
|
212
|
+
if ("completedAt" in update) merged.completedAt = update.completedAt;
|
|
213
|
+
const record = toStorageRecord(merged);
|
|
214
|
+
const { key, processedRecord } = processRecord(storage.TABLE_BACKGROUND_TASKS, record);
|
|
215
|
+
await this.client.set(key, processedRecord);
|
|
216
|
+
}
|
|
217
|
+
async getTask(taskId) {
|
|
218
|
+
const key = getKey(storage.TABLE_BACKGROUND_TASKS, { id: taskId });
|
|
219
|
+
const data = await this.client.get(key);
|
|
220
|
+
if (!data) return null;
|
|
221
|
+
return fromStorageRecord(data);
|
|
222
|
+
}
|
|
223
|
+
async listTasks(filter) {
|
|
224
|
+
const keys = await this.#db.scanKeys(`${storage.TABLE_BACKGROUND_TASKS}:*`);
|
|
225
|
+
if (keys.length === 0) return { tasks: [], total: 0 };
|
|
226
|
+
const pipeline = this.client.pipeline();
|
|
227
|
+
for (const key of keys) {
|
|
228
|
+
pipeline.get(key);
|
|
229
|
+
}
|
|
230
|
+
const results = await pipeline.exec();
|
|
231
|
+
let tasks = results.filter(Boolean).map((r) => fromStorageRecord(r));
|
|
232
|
+
if (filter.status) {
|
|
233
|
+
const statuses = Array.isArray(filter.status) ? filter.status : [filter.status];
|
|
234
|
+
tasks = tasks.filter((t) => statuses.includes(t.status));
|
|
235
|
+
}
|
|
236
|
+
if (filter.agentId) {
|
|
237
|
+
tasks = tasks.filter((t) => t.agentId === filter.agentId);
|
|
238
|
+
}
|
|
239
|
+
if (filter.threadId) {
|
|
240
|
+
tasks = tasks.filter((t) => t.threadId === filter.threadId);
|
|
241
|
+
}
|
|
242
|
+
if (filter.resourceId) {
|
|
243
|
+
tasks = tasks.filter((t) => t.resourceId === filter.resourceId);
|
|
244
|
+
}
|
|
245
|
+
if (filter.runId) {
|
|
246
|
+
tasks = tasks.filter((t) => t.runId === filter.runId);
|
|
247
|
+
}
|
|
248
|
+
if (filter.toolName) {
|
|
249
|
+
tasks = tasks.filter((t) => t.toolName === filter.toolName);
|
|
250
|
+
}
|
|
251
|
+
const dateCol = filter.dateFilterBy ?? "createdAt";
|
|
252
|
+
if (filter.fromDate) {
|
|
253
|
+
tasks = tasks.filter((t) => {
|
|
254
|
+
const val = t[dateCol];
|
|
255
|
+
return val != null && val >= filter.fromDate;
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
if (filter.toDate) {
|
|
259
|
+
tasks = tasks.filter((t) => {
|
|
260
|
+
const val = t[dateCol];
|
|
261
|
+
return val != null && val < filter.toDate;
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
const orderBy = filter.orderBy ?? "createdAt";
|
|
265
|
+
const direction = filter.orderDirection ?? "asc";
|
|
266
|
+
tasks.sort((a, b) => {
|
|
267
|
+
const aVal = a[orderBy]?.getTime() ?? 0;
|
|
268
|
+
const bVal = b[orderBy]?.getTime() ?? 0;
|
|
269
|
+
return direction === "asc" ? aVal - bVal : bVal - aVal;
|
|
270
|
+
});
|
|
271
|
+
const total = tasks.length;
|
|
272
|
+
if (filter.page != null && filter.perPage != null) {
|
|
273
|
+
const start = filter.page * filter.perPage;
|
|
274
|
+
tasks = tasks.slice(start, start + filter.perPage);
|
|
275
|
+
} else if (filter.perPage != null) {
|
|
276
|
+
tasks = tasks.slice(0, filter.perPage);
|
|
277
|
+
}
|
|
278
|
+
return { tasks, total };
|
|
279
|
+
}
|
|
280
|
+
async deleteTask(taskId) {
|
|
281
|
+
const key = getKey(storage.TABLE_BACKGROUND_TASKS, { id: taskId });
|
|
282
|
+
await this.client.del(key);
|
|
283
|
+
}
|
|
284
|
+
async deleteTasks(filter) {
|
|
285
|
+
const { tasks } = await this.listTasks(filter);
|
|
286
|
+
if (tasks.length === 0) return;
|
|
287
|
+
const keys = tasks.map((t) => getKey(storage.TABLE_BACKGROUND_TASKS, { id: t.id }));
|
|
288
|
+
if (keys.length > 0) {
|
|
289
|
+
await this.client.del(...keys);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
async getRunningCount() {
|
|
293
|
+
const { total } = await this.listTasks({ status: "running" });
|
|
294
|
+
return total;
|
|
295
|
+
}
|
|
296
|
+
async getRunningCountByAgent(agentId) {
|
|
297
|
+
const { total } = await this.listTasks({ status: "running", agentId });
|
|
298
|
+
return total;
|
|
299
|
+
}
|
|
300
|
+
};
|
|
144
301
|
function getThreadMessagesKey(threadId) {
|
|
145
302
|
return `thread:${threadId}:messages`;
|
|
146
303
|
}
|
|
@@ -393,14 +550,16 @@ var StoreMemoryUpstash = class extends storage.MemoryStorage {
|
|
|
393
550
|
async saveMessages(args) {
|
|
394
551
|
const { messages } = args;
|
|
395
552
|
if (messages.length === 0) return { messages: [] };
|
|
396
|
-
const threadId = messages[0]?.threadId;
|
|
397
553
|
try {
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
554
|
+
for (const message of messages) {
|
|
555
|
+
if (!message.threadId) {
|
|
556
|
+
throw new Error("Thread ID is required");
|
|
557
|
+
}
|
|
558
|
+
if (!message.resourceId) {
|
|
559
|
+
throw new Error(
|
|
560
|
+
`Expected to find a resourceId for message, but couldn't find one. An unexpected error has occurred.`
|
|
561
|
+
);
|
|
562
|
+
}
|
|
404
563
|
}
|
|
405
564
|
} catch (error$1) {
|
|
406
565
|
throw new error.MastraError(
|
|
@@ -413,46 +572,70 @@ var StoreMemoryUpstash = class extends storage.MemoryStorage {
|
|
|
413
572
|
);
|
|
414
573
|
}
|
|
415
574
|
const messagesWithIndex = messages.map((message, index) => {
|
|
416
|
-
if (!message.threadId) {
|
|
417
|
-
throw new Error(
|
|
418
|
-
`Expected to find a threadId for message, but couldn't find one. An unexpected error has occurred.`
|
|
419
|
-
);
|
|
420
|
-
}
|
|
421
|
-
if (!message.resourceId) {
|
|
422
|
-
throw new Error(
|
|
423
|
-
`Expected to find a resourceId for message, but couldn't find one. An unexpected error has occurred.`
|
|
424
|
-
);
|
|
425
|
-
}
|
|
426
575
|
return {
|
|
427
576
|
...message,
|
|
428
577
|
_index: index
|
|
429
578
|
};
|
|
430
579
|
});
|
|
431
|
-
const threadKey = getKey(storage.TABLE_THREADS, { id: threadId });
|
|
432
|
-
const existingThread = await this.client.get(threadKey);
|
|
433
580
|
try {
|
|
434
581
|
const batchSize = 1e3;
|
|
582
|
+
const targetThreadIds = new Set(messagesWithIndex.map((message) => message.threadId));
|
|
583
|
+
const existingThreadIds = [];
|
|
584
|
+
const touchedThreadIds = new Set(targetThreadIds);
|
|
585
|
+
for (let i = 0; i < messagesWithIndex.length; i += batchSize) {
|
|
586
|
+
const batch = messagesWithIndex.slice(i, i + batchSize);
|
|
587
|
+
const indexLookupPipeline = this.client.pipeline();
|
|
588
|
+
batch.forEach((message) => {
|
|
589
|
+
indexLookupPipeline.get(getMessageIndexKey(message.id));
|
|
590
|
+
});
|
|
591
|
+
const batchExistingThreadIds = await indexLookupPipeline.exec();
|
|
592
|
+
existingThreadIds.push(...batchExistingThreadIds);
|
|
593
|
+
batchExistingThreadIds.forEach((existingThreadId) => {
|
|
594
|
+
if (existingThreadId) {
|
|
595
|
+
touchedThreadIds.add(existingThreadId);
|
|
596
|
+
}
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
const touchedThreadIdList = Array.from(touchedThreadIds);
|
|
600
|
+
const threadLookupPipeline = this.client.pipeline();
|
|
601
|
+
touchedThreadIdList.forEach((touchedThreadId) => {
|
|
602
|
+
threadLookupPipeline.get(getKey(storage.TABLE_THREADS, { id: touchedThreadId }));
|
|
603
|
+
});
|
|
604
|
+
const threadLookupResults = await threadLookupPipeline.exec();
|
|
605
|
+
const threadRecordsById = /* @__PURE__ */ new Map();
|
|
606
|
+
touchedThreadIdList.forEach((touchedThreadId, index) => {
|
|
607
|
+
const threadRecord = threadLookupResults[index];
|
|
608
|
+
if (threadRecord) {
|
|
609
|
+
threadRecordsById.set(touchedThreadId, threadRecord);
|
|
610
|
+
}
|
|
611
|
+
});
|
|
612
|
+
for (const targetThreadId of targetThreadIds) {
|
|
613
|
+
if (!threadRecordsById.has(targetThreadId)) {
|
|
614
|
+
throw new error.MastraError(
|
|
615
|
+
{
|
|
616
|
+
id: storage.createStorageErrorId("UPSTASH", "SAVE_MESSAGES", "INVALID_ARGS"),
|
|
617
|
+
domain: error.ErrorDomain.STORAGE,
|
|
618
|
+
category: error.ErrorCategory.USER
|
|
619
|
+
},
|
|
620
|
+
new Error(`Thread ${targetThreadId} not found`)
|
|
621
|
+
);
|
|
622
|
+
}
|
|
623
|
+
}
|
|
435
624
|
for (let i = 0; i < messagesWithIndex.length; i += batchSize) {
|
|
436
625
|
const batch = messagesWithIndex.slice(i, i + batchSize);
|
|
437
626
|
const pipeline = this.client.pipeline();
|
|
438
|
-
|
|
627
|
+
const batchTouchedThreadIds = /* @__PURE__ */ new Set();
|
|
628
|
+
const batchExistingThreadIds = existingThreadIds.slice(i, i + batch.length);
|
|
629
|
+
for (const [batchIndex, message] of batch.entries()) {
|
|
439
630
|
const key = getMessageKey(message.threadId, message.id);
|
|
440
631
|
const createdAtScore = new Date(message.createdAt).getTime();
|
|
441
632
|
const score = message._index !== void 0 ? message._index : createdAtScore;
|
|
442
|
-
|
|
443
|
-
const
|
|
444
|
-
if (
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
const existingMessages = results.filter((msg) => msg !== null);
|
|
449
|
-
for (const existingMessage of existingMessages) {
|
|
450
|
-
const existingMessageKey = getMessageKey(existingMessage.threadId, existingMessage.id);
|
|
451
|
-
if (existingMessage && existingMessage.threadId !== message.threadId) {
|
|
452
|
-
pipeline.del(existingMessageKey);
|
|
453
|
-
pipeline.zrem(getThreadMessagesKey(existingMessage.threadId), existingMessage.id);
|
|
454
|
-
}
|
|
455
|
-
}
|
|
633
|
+
batchTouchedThreadIds.add(message.threadId);
|
|
634
|
+
const existingThreadId = batchExistingThreadIds[batchIndex];
|
|
635
|
+
if (existingThreadId && existingThreadId !== message.threadId) {
|
|
636
|
+
pipeline.del(getMessageKey(existingThreadId, message.id));
|
|
637
|
+
pipeline.zrem(getThreadMessagesKey(existingThreadId), message.id);
|
|
638
|
+
batchTouchedThreadIds.add(existingThreadId);
|
|
456
639
|
}
|
|
457
640
|
pipeline.set(key, message);
|
|
458
641
|
pipeline.set(getMessageIndexKey(message.id), message.threadId);
|
|
@@ -461,25 +644,35 @@ var StoreMemoryUpstash = class extends storage.MemoryStorage {
|
|
|
461
644
|
member: message.id
|
|
462
645
|
});
|
|
463
646
|
}
|
|
464
|
-
|
|
647
|
+
const now = /* @__PURE__ */ new Date();
|
|
648
|
+
for (const touchedThreadId of batchTouchedThreadIds) {
|
|
649
|
+
const existingThread = threadRecordsById.get(touchedThreadId);
|
|
650
|
+
if (!existingThread) {
|
|
651
|
+
continue;
|
|
652
|
+
}
|
|
465
653
|
const updatedThread = {
|
|
466
654
|
...existingThread,
|
|
467
|
-
updatedAt:
|
|
655
|
+
updatedAt: now
|
|
468
656
|
};
|
|
657
|
+
const threadKey = getKey(storage.TABLE_THREADS, { id: touchedThreadId });
|
|
469
658
|
pipeline.set(threadKey, processRecord(storage.TABLE_THREADS, updatedThread).processedRecord);
|
|
659
|
+
threadRecordsById.set(touchedThreadId, updatedThread);
|
|
470
660
|
}
|
|
471
661
|
await pipeline.exec();
|
|
472
662
|
}
|
|
473
663
|
const list = new agent.MessageList().add(messages, "memory");
|
|
474
664
|
return { messages: list.get.all.db() };
|
|
475
665
|
} catch (error$1) {
|
|
666
|
+
if (error$1 instanceof error.MastraError) {
|
|
667
|
+
throw error$1;
|
|
668
|
+
}
|
|
476
669
|
throw new error.MastraError(
|
|
477
670
|
{
|
|
478
671
|
id: storage.createStorageErrorId("UPSTASH", "SAVE_MESSAGES", "FAILED"),
|
|
479
672
|
domain: error.ErrorDomain.STORAGE,
|
|
480
673
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
481
674
|
details: {
|
|
482
|
-
threadId
|
|
675
|
+
threadIds: Array.from(new Set(messages.map((message) => message.threadId).filter(Boolean))).join(",")
|
|
483
676
|
}
|
|
484
677
|
},
|
|
485
678
|
error$1
|
|
@@ -836,9 +1029,41 @@ var StoreMemoryUpstash = class extends storage.MemoryStorage {
|
|
|
836
1029
|
}
|
|
837
1030
|
try {
|
|
838
1031
|
const messageIds = messages.map((m) => m.id);
|
|
1032
|
+
const updatesById = new Map(messages.map((message) => [message.id, message]));
|
|
839
1033
|
const existingMessages = [];
|
|
840
1034
|
const messageIdToKey = {};
|
|
841
|
-
|
|
1035
|
+
const backfillIndexValues = {};
|
|
1036
|
+
const indexPipeline = this.client.pipeline();
|
|
1037
|
+
messageIds.forEach((messageId) => indexPipeline.get(getMessageIndexKey(messageId)));
|
|
1038
|
+
const indexResults = await indexPipeline.exec();
|
|
1039
|
+
const indexedLookups = [];
|
|
1040
|
+
const fallbackMessageIds = [];
|
|
1041
|
+
messageIds.forEach((messageId, index) => {
|
|
1042
|
+
const indexedThreadId = indexResults[index];
|
|
1043
|
+
if (indexedThreadId) {
|
|
1044
|
+
indexedLookups.push({ messageId, threadId: indexedThreadId });
|
|
1045
|
+
} else {
|
|
1046
|
+
fallbackMessageIds.push(messageId);
|
|
1047
|
+
}
|
|
1048
|
+
});
|
|
1049
|
+
if (indexedLookups.length > 0) {
|
|
1050
|
+
const messagePipeline = this.client.pipeline();
|
|
1051
|
+
indexedLookups.forEach(({ messageId, threadId }) => {
|
|
1052
|
+
messagePipeline.get(getMessageKey(threadId, messageId));
|
|
1053
|
+
});
|
|
1054
|
+
const indexedMessages = await messagePipeline.exec();
|
|
1055
|
+
indexedLookups.forEach(({ messageId, threadId }, index) => {
|
|
1056
|
+
const key = getMessageKey(threadId, messageId);
|
|
1057
|
+
const message = indexedMessages[index];
|
|
1058
|
+
if (message && message.id === messageId) {
|
|
1059
|
+
existingMessages.push(message);
|
|
1060
|
+
messageIdToKey[messageId] = key;
|
|
1061
|
+
} else {
|
|
1062
|
+
fallbackMessageIds.push(messageId);
|
|
1063
|
+
}
|
|
1064
|
+
});
|
|
1065
|
+
}
|
|
1066
|
+
for (const messageId of fallbackMessageIds) {
|
|
842
1067
|
const pattern = getMessageKey("*", messageId);
|
|
843
1068
|
const keys = await this.#db.scanKeys(pattern);
|
|
844
1069
|
for (const key of keys) {
|
|
@@ -846,24 +1071,69 @@ var StoreMemoryUpstash = class extends storage.MemoryStorage {
|
|
|
846
1071
|
if (message && message.id === messageId) {
|
|
847
1072
|
existingMessages.push(message);
|
|
848
1073
|
messageIdToKey[messageId] = key;
|
|
1074
|
+
if (message.threadId) {
|
|
1075
|
+
backfillIndexValues[messageId] = message.threadId;
|
|
1076
|
+
}
|
|
849
1077
|
break;
|
|
850
1078
|
}
|
|
851
1079
|
}
|
|
852
1080
|
}
|
|
1081
|
+
if (Object.keys(backfillIndexValues).length > 0) {
|
|
1082
|
+
const backfillPipeline = this.client.pipeline();
|
|
1083
|
+
for (const [messageId, threadId] of Object.entries(backfillIndexValues)) {
|
|
1084
|
+
backfillPipeline.set(getMessageIndexKey(messageId), threadId);
|
|
1085
|
+
}
|
|
1086
|
+
await backfillPipeline.exec();
|
|
1087
|
+
}
|
|
853
1088
|
if (existingMessages.length === 0) {
|
|
854
1089
|
return [];
|
|
855
1090
|
}
|
|
856
1091
|
const threadIdsToUpdate = /* @__PURE__ */ new Set();
|
|
857
|
-
const
|
|
1092
|
+
const destinationThreadIds = /* @__PURE__ */ new Set();
|
|
858
1093
|
for (const existingMessage of existingMessages) {
|
|
859
|
-
const updatePayload =
|
|
1094
|
+
const updatePayload = updatesById.get(existingMessage.id);
|
|
860
1095
|
if (!updatePayload) continue;
|
|
861
|
-
const { id, ...fieldsToUpdate } = updatePayload;
|
|
1096
|
+
const { id: _id, ...fieldsToUpdate } = updatePayload;
|
|
862
1097
|
if (Object.keys(fieldsToUpdate).length === 0) continue;
|
|
863
1098
|
threadIdsToUpdate.add(existingMessage.threadId);
|
|
864
1099
|
if (updatePayload.threadId && updatePayload.threadId !== existingMessage.threadId) {
|
|
865
1100
|
threadIdsToUpdate.add(updatePayload.threadId);
|
|
1101
|
+
destinationThreadIds.add(updatePayload.threadId);
|
|
866
1102
|
}
|
|
1103
|
+
}
|
|
1104
|
+
const threadRecordsById = /* @__PURE__ */ new Map();
|
|
1105
|
+
if (threadIdsToUpdate.size > 0) {
|
|
1106
|
+
const threadIdList = Array.from(threadIdsToUpdate);
|
|
1107
|
+
const threadLookupPipeline = this.client.pipeline();
|
|
1108
|
+
threadIdList.forEach((threadId) => {
|
|
1109
|
+
threadLookupPipeline.get(getKey(storage.TABLE_THREADS, { id: threadId }));
|
|
1110
|
+
});
|
|
1111
|
+
const threadLookupResults = await threadLookupPipeline.exec();
|
|
1112
|
+
threadIdList.forEach((threadId, index) => {
|
|
1113
|
+
const threadRecord = threadLookupResults[index];
|
|
1114
|
+
if (threadRecord) {
|
|
1115
|
+
threadRecordsById.set(threadId, threadRecord);
|
|
1116
|
+
}
|
|
1117
|
+
});
|
|
1118
|
+
}
|
|
1119
|
+
for (const destinationThreadId of destinationThreadIds) {
|
|
1120
|
+
if (!threadRecordsById.has(destinationThreadId)) {
|
|
1121
|
+
throw new error.MastraError(
|
|
1122
|
+
{
|
|
1123
|
+
id: storage.createStorageErrorId("UPSTASH", "UPDATE_MESSAGES", "INVALID_ARGS"),
|
|
1124
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1125
|
+
category: error.ErrorCategory.USER
|
|
1126
|
+
},
|
|
1127
|
+
new Error(`Thread ${destinationThreadId} not found`)
|
|
1128
|
+
);
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
const pipeline = this.client.pipeline();
|
|
1132
|
+
for (const existingMessage of existingMessages) {
|
|
1133
|
+
const updatePayload = updatesById.get(existingMessage.id);
|
|
1134
|
+
if (!updatePayload) continue;
|
|
1135
|
+
const { id, ...fieldsToUpdate } = updatePayload;
|
|
1136
|
+
if (Object.keys(fieldsToUpdate).length === 0) continue;
|
|
867
1137
|
const updatedMessage = { ...existingMessage };
|
|
868
1138
|
if (fieldsToUpdate.content) {
|
|
869
1139
|
const existingContent = existingMessage.content;
|
|
@@ -888,12 +1158,15 @@ var StoreMemoryUpstash = class extends storage.MemoryStorage {
|
|
|
888
1158
|
const key = messageIdToKey[id];
|
|
889
1159
|
if (key) {
|
|
890
1160
|
if (updatePayload.threadId && updatePayload.threadId !== existingMessage.threadId) {
|
|
1161
|
+
const newThreadId = updatedMessage.threadId;
|
|
891
1162
|
const oldThreadMessagesKey = getThreadMessagesKey(existingMessage.threadId);
|
|
892
1163
|
pipeline.zrem(oldThreadMessagesKey, id);
|
|
893
1164
|
pipeline.del(key);
|
|
894
|
-
const newKey = getMessageKey(
|
|
1165
|
+
const newKey = getMessageKey(newThreadId, id);
|
|
895
1166
|
pipeline.set(newKey, updatedMessage);
|
|
896
|
-
|
|
1167
|
+
pipeline.set(getMessageIndexKey(id), newThreadId);
|
|
1168
|
+
messageIdToKey[id] = newKey;
|
|
1169
|
+
const newThreadMessagesKey = getThreadMessagesKey(newThreadId);
|
|
897
1170
|
const score = updatedMessage._index !== void 0 ? updatedMessage._index : new Date(updatedMessage.createdAt).getTime();
|
|
898
1171
|
pipeline.zadd(newThreadMessagesKey, { score, member: id });
|
|
899
1172
|
} else {
|
|
@@ -904,14 +1177,15 @@ var StoreMemoryUpstash = class extends storage.MemoryStorage {
|
|
|
904
1177
|
const now = /* @__PURE__ */ new Date();
|
|
905
1178
|
for (const threadId of threadIdsToUpdate) {
|
|
906
1179
|
if (threadId) {
|
|
907
|
-
const
|
|
908
|
-
const existingThread = await this.client.get(threadKey);
|
|
1180
|
+
const existingThread = threadRecordsById.get(threadId);
|
|
909
1181
|
if (existingThread) {
|
|
910
1182
|
const updatedThread = {
|
|
911
1183
|
...existingThread,
|
|
912
1184
|
updatedAt: now
|
|
913
1185
|
};
|
|
1186
|
+
const threadKey = getKey(storage.TABLE_THREADS, { id: threadId });
|
|
914
1187
|
pipeline.set(threadKey, processRecord(storage.TABLE_THREADS, updatedThread).processedRecord);
|
|
1188
|
+
threadRecordsById.set(threadId, updatedThread);
|
|
915
1189
|
}
|
|
916
1190
|
}
|
|
917
1191
|
}
|
|
@@ -928,6 +1202,9 @@ var StoreMemoryUpstash = class extends storage.MemoryStorage {
|
|
|
928
1202
|
}
|
|
929
1203
|
return updatedMessages;
|
|
930
1204
|
} catch (error$1) {
|
|
1205
|
+
if (error$1 instanceof error.MastraError) {
|
|
1206
|
+
throw error$1;
|
|
1207
|
+
}
|
|
931
1208
|
throw new error.MastraError(
|
|
932
1209
|
{
|
|
933
1210
|
id: storage.createStorageErrorId("UPSTASH", "UPDATE_MESSAGES", "FAILED"),
|
|
@@ -1884,10 +2161,12 @@ var UpstashStore = class extends storage.MastraCompositeStore {
|
|
|
1884
2161
|
const scores = new ScoresUpstash({ client: this.redis });
|
|
1885
2162
|
const workflows = new WorkflowsUpstash({ client: this.redis });
|
|
1886
2163
|
const memory = new StoreMemoryUpstash({ client: this.redis });
|
|
2164
|
+
const backgroundTasks = new BackgroundTasksUpstash({ client: this.redis });
|
|
1887
2165
|
this.stores = {
|
|
1888
2166
|
scores,
|
|
1889
2167
|
workflows,
|
|
1890
|
-
memory
|
|
2168
|
+
memory,
|
|
2169
|
+
backgroundTasks
|
|
1891
2170
|
};
|
|
1892
2171
|
}
|
|
1893
2172
|
async close() {
|
|
@@ -2593,6 +2872,7 @@ Example Complex Query:
|
|
|
2593
2872
|
]
|
|
2594
2873
|
}`;
|
|
2595
2874
|
|
|
2875
|
+
exports.BackgroundTasksUpstash = BackgroundTasksUpstash;
|
|
2596
2876
|
exports.ScoresUpstash = ScoresUpstash;
|
|
2597
2877
|
exports.StoreMemoryUpstash = StoreMemoryUpstash;
|
|
2598
2878
|
exports.UPSTASH_PROMPT = UPSTASH_PROMPT;
|