@mastra/convex 1.1.0-alpha.0 → 1.2.0-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 +129 -0
- package/README.md +31 -13
- package/dist/{chunk-FZDLZ4S3.js → chunk-AJFME2ZF.js} +323 -16
- package/dist/chunk-AJFME2ZF.js.map +1 -0
- package/dist/{chunk-JPWDG4L3.js → chunk-MC75WADX.js} +79 -4
- package/dist/chunk-MC75WADX.js.map +1 -0
- package/dist/{chunk-EEELVBWO.cjs → chunk-ORSDZTO4.cjs} +322 -15
- package/dist/chunk-ORSDZTO4.cjs.map +1 -0
- package/dist/{chunk-CV23JOCS.cjs → chunk-SFRHJGSM.cjs} +102 -2
- package/dist/chunk-SFRHJGSM.cjs.map +1 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +63 -23
- package/dist/index.cjs +634 -69
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +574 -49
- package/dist/index.js.map +1 -1
- package/dist/schema.cjs +60 -20
- package/dist/schema.d.ts +192 -2
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +1 -1
- package/dist/server/index-map.d.ts.map +1 -1
- package/dist/server/index.cjs +63 -23
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +2 -2
- package/dist/server/storage.d.ts.map +1 -1
- package/dist/storage/db/index.d.ts +28 -1
- package/dist/storage/db/index.d.ts.map +1 -1
- package/dist/storage/domains/background-tasks/index.d.ts.map +1 -1
- package/dist/storage/domains/channels/index.d.ts +19 -0
- package/dist/storage/domains/channels/index.d.ts.map +1 -0
- package/dist/storage/domains/schedules/index.d.ts +19 -0
- package/dist/storage/domains/schedules/index.d.ts.map +1 -0
- package/dist/storage/index.d.ts +3 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/types.d.ts +42 -0
- package/dist/storage/types.d.ts.map +1 -1
- package/package.json +5 -5
- package/dist/chunk-CV23JOCS.cjs.map +0 -1
- package/dist/chunk-EEELVBWO.cjs.map +0 -1
- package/dist/chunk-FZDLZ4S3.js.map +0 -1
- package/dist/chunk-JPWDG4L3.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { mastraCache, mastraNativeVectorAction, mastraNativeVectorMutation, mastraNativeVectorQuery, mastraStorage } from './chunk-
|
|
2
|
-
export { TABLE_MESSAGES, TABLE_RESOURCES, TABLE_SCORERS, TABLE_THREADS, TABLE_WORKFLOW_SNAPSHOT, defineMastraNativeVectorTable, mastraCacheListItemsTable, mastraCacheTable, mastraDocumentsTable, mastraMessagesTable, mastraResourcesTable, mastraScoresTable, mastraThreadsTable, mastraVectorIndexesTable, mastraVectorsTable, mastraWorkflowSnapshotsTable } from './chunk-
|
|
1
|
+
export { mastraCache, mastraNativeVectorAction, mastraNativeVectorMutation, mastraNativeVectorQuery, mastraStorage } from './chunk-AJFME2ZF.js';
|
|
2
|
+
export { TABLE_BACKGROUND_TASKS, TABLE_CHANNEL_CONFIG, TABLE_CHANNEL_INSTALLATIONS, TABLE_MESSAGES, TABLE_RESOURCES, TABLE_SCHEDULES, TABLE_SCHEDULE_TRIGGERS, TABLE_SCORERS, TABLE_THREADS, TABLE_WORKFLOW_SNAPSHOT, defineMastraNativeVectorTable, mastraBackgroundTasksTable, mastraCacheListItemsTable, mastraCacheTable, mastraChannelConfigTable, mastraChannelInstallationsTable, mastraDocumentsTable, mastraMessagesTable, mastraResourcesTable, mastraScheduleTriggersTable, mastraSchedulesTable, mastraScoresTable, mastraThreadsTable, mastraVectorIndexesTable, mastraVectorsTable, mastraWorkflowSnapshotsTable } from './chunk-MC75WADX.js';
|
|
3
3
|
import { MastraServerCache } from '@mastra/core/cache';
|
|
4
|
-
import { MastraCompositeStore, createVectorErrorId, MemoryStorage, TABLE_THREADS, TABLE_MESSAGES, TABLE_RESOURCES, createStorageErrorId, normalizePerPage, calculatePagination, filterByDateRange, safelyParseJSON, WorkflowsStorage, TABLE_WORKFLOW_SNAPSHOT, ScoresStorage, TABLE_SCORERS, BackgroundTasksStorage, TABLE_BACKGROUND_TASKS } from '@mastra/core/storage';
|
|
4
|
+
import { MastraCompositeStore, createVectorErrorId, MemoryStorage, TABLE_THREADS, TABLE_MESSAGES, TABLE_RESOURCES, createStorageErrorId, normalizePerPage, calculatePagination, filterByDateRange, safelyParseJSON, WorkflowsStorage, TABLE_WORKFLOW_SNAPSHOT, ScoresStorage, TABLE_SCORERS, ChannelsStorage, TABLE_CHANNEL_INSTALLATIONS, TABLE_CHANNEL_CONFIG, SchedulesStorage, TABLE_SCHEDULE_TRIGGERS, TABLE_SCHEDULES, BackgroundTasksStorage, TABLE_BACKGROUND_TASKS } from '@mastra/core/storage';
|
|
5
5
|
import crypto from 'crypto';
|
|
6
6
|
import { MastraBase } from '@mastra/core/base';
|
|
7
7
|
import { MessageList } from '@mastra/core/agent';
|
|
@@ -337,6 +337,18 @@ var ConvexDB = class extends MastraBase {
|
|
|
337
337
|
records: records.map((record) => this.normalizeRecord(tableName, record))
|
|
338
338
|
});
|
|
339
339
|
}
|
|
340
|
+
async patch({
|
|
341
|
+
tableName,
|
|
342
|
+
id,
|
|
343
|
+
record
|
|
344
|
+
}) {
|
|
345
|
+
return this.client.callStorage({
|
|
346
|
+
op: "patch",
|
|
347
|
+
tableName,
|
|
348
|
+
id,
|
|
349
|
+
record: this.normalizePatch(record)
|
|
350
|
+
});
|
|
351
|
+
}
|
|
340
352
|
async load({ tableName, keys }) {
|
|
341
353
|
const result = await this.client.callStorage({
|
|
342
354
|
op: "load",
|
|
@@ -345,12 +357,13 @@ var ConvexDB = class extends MastraBase {
|
|
|
345
357
|
});
|
|
346
358
|
return result;
|
|
347
359
|
}
|
|
348
|
-
async queryTable(tableName, filters, indexHint) {
|
|
360
|
+
async queryTable(tableName, filters, indexHint, limit) {
|
|
349
361
|
return this.client.callStorage({
|
|
350
362
|
op: "queryTable",
|
|
351
363
|
tableName,
|
|
352
364
|
filters,
|
|
353
|
-
indexHint
|
|
365
|
+
indexHint,
|
|
366
|
+
limit
|
|
354
367
|
});
|
|
355
368
|
}
|
|
356
369
|
async deleteMany(tableName, ids) {
|
|
@@ -361,6 +374,85 @@ var ConvexDB = class extends MastraBase {
|
|
|
361
374
|
ids
|
|
362
375
|
});
|
|
363
376
|
}
|
|
377
|
+
async createSchedule(record) {
|
|
378
|
+
if (!record.id) {
|
|
379
|
+
throw new Error(`Schedule is missing an id`);
|
|
380
|
+
}
|
|
381
|
+
await this.client.callStorage({
|
|
382
|
+
op: "createSchedule",
|
|
383
|
+
tableName: TABLE_SCHEDULES,
|
|
384
|
+
record: this.normalizeRecord(TABLE_SCHEDULES, record)
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
async recordScheduleTrigger(record) {
|
|
388
|
+
if (!record.id) {
|
|
389
|
+
throw new Error(`Schedule trigger is missing an id`);
|
|
390
|
+
}
|
|
391
|
+
await this.client.callStorage({
|
|
392
|
+
op: "recordScheduleTrigger",
|
|
393
|
+
tableName: TABLE_SCHEDULE_TRIGGERS,
|
|
394
|
+
record: this.normalizeRecord(TABLE_SCHEDULE_TRIGGERS, record)
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
async listDueSchedules(now, limit) {
|
|
398
|
+
return this.client.callStorage({
|
|
399
|
+
op: "listDueSchedules",
|
|
400
|
+
tableName: TABLE_SCHEDULES,
|
|
401
|
+
now,
|
|
402
|
+
limit
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
async updateScheduleNextFire({
|
|
406
|
+
id,
|
|
407
|
+
expectedNextFireAt,
|
|
408
|
+
newNextFireAt,
|
|
409
|
+
lastFireAt,
|
|
410
|
+
lastRunId
|
|
411
|
+
}) {
|
|
412
|
+
return this.client.callStorage({
|
|
413
|
+
op: "updateScheduleNextFire",
|
|
414
|
+
tableName: TABLE_SCHEDULES,
|
|
415
|
+
id,
|
|
416
|
+
expectedNextFireAt,
|
|
417
|
+
newNextFireAt,
|
|
418
|
+
lastFireAt,
|
|
419
|
+
lastRunId
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
async updateSchedule({ id, patch }) {
|
|
423
|
+
return this.client.callStorage({
|
|
424
|
+
op: "updateSchedule",
|
|
425
|
+
tableName: TABLE_SCHEDULES,
|
|
426
|
+
id,
|
|
427
|
+
patch
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
async listScheduleTriggers({
|
|
431
|
+
scheduleId,
|
|
432
|
+
fromActualFireAt,
|
|
433
|
+
toActualFireAt,
|
|
434
|
+
limit
|
|
435
|
+
}) {
|
|
436
|
+
return this.client.callStorage({
|
|
437
|
+
op: "listScheduleTriggers",
|
|
438
|
+
tableName: TABLE_SCHEDULE_TRIGGERS,
|
|
439
|
+
scheduleId,
|
|
440
|
+
fromActualFireAt,
|
|
441
|
+
toActualFireAt,
|
|
442
|
+
limit
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
async deleteScheduleTriggers(scheduleId) {
|
|
446
|
+
let hasMore = true;
|
|
447
|
+
while (hasMore) {
|
|
448
|
+
const response = await this.client.callStorageRaw({
|
|
449
|
+
op: "deleteScheduleTriggers",
|
|
450
|
+
tableName: TABLE_SCHEDULE_TRIGGERS,
|
|
451
|
+
scheduleId
|
|
452
|
+
});
|
|
453
|
+
hasMore = response.hasMore ?? false;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
364
456
|
normalizeRecord(tableName, record) {
|
|
365
457
|
const normalized = { ...record };
|
|
366
458
|
if (tableName === TABLE_WORKFLOW_SNAPSHOT && !normalized.id) {
|
|
@@ -378,29 +470,69 @@ var ConvexDB = class extends MastraBase {
|
|
|
378
470
|
}
|
|
379
471
|
return normalized;
|
|
380
472
|
}
|
|
473
|
+
normalizePatch(record) {
|
|
474
|
+
const normalized = { ...record };
|
|
475
|
+
for (const [key, value] of Object.entries(normalized)) {
|
|
476
|
+
if (value instanceof Date) {
|
|
477
|
+
normalized[key] = value.toISOString();
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
return normalized;
|
|
481
|
+
}
|
|
381
482
|
};
|
|
382
483
|
|
|
383
484
|
// src/storage/domains/background-tasks/index.ts
|
|
384
485
|
function serializeJson(v) {
|
|
385
|
-
if (
|
|
386
|
-
return v
|
|
486
|
+
if (v === void 0 || v === null) return null;
|
|
487
|
+
return JSON.stringify(v);
|
|
488
|
+
}
|
|
489
|
+
function serializeRequiredJson(v) {
|
|
490
|
+
return JSON.stringify(v ?? {});
|
|
387
491
|
}
|
|
388
492
|
function toStored(task) {
|
|
389
493
|
return {
|
|
390
|
-
|
|
391
|
-
|
|
494
|
+
id: task.id,
|
|
495
|
+
status: task.status,
|
|
496
|
+
tool_call_id: task.toolCallId,
|
|
497
|
+
tool_name: task.toolName,
|
|
498
|
+
agent_id: task.agentId,
|
|
499
|
+
run_id: task.runId,
|
|
500
|
+
thread_id: task.threadId ?? null,
|
|
501
|
+
resource_id: task.resourceId ?? null,
|
|
502
|
+
args: serializeRequiredJson(task.args),
|
|
392
503
|
result: serializeJson(task.result),
|
|
393
504
|
error: serializeJson(task.error),
|
|
394
|
-
|
|
505
|
+
suspend_payload: serializeJson(task.suspendPayload),
|
|
506
|
+
retry_count: task.retryCount,
|
|
507
|
+
max_retries: task.maxRetries,
|
|
508
|
+
timeout_ms: task.timeoutMs,
|
|
395
509
|
createdAt: task.createdAt.toISOString(),
|
|
396
|
-
startedAt: task.startedAt?.toISOString(),
|
|
397
|
-
suspendedAt: task.suspendedAt?.toISOString(),
|
|
398
|
-
completedAt: task.completedAt?.toISOString()
|
|
510
|
+
startedAt: task.startedAt?.toISOString() ?? null,
|
|
511
|
+
suspendedAt: task.suspendedAt?.toISOString() ?? null,
|
|
512
|
+
completedAt: task.completedAt?.toISOString() ?? null
|
|
399
513
|
};
|
|
400
514
|
}
|
|
515
|
+
function toStoredPatch(update) {
|
|
516
|
+
const patch = {};
|
|
517
|
+
if (update.status !== void 0) patch.status = update.status;
|
|
518
|
+
if ("result" in update) patch.result = serializeJson(update.result);
|
|
519
|
+
if ("error" in update) patch.error = serializeJson(update.error);
|
|
520
|
+
if ("suspendPayload" in update) patch.suspend_payload = serializeJson(update.suspendPayload);
|
|
521
|
+
if (update.retryCount !== void 0) patch.retry_count = update.retryCount;
|
|
522
|
+
if (update.maxRetries !== void 0) patch.max_retries = update.maxRetries;
|
|
523
|
+
if (update.timeoutMs !== void 0) patch.timeout_ms = update.timeoutMs;
|
|
524
|
+
if ("startedAt" in update) patch.startedAt = update.startedAt?.toISOString() ?? null;
|
|
525
|
+
if ("suspendedAt" in update) patch.suspendedAt = update.suspendedAt?.toISOString() ?? null;
|
|
526
|
+
if ("completedAt" in update) patch.completedAt = update.completedAt?.toISOString() ?? null;
|
|
527
|
+
return patch;
|
|
528
|
+
}
|
|
529
|
+
function legacyOrCurrent(stored, currentKey, legacyKey) {
|
|
530
|
+
return currentKey in stored ? stored[currentKey] : stored[legacyKey];
|
|
531
|
+
}
|
|
401
532
|
function fromStored(stored) {
|
|
402
|
-
const
|
|
403
|
-
|
|
533
|
+
const record = stored;
|
|
534
|
+
const parseJson3 = (val) => {
|
|
535
|
+
if (val == null) return void 0;
|
|
404
536
|
try {
|
|
405
537
|
return JSON.parse(val);
|
|
406
538
|
} catch {
|
|
@@ -408,27 +540,32 @@ function fromStored(stored) {
|
|
|
408
540
|
}
|
|
409
541
|
};
|
|
410
542
|
return {
|
|
411
|
-
id:
|
|
412
|
-
status:
|
|
413
|
-
toolName:
|
|
414
|
-
toolCallId:
|
|
415
|
-
args:
|
|
416
|
-
agentId:
|
|
417
|
-
threadId:
|
|
418
|
-
resourceId:
|
|
419
|
-
runId:
|
|
420
|
-
result:
|
|
421
|
-
error:
|
|
422
|
-
suspendPayload:
|
|
423
|
-
retryCount:
|
|
424
|
-
maxRetries:
|
|
425
|
-
timeoutMs:
|
|
426
|
-
createdAt: new Date(
|
|
427
|
-
startedAt:
|
|
428
|
-
suspendedAt:
|
|
429
|
-
completedAt:
|
|
543
|
+
id: record.id,
|
|
544
|
+
status: record.status,
|
|
545
|
+
toolName: legacyOrCurrent(record, "tool_name", "toolName"),
|
|
546
|
+
toolCallId: legacyOrCurrent(record, "tool_call_id", "toolCallId"),
|
|
547
|
+
args: parseJson3(record.args) ?? {},
|
|
548
|
+
agentId: legacyOrCurrent(record, "agent_id", "agentId"),
|
|
549
|
+
threadId: legacyOrCurrent(record, "thread_id", "threadId") ?? void 0,
|
|
550
|
+
resourceId: legacyOrCurrent(record, "resource_id", "resourceId") ?? void 0,
|
|
551
|
+
runId: legacyOrCurrent(record, "run_id", "runId"),
|
|
552
|
+
result: parseJson3(record.result),
|
|
553
|
+
error: parseJson3(record.error),
|
|
554
|
+
suspendPayload: parseJson3(legacyOrCurrent(record, "suspend_payload", "suspendPayload")),
|
|
555
|
+
retryCount: legacyOrCurrent(record, "retry_count", "retryCount"),
|
|
556
|
+
maxRetries: legacyOrCurrent(record, "max_retries", "maxRetries"),
|
|
557
|
+
timeoutMs: legacyOrCurrent(record, "timeout_ms", "timeoutMs"),
|
|
558
|
+
createdAt: new Date(record.createdAt),
|
|
559
|
+
startedAt: record.startedAt ? new Date(record.startedAt) : void 0,
|
|
560
|
+
suspendedAt: record.suspendedAt ? new Date(record.suspendedAt) : void 0,
|
|
561
|
+
completedAt: record.completedAt ? new Date(record.completedAt) : void 0
|
|
430
562
|
};
|
|
431
563
|
}
|
|
564
|
+
function hasDeleteFilter(filter) {
|
|
565
|
+
return Boolean(
|
|
566
|
+
(Array.isArray(filter.status) ? filter.status.length > 0 : filter.status) || filter.agentId || filter.threadId || filter.resourceId || filter.toolName || filter.toolCallId || filter.runId || filter.fromDate || filter.toDate
|
|
567
|
+
);
|
|
568
|
+
}
|
|
432
569
|
var BackgroundTasksConvex = class extends BackgroundTasksStorage {
|
|
433
570
|
#db;
|
|
434
571
|
constructor(config) {
|
|
@@ -443,26 +580,34 @@ var BackgroundTasksConvex = class extends BackgroundTasksStorage {
|
|
|
443
580
|
await this.#db.insert({ tableName: TABLE_BACKGROUND_TASKS, record: toStored(task) });
|
|
444
581
|
}
|
|
445
582
|
async updateTask(taskId, update) {
|
|
446
|
-
const
|
|
447
|
-
if (
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
if ("retryCount" in update) merged.retryCount = update.retryCount;
|
|
454
|
-
if ("startedAt" in update) merged.startedAt = update.startedAt;
|
|
455
|
-
if ("suspendedAt" in update) merged.suspendedAt = update.suspendedAt;
|
|
456
|
-
if ("completedAt" in update) merged.completedAt = update.completedAt;
|
|
457
|
-
await this.#db.deleteMany(TABLE_BACKGROUND_TASKS, [taskId]);
|
|
458
|
-
await this.#db.insert({ tableName: TABLE_BACKGROUND_TASKS, record: toStored(merged) });
|
|
583
|
+
const patch = toStoredPatch(update);
|
|
584
|
+
if (Object.keys(patch).length === 0) return;
|
|
585
|
+
await this.#db.patch({
|
|
586
|
+
tableName: TABLE_BACKGROUND_TASKS,
|
|
587
|
+
id: taskId,
|
|
588
|
+
record: patch
|
|
589
|
+
});
|
|
459
590
|
}
|
|
460
591
|
async getTask(taskId) {
|
|
461
592
|
const data = await this.#db.load({ tableName: TABLE_BACKGROUND_TASKS, keys: { id: taskId } });
|
|
462
593
|
return data ? fromStored(data) : null;
|
|
463
594
|
}
|
|
464
595
|
async listTasks(filter) {
|
|
465
|
-
const
|
|
596
|
+
const queryFilters = [];
|
|
597
|
+
if (typeof filter.status === "string") queryFilters.push({ field: "status", value: filter.status });
|
|
598
|
+
if (Array.isArray(filter.status) && filter.status.length === 1) {
|
|
599
|
+
queryFilters.push({ field: "status", value: filter.status[0] });
|
|
600
|
+
}
|
|
601
|
+
if (filter.agentId) queryFilters.push({ field: "agent_id", value: filter.agentId });
|
|
602
|
+
if (filter.threadId) queryFilters.push({ field: "thread_id", value: filter.threadId });
|
|
603
|
+
if (filter.resourceId) queryFilters.push({ field: "resource_id", value: filter.resourceId });
|
|
604
|
+
if (filter.toolName) queryFilters.push({ field: "tool_name", value: filter.toolName });
|
|
605
|
+
if (filter.toolCallId) queryFilters.push({ field: "tool_call_id", value: filter.toolCallId });
|
|
606
|
+
if (filter.runId) queryFilters.push({ field: "run_id", value: filter.runId });
|
|
607
|
+
const all = await this.#db.queryTable(
|
|
608
|
+
TABLE_BACKGROUND_TASKS,
|
|
609
|
+
queryFilters.length > 0 ? queryFilters : void 0
|
|
610
|
+
);
|
|
466
611
|
let tasks = all.map(fromStored);
|
|
467
612
|
if (filter.status) {
|
|
468
613
|
const s = Array.isArray(filter.status) ? filter.status : [filter.status];
|
|
@@ -470,6 +615,7 @@ var BackgroundTasksConvex = class extends BackgroundTasksStorage {
|
|
|
470
615
|
}
|
|
471
616
|
if (filter.agentId) tasks = tasks.filter((t) => t.agentId === filter.agentId);
|
|
472
617
|
if (filter.threadId) tasks = tasks.filter((t) => t.threadId === filter.threadId);
|
|
618
|
+
if (filter.resourceId) tasks = tasks.filter((t) => t.resourceId === filter.resourceId);
|
|
473
619
|
if (filter.toolName) tasks = tasks.filter((t) => t.toolName === filter.toolName);
|
|
474
620
|
if (filter.toolCallId) tasks = tasks.filter((t) => t.toolCallId === filter.toolCallId);
|
|
475
621
|
if (filter.runId) tasks = tasks.filter((t) => t.runId === filter.runId);
|
|
@@ -502,6 +648,7 @@ var BackgroundTasksConvex = class extends BackgroundTasksStorage {
|
|
|
502
648
|
await this.#db.deleteMany(TABLE_BACKGROUND_TASKS, [taskId]);
|
|
503
649
|
}
|
|
504
650
|
async deleteTasks(filter) {
|
|
651
|
+
if (!hasDeleteFilter(filter)) return;
|
|
505
652
|
const { tasks } = await this.listTasks(filter);
|
|
506
653
|
const taskIds = tasks.map((t) => t.id);
|
|
507
654
|
await this.#db.deleteMany(TABLE_BACKGROUND_TASKS, taskIds);
|
|
@@ -515,6 +662,141 @@ var BackgroundTasksConvex = class extends BackgroundTasksStorage {
|
|
|
515
662
|
return total;
|
|
516
663
|
}
|
|
517
664
|
};
|
|
665
|
+
var statusPriority = {
|
|
666
|
+
active: 0,
|
|
667
|
+
pending: 1,
|
|
668
|
+
error: 2
|
|
669
|
+
};
|
|
670
|
+
function stringifyJson(value) {
|
|
671
|
+
return JSON.stringify(value);
|
|
672
|
+
}
|
|
673
|
+
function parseJson(value, context) {
|
|
674
|
+
try {
|
|
675
|
+
return JSON.parse(value);
|
|
676
|
+
} catch (error) {
|
|
677
|
+
throw new Error(`Invalid channel data JSON for ${context}`, { cause: error });
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
function installationToRecord(installation, existingRecord) {
|
|
681
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
682
|
+
return {
|
|
683
|
+
id: installation.id,
|
|
684
|
+
platform: installation.platform,
|
|
685
|
+
agentId: installation.agentId,
|
|
686
|
+
status: installation.status,
|
|
687
|
+
webhookId: installation.webhookId ?? null,
|
|
688
|
+
data: stringifyJson(installation.data),
|
|
689
|
+
configHash: installation.configHash ?? null,
|
|
690
|
+
error: installation.error ?? null,
|
|
691
|
+
createdAt: existingRecord?.createdAt ?? installation.createdAt?.toISOString() ?? now,
|
|
692
|
+
updatedAt: now
|
|
693
|
+
};
|
|
694
|
+
}
|
|
695
|
+
function recordToInstallation(record) {
|
|
696
|
+
return {
|
|
697
|
+
id: record.id,
|
|
698
|
+
platform: record.platform,
|
|
699
|
+
agentId: record.agentId,
|
|
700
|
+
status: record.status,
|
|
701
|
+
webhookId: record.webhookId ?? void 0,
|
|
702
|
+
data: parseJson(record.data, `installation ${record.id}`),
|
|
703
|
+
configHash: record.configHash ?? void 0,
|
|
704
|
+
error: record.error ?? void 0,
|
|
705
|
+
createdAt: new Date(record.createdAt),
|
|
706
|
+
updatedAt: new Date(record.updatedAt)
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
function configToRecord(config) {
|
|
710
|
+
return {
|
|
711
|
+
id: config.platform,
|
|
712
|
+
platform: config.platform,
|
|
713
|
+
data: stringifyJson(config.data),
|
|
714
|
+
updatedAt: config.updatedAt.toISOString()
|
|
715
|
+
};
|
|
716
|
+
}
|
|
717
|
+
function recordToConfig(record) {
|
|
718
|
+
return {
|
|
719
|
+
platform: record.platform,
|
|
720
|
+
data: parseJson(record.data, `config ${record.platform}`),
|
|
721
|
+
updatedAt: new Date(record.updatedAt)
|
|
722
|
+
};
|
|
723
|
+
}
|
|
724
|
+
function sortInstallationsForAgent(a, b) {
|
|
725
|
+
const statusDiff = statusPriority[a.status] - statusPriority[b.status];
|
|
726
|
+
if (statusDiff !== 0) return statusDiff;
|
|
727
|
+
return b.updatedAt.getTime() - a.updatedAt.getTime();
|
|
728
|
+
}
|
|
729
|
+
var ChannelsConvex = class extends ChannelsStorage {
|
|
730
|
+
#db;
|
|
731
|
+
constructor(config) {
|
|
732
|
+
super();
|
|
733
|
+
const client = resolveConvexConfig(config);
|
|
734
|
+
this.#db = new ConvexDB(client);
|
|
735
|
+
}
|
|
736
|
+
async init() {
|
|
737
|
+
}
|
|
738
|
+
async dangerouslyClearAll() {
|
|
739
|
+
await this.#db.clearTable({ tableName: TABLE_CHANNEL_INSTALLATIONS });
|
|
740
|
+
await this.#db.clearTable({ tableName: TABLE_CHANNEL_CONFIG });
|
|
741
|
+
}
|
|
742
|
+
async saveInstallation(installation) {
|
|
743
|
+
const existingRecord = await this.#db.load({
|
|
744
|
+
tableName: TABLE_CHANNEL_INSTALLATIONS,
|
|
745
|
+
keys: { id: installation.id }
|
|
746
|
+
});
|
|
747
|
+
await this.#db.insert({
|
|
748
|
+
tableName: TABLE_CHANNEL_INSTALLATIONS,
|
|
749
|
+
record: installationToRecord(installation, existingRecord)
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
async getInstallation(id) {
|
|
753
|
+
const record = await this.#db.load({
|
|
754
|
+
tableName: TABLE_CHANNEL_INSTALLATIONS,
|
|
755
|
+
keys: { id }
|
|
756
|
+
});
|
|
757
|
+
return record ? recordToInstallation(record) : null;
|
|
758
|
+
}
|
|
759
|
+
async getInstallationByAgent(platform, agentId) {
|
|
760
|
+
const records = await this.#db.queryTable(TABLE_CHANNEL_INSTALLATIONS, [
|
|
761
|
+
{ field: "platform", value: platform },
|
|
762
|
+
{ field: "agentId", value: agentId }
|
|
763
|
+
]);
|
|
764
|
+
const [installation] = records.map(recordToInstallation).sort(sortInstallationsForAgent);
|
|
765
|
+
return installation ?? null;
|
|
766
|
+
}
|
|
767
|
+
async getInstallationByWebhookId(webhookId) {
|
|
768
|
+
const records = await this.#db.queryTable(TABLE_CHANNEL_INSTALLATIONS, [
|
|
769
|
+
{ field: "webhookId", value: webhookId }
|
|
770
|
+
]);
|
|
771
|
+
const [installation] = records.map(recordToInstallation).sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime());
|
|
772
|
+
return installation ?? null;
|
|
773
|
+
}
|
|
774
|
+
async listInstallations(platform) {
|
|
775
|
+
const records = await this.#db.queryTable(TABLE_CHANNEL_INSTALLATIONS, [
|
|
776
|
+
{ field: "platform", value: platform }
|
|
777
|
+
]);
|
|
778
|
+
return records.map(recordToInstallation).sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
779
|
+
}
|
|
780
|
+
async deleteInstallation(id) {
|
|
781
|
+
await this.#db.deleteMany(TABLE_CHANNEL_INSTALLATIONS, [id]);
|
|
782
|
+
}
|
|
783
|
+
async saveConfig(config) {
|
|
784
|
+
await this.#db.insert({
|
|
785
|
+
tableName: TABLE_CHANNEL_CONFIG,
|
|
786
|
+
record: configToRecord(config)
|
|
787
|
+
});
|
|
788
|
+
}
|
|
789
|
+
async getConfig(platform) {
|
|
790
|
+
const record = await this.#db.load({
|
|
791
|
+
tableName: TABLE_CHANNEL_CONFIG,
|
|
792
|
+
keys: { id: platform }
|
|
793
|
+
});
|
|
794
|
+
return record ? recordToConfig(record) : null;
|
|
795
|
+
}
|
|
796
|
+
async deleteConfig(platform) {
|
|
797
|
+
await this.#db.deleteMany(TABLE_CHANNEL_CONFIG, [platform]);
|
|
798
|
+
}
|
|
799
|
+
};
|
|
518
800
|
var MemoryConvex = class extends MemoryStorage {
|
|
519
801
|
#db;
|
|
520
802
|
constructor(config) {
|
|
@@ -1000,6 +1282,247 @@ var MemoryConvex = class extends MemoryStorage {
|
|
|
1000
1282
|
}
|
|
1001
1283
|
}
|
|
1002
1284
|
};
|
|
1285
|
+
var SCHEDULE_LIST_LIMIT = 8e3;
|
|
1286
|
+
function serializeJson2(value) {
|
|
1287
|
+
return JSON.stringify(value);
|
|
1288
|
+
}
|
|
1289
|
+
function parseJson2(value) {
|
|
1290
|
+
if (value == null) return void 0;
|
|
1291
|
+
if (typeof value === "string") {
|
|
1292
|
+
try {
|
|
1293
|
+
return JSON.parse(value);
|
|
1294
|
+
} catch {
|
|
1295
|
+
return value;
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
return value;
|
|
1299
|
+
}
|
|
1300
|
+
function isMissingSchedulesSchemaError(error) {
|
|
1301
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1302
|
+
return /(?:Table|table)\s+(?:["'`])?(?:mastra_schedules|mastra_schedule_triggers)(?:["'`])?\s+(?:is\s+)?(?:not\s+in\s+the\s+schema|not\s+found\s+in\s+schema|not\s+found|does\s+not\s+exist)/i.test(
|
|
1303
|
+
message
|
|
1304
|
+
);
|
|
1305
|
+
}
|
|
1306
|
+
function scheduleToRecord(schedule) {
|
|
1307
|
+
return {
|
|
1308
|
+
id: schedule.id,
|
|
1309
|
+
target: serializeJson2(schedule.target),
|
|
1310
|
+
cron: schedule.cron,
|
|
1311
|
+
timezone: schedule.timezone ?? null,
|
|
1312
|
+
status: schedule.status,
|
|
1313
|
+
next_fire_at: schedule.nextFireAt,
|
|
1314
|
+
last_fire_at: schedule.lastFireAt ?? null,
|
|
1315
|
+
last_run_id: schedule.lastRunId ?? null,
|
|
1316
|
+
created_at: schedule.createdAt,
|
|
1317
|
+
updated_at: schedule.updatedAt,
|
|
1318
|
+
metadata: schedule.metadata == null ? null : serializeJson2(schedule.metadata),
|
|
1319
|
+
owner_type: schedule.ownerType ?? null,
|
|
1320
|
+
owner_id: schedule.ownerId ?? null,
|
|
1321
|
+
workflow_id: schedule.target.type === "workflow" ? schedule.target.workflowId : null
|
|
1322
|
+
};
|
|
1323
|
+
}
|
|
1324
|
+
function recordToSchedule(record) {
|
|
1325
|
+
const target = parseJson2(record.target);
|
|
1326
|
+
if (!target || typeof target !== "object" || typeof target.type !== "string") {
|
|
1327
|
+
throw new Error(`Schedule ${record.id} has invalid target`);
|
|
1328
|
+
}
|
|
1329
|
+
const schedule = {
|
|
1330
|
+
id: String(record.id),
|
|
1331
|
+
target,
|
|
1332
|
+
cron: String(record.cron),
|
|
1333
|
+
status: String(record.status),
|
|
1334
|
+
nextFireAt: Number(record.next_fire_at),
|
|
1335
|
+
createdAt: Number(record.created_at),
|
|
1336
|
+
updatedAt: Number(record.updated_at)
|
|
1337
|
+
};
|
|
1338
|
+
if (record.timezone != null) schedule.timezone = String(record.timezone);
|
|
1339
|
+
if (record.last_fire_at != null) schedule.lastFireAt = Number(record.last_fire_at);
|
|
1340
|
+
if (record.last_run_id != null) schedule.lastRunId = String(record.last_run_id);
|
|
1341
|
+
const metadata = parseJson2(record.metadata);
|
|
1342
|
+
if (metadata != null) schedule.metadata = metadata;
|
|
1343
|
+
if (record.owner_type != null) schedule.ownerType = String(record.owner_type);
|
|
1344
|
+
if (record.owner_id != null) schedule.ownerId = String(record.owner_id);
|
|
1345
|
+
return schedule;
|
|
1346
|
+
}
|
|
1347
|
+
function triggerToRecord(trigger) {
|
|
1348
|
+
return {
|
|
1349
|
+
id: trigger.id ?? crypto.randomUUID(),
|
|
1350
|
+
schedule_id: trigger.scheduleId,
|
|
1351
|
+
run_id: trigger.runId,
|
|
1352
|
+
scheduled_fire_at: trigger.scheduledFireAt,
|
|
1353
|
+
actual_fire_at: trigger.actualFireAt,
|
|
1354
|
+
outcome: trigger.outcome,
|
|
1355
|
+
error: trigger.error ?? null,
|
|
1356
|
+
trigger_kind: trigger.triggerKind ?? "schedule-fire",
|
|
1357
|
+
parent_trigger_id: trigger.parentTriggerId ?? null,
|
|
1358
|
+
metadata: trigger.metadata == null ? null : serializeJson2(trigger.metadata)
|
|
1359
|
+
};
|
|
1360
|
+
}
|
|
1361
|
+
function recordToTrigger(record) {
|
|
1362
|
+
const trigger = {
|
|
1363
|
+
id: record.id != null ? String(record.id) : void 0,
|
|
1364
|
+
scheduleId: String(record.schedule_id),
|
|
1365
|
+
runId: record.run_id != null ? String(record.run_id) : null,
|
|
1366
|
+
scheduledFireAt: Number(record.scheduled_fire_at),
|
|
1367
|
+
actualFireAt: Number(record.actual_fire_at),
|
|
1368
|
+
outcome: String(record.outcome),
|
|
1369
|
+
triggerKind: record.trigger_kind != null ? String(record.trigger_kind) : "schedule-fire"
|
|
1370
|
+
};
|
|
1371
|
+
if (record.error != null) trigger.error = String(record.error);
|
|
1372
|
+
if (record.parent_trigger_id != null) trigger.parentTriggerId = String(record.parent_trigger_id);
|
|
1373
|
+
const metadata = parseJson2(record.metadata);
|
|
1374
|
+
if (metadata != null) trigger.metadata = metadata;
|
|
1375
|
+
return trigger;
|
|
1376
|
+
}
|
|
1377
|
+
var SchedulesConvex = class extends SchedulesStorage {
|
|
1378
|
+
#db;
|
|
1379
|
+
constructor(config) {
|
|
1380
|
+
super();
|
|
1381
|
+
const client = resolveConvexConfig(config);
|
|
1382
|
+
this.#db = new ConvexDB(client);
|
|
1383
|
+
}
|
|
1384
|
+
async init() {
|
|
1385
|
+
}
|
|
1386
|
+
async dangerouslyClearAll() {
|
|
1387
|
+
await this.#db.clearTable({ tableName: TABLE_SCHEDULE_TRIGGERS });
|
|
1388
|
+
await this.#db.clearTable({ tableName: TABLE_SCHEDULES });
|
|
1389
|
+
}
|
|
1390
|
+
async createSchedule(schedule) {
|
|
1391
|
+
await this.#db.createSchedule(scheduleToRecord(schedule));
|
|
1392
|
+
return schedule;
|
|
1393
|
+
}
|
|
1394
|
+
async getSchedule(id) {
|
|
1395
|
+
const record = await this.#db.load({ tableName: TABLE_SCHEDULES, keys: { id } });
|
|
1396
|
+
return record ? recordToSchedule(record) : null;
|
|
1397
|
+
}
|
|
1398
|
+
async listSchedules(filter) {
|
|
1399
|
+
const queryFilters = [];
|
|
1400
|
+
if (filter?.status) queryFilters.push({ field: "status", value: filter.status });
|
|
1401
|
+
if (filter?.ownerType !== void 0 && filter.ownerType !== null) {
|
|
1402
|
+
queryFilters.push({ field: "owner_type", value: filter.ownerType });
|
|
1403
|
+
}
|
|
1404
|
+
if (filter?.ownerType === null) {
|
|
1405
|
+
queryFilters.push({ field: "owner_type", value: null });
|
|
1406
|
+
}
|
|
1407
|
+
if (filter?.ownerId !== void 0 && filter.ownerId !== null) {
|
|
1408
|
+
queryFilters.push({ field: "owner_id", value: filter.ownerId });
|
|
1409
|
+
}
|
|
1410
|
+
if (filter?.ownerId === null) {
|
|
1411
|
+
queryFilters.push({ field: "owner_id", value: null });
|
|
1412
|
+
}
|
|
1413
|
+
if (filter?.workflowId) queryFilters.push({ field: "workflow_id", value: filter.workflowId });
|
|
1414
|
+
let records;
|
|
1415
|
+
try {
|
|
1416
|
+
records = await this.#db.queryTable(
|
|
1417
|
+
TABLE_SCHEDULES,
|
|
1418
|
+
queryFilters.length ? queryFilters : void 0,
|
|
1419
|
+
void 0,
|
|
1420
|
+
SCHEDULE_LIST_LIMIT
|
|
1421
|
+
);
|
|
1422
|
+
} catch (error) {
|
|
1423
|
+
if (isMissingSchedulesSchemaError(error)) {
|
|
1424
|
+
this.logger.warn("Convex schedules schema is not available; returning no schedules", { error });
|
|
1425
|
+
return [];
|
|
1426
|
+
}
|
|
1427
|
+
throw error;
|
|
1428
|
+
}
|
|
1429
|
+
if (records.length >= SCHEDULE_LIST_LIMIT) {
|
|
1430
|
+
this.logger.warn("Convex schedules list reached the adapter limit; results may be truncated", {
|
|
1431
|
+
limit: SCHEDULE_LIST_LIMIT
|
|
1432
|
+
});
|
|
1433
|
+
}
|
|
1434
|
+
let schedules = records.map(recordToSchedule);
|
|
1435
|
+
if (filter?.workflowId) {
|
|
1436
|
+
schedules = schedules.filter(
|
|
1437
|
+
(schedule) => schedule.target.type === "workflow" && schedule.target.workflowId === filter.workflowId
|
|
1438
|
+
);
|
|
1439
|
+
}
|
|
1440
|
+
if (filter?.ownerType === null) {
|
|
1441
|
+
schedules = schedules.filter((schedule) => (schedule.ownerType ?? null) === null);
|
|
1442
|
+
}
|
|
1443
|
+
if (filter?.ownerId === null) {
|
|
1444
|
+
schedules = schedules.filter((schedule) => (schedule.ownerId ?? null) === null);
|
|
1445
|
+
}
|
|
1446
|
+
schedules.sort((a, b) => a.createdAt - b.createdAt);
|
|
1447
|
+
return schedules;
|
|
1448
|
+
}
|
|
1449
|
+
async listDueSchedules(now, limit) {
|
|
1450
|
+
let records;
|
|
1451
|
+
try {
|
|
1452
|
+
records = await this.#db.listDueSchedules(now, limit);
|
|
1453
|
+
} catch (error) {
|
|
1454
|
+
if (isMissingSchedulesSchemaError(error)) {
|
|
1455
|
+
this.logger.warn("Convex schedules schema is not available; returning no due schedules", { error });
|
|
1456
|
+
return [];
|
|
1457
|
+
}
|
|
1458
|
+
throw error;
|
|
1459
|
+
}
|
|
1460
|
+
return records.map(recordToSchedule);
|
|
1461
|
+
}
|
|
1462
|
+
async updateSchedule(id, patch) {
|
|
1463
|
+
const updates = {};
|
|
1464
|
+
if ("cron" in patch && patch.cron !== void 0) {
|
|
1465
|
+
updates.cron = patch.cron;
|
|
1466
|
+
}
|
|
1467
|
+
if ("timezone" in patch) {
|
|
1468
|
+
updates.timezone = patch.timezone ?? null;
|
|
1469
|
+
}
|
|
1470
|
+
if ("status" in patch && patch.status !== void 0) {
|
|
1471
|
+
updates.status = patch.status;
|
|
1472
|
+
}
|
|
1473
|
+
if ("nextFireAt" in patch && patch.nextFireAt !== void 0) {
|
|
1474
|
+
updates.next_fire_at = patch.nextFireAt;
|
|
1475
|
+
}
|
|
1476
|
+
if ("target" in patch && patch.target !== void 0) {
|
|
1477
|
+
updates.target = serializeJson2(patch.target);
|
|
1478
|
+
updates.workflow_id = patch.target.type === "workflow" ? patch.target.workflowId : null;
|
|
1479
|
+
}
|
|
1480
|
+
if ("metadata" in patch) {
|
|
1481
|
+
updates.metadata = patch.metadata == null ? null : serializeJson2(patch.metadata);
|
|
1482
|
+
}
|
|
1483
|
+
if ("ownerType" in patch) {
|
|
1484
|
+
updates.owner_type = patch.ownerType ?? null;
|
|
1485
|
+
}
|
|
1486
|
+
if ("ownerId" in patch) {
|
|
1487
|
+
updates.owner_id = patch.ownerId ?? null;
|
|
1488
|
+
}
|
|
1489
|
+
if (Object.keys(updates).length === 0) {
|
|
1490
|
+
const existing = await this.getSchedule(id);
|
|
1491
|
+
if (!existing) {
|
|
1492
|
+
throw new Error(`Schedule ${id} not found`);
|
|
1493
|
+
}
|
|
1494
|
+
return existing;
|
|
1495
|
+
}
|
|
1496
|
+
updates.updated_at = Date.now();
|
|
1497
|
+
const updated = await this.#db.updateSchedule({ id, patch: updates });
|
|
1498
|
+
return recordToSchedule(updated);
|
|
1499
|
+
}
|
|
1500
|
+
async updateScheduleNextFire(id, expectedNextFireAt, newNextFireAt, lastFireAt, lastRunId) {
|
|
1501
|
+
return this.#db.updateScheduleNextFire({
|
|
1502
|
+
id,
|
|
1503
|
+
expectedNextFireAt,
|
|
1504
|
+
newNextFireAt,
|
|
1505
|
+
lastFireAt,
|
|
1506
|
+
lastRunId
|
|
1507
|
+
});
|
|
1508
|
+
}
|
|
1509
|
+
async deleteSchedule(id) {
|
|
1510
|
+
await this.#db.deleteScheduleTriggers(id);
|
|
1511
|
+
await this.#db.deleteMany(TABLE_SCHEDULES, [id]);
|
|
1512
|
+
}
|
|
1513
|
+
async recordTrigger(trigger) {
|
|
1514
|
+
await this.#db.recordScheduleTrigger(triggerToRecord(trigger));
|
|
1515
|
+
}
|
|
1516
|
+
async listTriggers(scheduleId, opts) {
|
|
1517
|
+
const triggers = await this.#db.listScheduleTriggers({
|
|
1518
|
+
scheduleId,
|
|
1519
|
+
fromActualFireAt: opts?.fromActualFireAt,
|
|
1520
|
+
toActualFireAt: opts?.toActualFireAt,
|
|
1521
|
+
limit: opts?.limit
|
|
1522
|
+
});
|
|
1523
|
+
return triggers.map(recordToTrigger);
|
|
1524
|
+
}
|
|
1525
|
+
};
|
|
1003
1526
|
var ScoresConvex = class extends ScoresStorage {
|
|
1004
1527
|
#db;
|
|
1005
1528
|
constructor(config) {
|
|
@@ -1280,7 +1803,9 @@ var ConvexStore = class extends MastraCompositeStore {
|
|
|
1280
1803
|
memory,
|
|
1281
1804
|
workflows,
|
|
1282
1805
|
scores,
|
|
1283
|
-
backgroundTasks: new BackgroundTasksConvex(domainConfig)
|
|
1806
|
+
backgroundTasks: new BackgroundTasksConvex(domainConfig),
|
|
1807
|
+
schedules: new SchedulesConvex(domainConfig),
|
|
1808
|
+
channels: new ChannelsConvex(domainConfig)
|
|
1284
1809
|
};
|
|
1285
1810
|
}
|
|
1286
1811
|
};
|