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