@mastra/factory 0.12.0-alpha.0 → 0.12.0-alpha.1
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 +29 -0
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +6 -1
- package/dist/factory.js.map +1 -1
- package/dist/feed-events.d.ts +13 -0
- package/dist/feed-events.d.ts.map +1 -0
- package/dist/feed-events.js +25 -0
- package/dist/feed-events.js.map +1 -0
- package/dist/integrations/github/reconcile-worker.js +1 -1
- package/dist/integrations/issue-reconcile-worker.js +1 -1
- package/dist/integrations/platform/github/event-worker.js +1 -1
- package/dist/integrations/platform/linear/event-worker.js +1 -1
- package/dist/routes/attention-activity.d.ts +24 -0
- package/dist/routes/attention-activity.d.ts.map +1 -0
- package/dist/routes/attention-activity.js +143 -0
- package/dist/routes/attention-activity.js.map +1 -0
- package/dist/routes/attention-providers.d.ts +31 -1
- package/dist/routes/attention-providers.d.ts.map +1 -1
- package/dist/routes/attention-providers.js +4 -4
- package/dist/routes/attention-providers.js.map +1 -1
- package/dist/routes/attention.d.ts.map +1 -1
- package/dist/routes/attention.js +39 -11
- package/dist/routes/attention.js.map +1 -1
- package/dist/storage/domains/comments/activity.d.ts +40 -0
- package/dist/storage/domains/comments/activity.d.ts.map +1 -0
- package/dist/storage/domains/comments/activity.js +94 -0
- package/dist/storage/domains/comments/activity.js.map +1 -0
- package/dist/storage/domains/comments/base.d.ts +13 -1
- package/dist/storage/domains/comments/base.d.ts.map +1 -1
- package/dist/storage/domains/comments/base.js +41 -3
- package/dist/storage/domains/comments/base.js.map +1 -1
- package/dist/storage/domains/comments/domain.d.ts +4 -1
- package/dist/storage/domains/comments/domain.d.ts.map +1 -1
- package/dist/storage/domains/comments/domain.js +17 -5
- package/dist/storage/domains/comments/domain.js.map +1 -1
- package/dist/storage/domains/comments/parse.d.ts +1 -0
- package/dist/storage/domains/comments/parse.d.ts.map +1 -1
- package/dist/storage/domains/comments/parse.js +2 -2
- package/dist/storage/domains/comments/parse.js.map +1 -1
- package/dist/storage/domains/comments/routes.d.ts +2 -0
- package/dist/storage/domains/comments/routes.d.ts.map +1 -1
- package/dist/storage/domains/comments/routes.js +49 -3
- package/dist/storage/domains/comments/routes.js.map +1 -1
- package/dist/storage/domains/comments/schema.d.ts +1 -0
- package/dist/storage/domains/comments/schema.d.ts.map +1 -1
- package/dist/storage/domains/comments/schema.js +45 -1
- package/dist/storage/domains/comments/schema.js.map +1 -1
- package/dist/storage/domains/work-items/base.d.ts +14 -1
- package/dist/storage/domains/work-items/base.d.ts.map +1 -1
- package/dist/storage/domains/work-items/base.js +60 -11
- package/dist/storage/domains/work-items/base.js.map +1 -1
- package/package.json +5 -5
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isTerminalFactoryRuleStage } from "../../../rules/types.js";
|
|
2
|
-
import { WORK_ITEM_COMMENTS_SCHEMA, WORK_ITEM_COMMENT_MENTIONS_SCHEMA } from "../comments/schema.js";
|
|
2
|
+
import { WORK_ITEM_ACTIVITY_SCHEMA, WORK_ITEM_COMMENTS_SCHEMA, WORK_ITEM_COMMENT_MENTIONS_SCHEMA } from "../comments/schema.js";
|
|
3
3
|
import { createHash } from "crypto";
|
|
4
4
|
import { FactoryStorageDomain, UniqueViolationError } from "@mastra/core/storage";
|
|
5
5
|
//#region src/storage/domains/work-items/base.ts
|
|
@@ -70,6 +70,14 @@ function factoryMentionAttentionIdentity(commentId) {
|
|
|
70
70
|
occurrence: 0
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
|
+
/** Collapsed per work item, so the occurrence is what a new comment bumps. */
|
|
74
|
+
function factoryActivityAttentionIdentity(workItemId, occurrence) {
|
|
75
|
+
return {
|
|
76
|
+
kind: "activity",
|
|
77
|
+
sourceId: workItemId,
|
|
78
|
+
occurrence
|
|
79
|
+
};
|
|
80
|
+
}
|
|
73
81
|
function factoryAttentionKey(factoryProjectId, identity) {
|
|
74
82
|
return `factory:${factoryProjectId}:attention:${identity.kind}:${identity.sourceId}:${identity.occurrence}`;
|
|
75
83
|
}
|
|
@@ -644,7 +652,7 @@ function toDeferredDecision(row) {
|
|
|
644
652
|
};
|
|
645
653
|
}
|
|
646
654
|
function attentionReceiptKind(value) {
|
|
647
|
-
if (value === "automation-failed" || value === "mention") return value;
|
|
655
|
+
if (value === "automation-failed" || value === "mention" || value === "activity") return value;
|
|
648
656
|
throw new Error(`Unsupported attention receipt kind '${String(value)}'.`);
|
|
649
657
|
}
|
|
650
658
|
function attentionReceiptState(value) {
|
|
@@ -695,15 +703,25 @@ function toPendingStart(row) {
|
|
|
695
703
|
};
|
|
696
704
|
}
|
|
697
705
|
var WorkItemsStorage = class extends FactoryStorageDomain {
|
|
706
|
+
#attentionChanged = () => {};
|
|
698
707
|
constructor() {
|
|
699
708
|
super("work-items");
|
|
700
709
|
}
|
|
710
|
+
/**
|
|
711
|
+
* Wired once at boot. Every write below that changes what this project's
|
|
712
|
+
* attention list projects announces it here — the one place a new such write
|
|
713
|
+
* has to remember, since clients stop polling while their stream is up.
|
|
714
|
+
*/
|
|
715
|
+
onAttentionChanged(listener) {
|
|
716
|
+
this.#attentionChanged = listener;
|
|
717
|
+
}
|
|
701
718
|
async init() {
|
|
702
719
|
await this.ensureCollections([
|
|
703
720
|
WORK_ITEMS_SCHEMA,
|
|
704
721
|
...FACTORY_GOVERNANCE_SCHEMAS,
|
|
705
722
|
WORK_ITEM_COMMENTS_SCHEMA,
|
|
706
|
-
WORK_ITEM_COMMENT_MENTIONS_SCHEMA
|
|
723
|
+
WORK_ITEM_COMMENT_MENTIONS_SCHEMA,
|
|
724
|
+
WORK_ITEM_ACTIVITY_SCHEMA
|
|
707
725
|
]);
|
|
708
726
|
await this.repairLegacyAttentionState();
|
|
709
727
|
}
|
|
@@ -1282,6 +1300,13 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
|
|
|
1282
1300
|
});
|
|
1283
1301
|
return Boolean(decision) && currentOccurrence;
|
|
1284
1302
|
}
|
|
1303
|
+
if (identity.kind === "activity") return await ops.findOne("work_item_activity", {
|
|
1304
|
+
work_item_id: identity.sourceId,
|
|
1305
|
+
participant_id: userId,
|
|
1306
|
+
org_id: orgId,
|
|
1307
|
+
factory_project_id: factoryProjectId,
|
|
1308
|
+
occurrence: identity.occurrence
|
|
1309
|
+
}) !== null;
|
|
1285
1310
|
if (identity.occurrence !== 0) return false;
|
|
1286
1311
|
if (!await ops.findOne("work_item_comment_mentions", {
|
|
1287
1312
|
comment_id: identity.sourceId,
|
|
@@ -1364,7 +1389,10 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
|
|
|
1364
1389
|
}
|
|
1365
1390
|
async failDeferredDecision(input) {
|
|
1366
1391
|
const row = await this.#failLease("factory_deferred_decisions", input);
|
|
1367
|
-
|
|
1392
|
+
if (!row) return null;
|
|
1393
|
+
const record = toDeferredDecision(row);
|
|
1394
|
+
if (input.terminal) this.#attentionChanged(record);
|
|
1395
|
+
return record;
|
|
1368
1396
|
}
|
|
1369
1397
|
/** Park a claimed effect for human approval; the dispatcher never claims `proposed` rows. */
|
|
1370
1398
|
async proposeDeferredDecision(identity, now) {
|
|
@@ -1384,7 +1412,10 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
|
|
|
1384
1412
|
updated_at: now
|
|
1385
1413
|
};
|
|
1386
1414
|
});
|
|
1387
|
-
|
|
1415
|
+
if (!proposed || !row) return null;
|
|
1416
|
+
const record = toDeferredDecision(row);
|
|
1417
|
+
this.#attentionChanged(record);
|
|
1418
|
+
return record;
|
|
1388
1419
|
}
|
|
1389
1420
|
/**
|
|
1390
1421
|
* Release an approved effect back to the dispatcher; only `proposed` rows are
|
|
@@ -1393,7 +1424,7 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
|
|
|
1393
1424
|
* leaving its follow-up work parked for re-approval.
|
|
1394
1425
|
*/
|
|
1395
1426
|
async approveDeferredDecision(orgId, factoryProjectId, decisionId, now, approvedBy) {
|
|
1396
|
-
|
|
1427
|
+
const approved = await this.storage.withTransaction(async (ops) => {
|
|
1397
1428
|
let settled = false;
|
|
1398
1429
|
const row = await ops.updateAtomic("factory_deferred_decisions", {
|
|
1399
1430
|
id: decisionId,
|
|
@@ -1419,6 +1450,8 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
|
|
|
1419
1450
|
}, (current) => current.autonomy_armed_at ? null : { autonomy_armed_at: now });
|
|
1420
1451
|
return record;
|
|
1421
1452
|
});
|
|
1453
|
+
if (approved) this.#attentionChanged(approved);
|
|
1454
|
+
return approved;
|
|
1422
1455
|
}
|
|
1423
1456
|
/** Retire a proposal nobody wants: `dismissed` is terminal, so the run never happens. */
|
|
1424
1457
|
async dismissDeferredDecision(orgId, factoryProjectId, decisionId, now) {
|
|
@@ -1477,10 +1510,13 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
|
|
|
1477
1510
|
settled = true;
|
|
1478
1511
|
return patch;
|
|
1479
1512
|
});
|
|
1480
|
-
|
|
1513
|
+
if (!settled || !row) return null;
|
|
1514
|
+
const record = toDeferredDecision(row);
|
|
1515
|
+
this.#attentionChanged(record);
|
|
1516
|
+
return record;
|
|
1481
1517
|
}
|
|
1482
1518
|
async #resolveFailedDecision({ orgId, factoryProjectId, decisionId, status, now }) {
|
|
1483
|
-
|
|
1519
|
+
const resolved = await this.storage.withTransaction(async (ops) => {
|
|
1484
1520
|
let resolved = false;
|
|
1485
1521
|
const row = await ops.updateAtomic("factory_deferred_decisions", {
|
|
1486
1522
|
id: decisionId,
|
|
@@ -1504,6 +1540,8 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
|
|
|
1504
1540
|
});
|
|
1505
1541
|
return toDeferredDecision(row);
|
|
1506
1542
|
});
|
|
1543
|
+
if (resolved) this.#attentionChanged(resolved);
|
|
1544
|
+
return resolved;
|
|
1507
1545
|
}
|
|
1508
1546
|
async supersedeTerminalDecisionsForWorkItem(input) {
|
|
1509
1547
|
await this.supersedeDecisionsForWorkItem(input);
|
|
@@ -1560,7 +1598,7 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
|
|
|
1560
1598
|
}
|
|
1561
1599
|
/** Requeue the same idempotent terminal effect; non-failed decisions are never rerun. */
|
|
1562
1600
|
async retryDeferredDecision(orgId, factoryProjectId, decisionId, now) {
|
|
1563
|
-
|
|
1601
|
+
const retriedRecord = await this.storage.withTransaction(async (ops) => {
|
|
1564
1602
|
let retried = false;
|
|
1565
1603
|
const row = await ops.updateAtomic("factory_deferred_decisions", {
|
|
1566
1604
|
id: decisionId,
|
|
@@ -1592,6 +1630,8 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
|
|
|
1592
1630
|
});
|
|
1593
1631
|
return toDeferredDecision(row);
|
|
1594
1632
|
});
|
|
1633
|
+
if (retriedRecord) this.#attentionChanged(retriedRecord);
|
|
1634
|
+
return retriedRecord;
|
|
1595
1635
|
}
|
|
1596
1636
|
/** Resolve exact active agent authority; partial session matches never authorize. */
|
|
1597
1637
|
async findActiveRunBinding(address) {
|
|
@@ -2101,6 +2141,13 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
|
|
|
2101
2141
|
if (comments.length < ATTENTION_RECEIPT_QUERY_BATCH_SIZE) break;
|
|
2102
2142
|
}
|
|
2103
2143
|
await ops.deleteMany("work_item_comment_mentions", where);
|
|
2144
|
+
await ops.deleteMany("factory_attention_receipts", {
|
|
2145
|
+
org_id: orgId,
|
|
2146
|
+
factory_project_id: factoryProjectId,
|
|
2147
|
+
kind: "activity",
|
|
2148
|
+
source_id: workItemId
|
|
2149
|
+
});
|
|
2150
|
+
await ops.deleteMany("work_item_activity", where);
|
|
2104
2151
|
}
|
|
2105
2152
|
async delete({ orgId, id }) {
|
|
2106
2153
|
const candidate = await this.#db.findOne("work_items", {
|
|
@@ -2108,7 +2155,7 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
|
|
|
2108
2155
|
id
|
|
2109
2156
|
});
|
|
2110
2157
|
if (!candidate) return null;
|
|
2111
|
-
|
|
2158
|
+
const removed = await this.#withProjectRelationTransaction(orgId, candidate.factory_project_id, async (ops) => {
|
|
2112
2159
|
const existing = await ops.findOne("work_items", {
|
|
2113
2160
|
org_id: orgId,
|
|
2114
2161
|
id
|
|
@@ -2137,9 +2184,11 @@ var WorkItemsStorage = class extends FactoryStorageDomain {
|
|
|
2137
2184
|
});
|
|
2138
2185
|
return toWorkItem(existing);
|
|
2139
2186
|
});
|
|
2187
|
+
if (removed) this.#attentionChanged(removed);
|
|
2188
|
+
return removed;
|
|
2140
2189
|
}
|
|
2141
2190
|
};
|
|
2142
2191
|
//#endregion
|
|
2143
|
-
export { FACTORY_PULL_REQUEST_RECONCILIATION_KEY, FACTORY_RULE_MATERIALIZATION_KEY, WORK_ITEMS_SCHEMA, WorkItemRelationError, WorkItemsStorage, applyStageTransition, factoryAttentionKey, factoryDecisionAttentionIdentity, factoryDecisionHash, factoryMentionAttentionIdentity, isAgentActor, stampSessions, validateParentRelation };
|
|
2192
|
+
export { FACTORY_PULL_REQUEST_RECONCILIATION_KEY, FACTORY_RULE_MATERIALIZATION_KEY, WORK_ITEMS_SCHEMA, WorkItemRelationError, WorkItemsStorage, applyStageTransition, factoryActivityAttentionIdentity, factoryAttentionKey, factoryDecisionAttentionIdentity, factoryDecisionHash, factoryMentionAttentionIdentity, isAgentActor, stampSessions, validateParentRelation };
|
|
2144
2193
|
|
|
2145
2194
|
//# sourceMappingURL=base.js.map
|