@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.
Files changed (52) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/factory.d.ts.map +1 -1
  3. package/dist/factory.js +6 -1
  4. package/dist/factory.js.map +1 -1
  5. package/dist/feed-events.d.ts +13 -0
  6. package/dist/feed-events.d.ts.map +1 -0
  7. package/dist/feed-events.js +25 -0
  8. package/dist/feed-events.js.map +1 -0
  9. package/dist/integrations/github/reconcile-worker.js +1 -1
  10. package/dist/integrations/issue-reconcile-worker.js +1 -1
  11. package/dist/integrations/platform/github/event-worker.js +1 -1
  12. package/dist/integrations/platform/linear/event-worker.js +1 -1
  13. package/dist/routes/attention-activity.d.ts +24 -0
  14. package/dist/routes/attention-activity.d.ts.map +1 -0
  15. package/dist/routes/attention-activity.js +143 -0
  16. package/dist/routes/attention-activity.js.map +1 -0
  17. package/dist/routes/attention-providers.d.ts +31 -1
  18. package/dist/routes/attention-providers.d.ts.map +1 -1
  19. package/dist/routes/attention-providers.js +4 -4
  20. package/dist/routes/attention-providers.js.map +1 -1
  21. package/dist/routes/attention.d.ts.map +1 -1
  22. package/dist/routes/attention.js +39 -11
  23. package/dist/routes/attention.js.map +1 -1
  24. package/dist/storage/domains/comments/activity.d.ts +40 -0
  25. package/dist/storage/domains/comments/activity.d.ts.map +1 -0
  26. package/dist/storage/domains/comments/activity.js +94 -0
  27. package/dist/storage/domains/comments/activity.js.map +1 -0
  28. package/dist/storage/domains/comments/base.d.ts +13 -1
  29. package/dist/storage/domains/comments/base.d.ts.map +1 -1
  30. package/dist/storage/domains/comments/base.js +41 -3
  31. package/dist/storage/domains/comments/base.js.map +1 -1
  32. package/dist/storage/domains/comments/domain.d.ts +4 -1
  33. package/dist/storage/domains/comments/domain.d.ts.map +1 -1
  34. package/dist/storage/domains/comments/domain.js +17 -5
  35. package/dist/storage/domains/comments/domain.js.map +1 -1
  36. package/dist/storage/domains/comments/parse.d.ts +1 -0
  37. package/dist/storage/domains/comments/parse.d.ts.map +1 -1
  38. package/dist/storage/domains/comments/parse.js +2 -2
  39. package/dist/storage/domains/comments/parse.js.map +1 -1
  40. package/dist/storage/domains/comments/routes.d.ts +2 -0
  41. package/dist/storage/domains/comments/routes.d.ts.map +1 -1
  42. package/dist/storage/domains/comments/routes.js +49 -3
  43. package/dist/storage/domains/comments/routes.js.map +1 -1
  44. package/dist/storage/domains/comments/schema.d.ts +1 -0
  45. package/dist/storage/domains/comments/schema.d.ts.map +1 -1
  46. package/dist/storage/domains/comments/schema.js +45 -1
  47. package/dist/storage/domains/comments/schema.js.map +1 -1
  48. package/dist/storage/domains/work-items/base.d.ts +14 -1
  49. package/dist/storage/domains/work-items/base.d.ts.map +1 -1
  50. package/dist/storage/domains/work-items/base.js +60 -11
  51. package/dist/storage/domains/work-items/base.js.map +1 -1
  52. 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
- return row ? toDeferredDecision(row) : null;
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
- return proposed && row ? toDeferredDecision(row) : null;
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
- return this.storage.withTransaction(async (ops) => {
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
- return settled && row ? toDeferredDecision(row) : null;
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
- return this.storage.withTransaction(async (ops) => {
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
- return this.storage.withTransaction(async (ops) => {
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
- return this.#withProjectRelationTransaction(orgId, candidate.factory_project_id, async (ops) => {
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