@mastra/github-signals 0.2.4 → 0.2.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 +9 -0
- package/dist/index.cjs +47 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +47 -19
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @mastra/github-signals
|
|
2
2
|
|
|
3
|
+
## 0.2.5-alpha.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Fixed GitHub polling so stopping a poll prevents in-flight work from sending notifications or writing subscription state. ([#20593](https://github.com/mastra-ai/mastra/pull/20593))
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [[`cdd5c33`](https://github.com/mastra-ai/mastra/commit/cdd5c33ac6c7118a9f139e6dc0e14e6a8ae31658), [`d7cf7fa`](https://github.com/mastra-ai/mastra/commit/d7cf7fafc1ae1b50bd8462dd0e6c671a8606db93), [`0f9a448`](https://github.com/mastra-ai/mastra/commit/0f9a448502157e59f7b76f24360ad497168f5ef8), [`289f4ce`](https://github.com/mastra-ai/mastra/commit/289f4ce16e3293370440172132c52ee787cbc09f), [`4f16ff8`](https://github.com/mastra-ai/mastra/commit/4f16ff824bf2f9b0ddc93f210477c10c8a4fb1ab), [`1c67d85`](https://github.com/mastra-ai/mastra/commit/1c67d85e9da8285662f4dbbf47e0378c3fee0747), [`ba24be6`](https://github.com/mastra-ai/mastra/commit/ba24be662439c331ab23a600041f93803c89eca8), [`842b5fe`](https://github.com/mastra-ai/mastra/commit/842b5fe22b6a7fa811bd14e48eb9af523ac989f2), [`80bdf3a`](https://github.com/mastra-ai/mastra/commit/80bdf3ae16ade6ff63bde0cb16fa2df8ab7dd4dd), [`9ba1247`](https://github.com/mastra-ai/mastra/commit/9ba12470c77f1c03642d720ce67e517e878f666e), [`fd96298`](https://github.com/mastra-ai/mastra/commit/fd96298a8367622f4ebfcaa97b5b6c1fbbd14564), [`6a84954`](https://github.com/mastra-ai/mastra/commit/6a84954a2667f85b6d59da652dab1bbff007ccb0), [`52d8ef0`](https://github.com/mastra-ai/mastra/commit/52d8ef03801f1deb7ee48532fc4190dd4a33916c), [`cdd5c33`](https://github.com/mastra-ai/mastra/commit/cdd5c33ac6c7118a9f139e6dc0e14e6a8ae31658), [`efd5c81`](https://github.com/mastra-ai/mastra/commit/efd5c81cc25fde3c2ddd86fc1178deb4ec176e19), [`0976933`](https://github.com/mastra-ai/mastra/commit/0976933142333ec78451feef265b68bcb45aa5e7), [`242b945`](https://github.com/mastra-ai/mastra/commit/242b94558777bfbdeb42cbfea84afff0b6ad0633), [`fea5cae`](https://github.com/mastra-ai/mastra/commit/fea5caedc7e2cfea51784a15e015952692027abf), [`4b59f78`](https://github.com/mastra-ai/mastra/commit/4b59f786cbc9a7d1ef07a07517dbd4b96865e99d), [`7010c5d`](https://github.com/mastra-ai/mastra/commit/7010c5d15728bf9c5dfe4fb6b1bf80ce23bf143a)]:
|
|
10
|
+
- @mastra/core@1.58.0-alpha.3
|
|
11
|
+
|
|
3
12
|
## 0.2.4
|
|
4
13
|
|
|
5
14
|
### Patch Changes
|
package/dist/index.cjs
CHANGED
|
@@ -740,6 +740,8 @@ var GithubSignals = class extends _mastra_core_signals.SignalProvider {
|
|
|
740
740
|
#syncClient;
|
|
741
741
|
#repositoryResolver;
|
|
742
742
|
#polling = /* @__PURE__ */ new Map();
|
|
743
|
+
#pollingThreadGenerations = /* @__PURE__ */ new Map();
|
|
744
|
+
#pollingGeneration = 0;
|
|
743
745
|
#permissionCache = /* @__PURE__ */ new Map();
|
|
744
746
|
#agent;
|
|
745
747
|
#agentOptions = {};
|
|
@@ -813,6 +815,7 @@ var GithubSignals = class extends _mastra_core_signals.SignalProvider {
|
|
|
813
815
|
const key = this.#pollingKey(input);
|
|
814
816
|
for (const [pollingKey, state] of this.#polling.entries()) {
|
|
815
817
|
if (pollingKey === key) continue;
|
|
818
|
+
this.#invalidatePollingThread(pollingKey);
|
|
816
819
|
clearInterval(state.timer);
|
|
817
820
|
this.#polling.delete(pollingKey);
|
|
818
821
|
}
|
|
@@ -836,6 +839,7 @@ var GithubSignals = class extends _mastra_core_signals.SignalProvider {
|
|
|
836
839
|
}
|
|
837
840
|
stopPollingForThread(input) {
|
|
838
841
|
const key = this.#pollingKey(input);
|
|
842
|
+
this.#invalidatePollingThread(key);
|
|
839
843
|
const state = this.#polling.get(key);
|
|
840
844
|
if (!state) return;
|
|
841
845
|
clearInterval(state.timer);
|
|
@@ -851,6 +855,8 @@ var GithubSignals = class extends _mastra_core_signals.SignalProvider {
|
|
|
851
855
|
return this.#options.pollIntervalMs ?? 3e5;
|
|
852
856
|
}
|
|
853
857
|
stopAllPolling() {
|
|
858
|
+
this.#pollingGeneration++;
|
|
859
|
+
this.#pollingThreadGenerations.clear();
|
|
854
860
|
for (const state of this.#polling.values()) clearInterval(state.timer);
|
|
855
861
|
this.#polling.clear();
|
|
856
862
|
}
|
|
@@ -1044,6 +1050,9 @@ var GithubSignals = class extends _mastra_core_signals.SignalProvider {
|
|
|
1044
1050
|
#pollingKey(input) {
|
|
1045
1051
|
return `${input.resourceId}:${input.threadId}`;
|
|
1046
1052
|
}
|
|
1053
|
+
#invalidatePollingThread(key) {
|
|
1054
|
+
this.#pollingThreadGenerations.set(key, (this.#pollingThreadGenerations.get(key) ?? 0) + 1);
|
|
1055
|
+
}
|
|
1047
1056
|
#getNotificationAgent(_input) {
|
|
1048
1057
|
if (this.#agent) return this.#agent;
|
|
1049
1058
|
const agentId = _input?.agentId ?? this.#options.agentId;
|
|
@@ -1063,6 +1072,9 @@ var GithubSignals = class extends _mastra_core_signals.SignalProvider {
|
|
|
1063
1072
|
const key = this.#pollingKey(input);
|
|
1064
1073
|
const state = this.#polling.get(key);
|
|
1065
1074
|
if (state?.running) return 0;
|
|
1075
|
+
const generation = this.#pollingGeneration;
|
|
1076
|
+
const threadGeneration = this.#pollingThreadGenerations.get(key) ?? 0;
|
|
1077
|
+
const isCurrentGeneration = () => this.#pollingGeneration === generation && (this.#pollingThreadGenerations.get(key) ?? 0) === threadGeneration;
|
|
1066
1078
|
if (state) state.running = true;
|
|
1067
1079
|
this.#notifyPollingChanged({
|
|
1068
1080
|
threadId: input.threadId,
|
|
@@ -1071,6 +1083,7 @@ var GithubSignals = class extends _mastra_core_signals.SignalProvider {
|
|
|
1071
1083
|
});
|
|
1072
1084
|
try {
|
|
1073
1085
|
const { threadStore, loadedThread } = await this.#loadThread(input);
|
|
1086
|
+
if (!isCurrentGeneration()) return 0;
|
|
1074
1087
|
const githubMetadata = getGithubMetadata(loadedThread.metadata);
|
|
1075
1088
|
if (githubMetadata.subscriptions.length === 0) {
|
|
1076
1089
|
this.stopPollingForThread(input);
|
|
@@ -1087,6 +1100,7 @@ var GithubSignals = class extends _mastra_core_signals.SignalProvider {
|
|
|
1087
1100
|
includeComments: options.includeComments
|
|
1088
1101
|
};
|
|
1089
1102
|
const syncResult = await this.#syncClient.syncPullRequest(syncInput);
|
|
1103
|
+
if (!isCurrentGeneration()) return 0;
|
|
1090
1104
|
let snapshot;
|
|
1091
1105
|
let snapshotError;
|
|
1092
1106
|
if (syncResult.ok) try {
|
|
@@ -1094,7 +1108,9 @@ var GithubSignals = class extends _mastra_core_signals.SignalProvider {
|
|
|
1094
1108
|
} catch (error) {
|
|
1095
1109
|
snapshotError = error instanceof Error ? error.message : String(error);
|
|
1096
1110
|
}
|
|
1097
|
-
if (
|
|
1111
|
+
if (!isCurrentGeneration()) return 0;
|
|
1112
|
+
if (snapshot) snapshot = await this.#filterUnauthorizedLatestComment(subscription.owner, subscription.repo, snapshot, isCurrentGeneration);
|
|
1113
|
+
if (!isCurrentGeneration()) return 0;
|
|
1098
1114
|
const nextSubscription = {
|
|
1099
1115
|
...subscription,
|
|
1100
1116
|
updatedAt: now,
|
|
@@ -1117,15 +1133,17 @@ var GithubSignals = class extends _mastra_core_signals.SignalProvider {
|
|
|
1117
1133
|
const legacyAggregateChanged = previousContentHash && snapshot?.contentHash && previousContentHash !== snapshot.contentHash && !previousThreadContentHash && !previousHeadSha;
|
|
1118
1134
|
const changed = isFirstObservation || syncResult.ok && snapshot && (legacyAggregateChanged || latestCommentChanged || previousThreadContentHash && snapshot.threadContentHash && previousThreadContentHash !== snapshot.threadContentHash && !existingBotCommentEdited || previousHeadSha && snapshot.headSha && previousHeadSha !== snapshot.headSha || subscription.lastObservedState && snapshot.state && subscription.lastObservedState !== snapshot.state || hasMeaningfulMergeableStateChange(subscription.lastObservedMergeableState, snapshot.mergeableState) || subscription.lastObservedCiState && snapshot.ciState && subscription.lastObservedCiState !== snapshot.ciState || subscription.lastObservedReviewStateHash && snapshot.reviewStateHash && subscription.lastObservedReviewStateHash !== snapshot.reviewStateHash);
|
|
1119
1135
|
let shouldKeepSubscription = true;
|
|
1120
|
-
if (changed && snapshot) {
|
|
1136
|
+
if (changed && snapshot && isCurrentGeneration()) {
|
|
1121
1137
|
const notifications = await this.#sendActivityNotifications({
|
|
1122
1138
|
polling: input,
|
|
1123
1139
|
subscription,
|
|
1124
1140
|
snapshot,
|
|
1125
1141
|
previousGithubUpdatedAt,
|
|
1126
1142
|
previousContentHash,
|
|
1127
|
-
latestCommentChanged
|
|
1143
|
+
latestCommentChanged,
|
|
1144
|
+
isCurrentGeneration
|
|
1128
1145
|
});
|
|
1146
|
+
if (!isCurrentGeneration()) return 0;
|
|
1129
1147
|
const primaryNotification = notifications[0];
|
|
1130
1148
|
if (primaryNotification) {
|
|
1131
1149
|
nextSubscription.lastNotificationAt = now;
|
|
@@ -1137,6 +1155,7 @@ var GithubSignals = class extends _mastra_core_signals.SignalProvider {
|
|
|
1137
1155
|
}
|
|
1138
1156
|
if (shouldKeepSubscription) subscriptions.push(nextSubscription);
|
|
1139
1157
|
}
|
|
1158
|
+
if (!isCurrentGeneration()) return 0;
|
|
1140
1159
|
await threadStore.saveThread({ thread: {
|
|
1141
1160
|
...loadedThread,
|
|
1142
1161
|
id: input.threadId,
|
|
@@ -1145,6 +1164,7 @@ var GithubSignals = class extends _mastra_core_signals.SignalProvider {
|
|
|
1145
1164
|
updatedAt: /* @__PURE__ */ new Date(),
|
|
1146
1165
|
metadata: setGithubMetadata(loadedThread.metadata, { subscriptions })
|
|
1147
1166
|
} });
|
|
1167
|
+
if (!isCurrentGeneration()) return 0;
|
|
1148
1168
|
this.#notifySubscriptionsChanged({
|
|
1149
1169
|
threadId: input.threadId,
|
|
1150
1170
|
resourceId: input.resourceId,
|
|
@@ -1152,16 +1172,16 @@ var GithubSignals = class extends _mastra_core_signals.SignalProvider {
|
|
|
1152
1172
|
});
|
|
1153
1173
|
if (subscriptions.length === 0) this.stopPollingForThread(input);
|
|
1154
1174
|
return subscriptions.length;
|
|
1155
|
-
} catch (error) {
|
|
1156
|
-
throw error;
|
|
1157
1175
|
} finally {
|
|
1158
1176
|
const latestState = this.#polling.get(key);
|
|
1159
|
-
if (
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1177
|
+
if (isCurrentGeneration()) {
|
|
1178
|
+
if (latestState) latestState.running = false;
|
|
1179
|
+
this.#notifyPollingChanged({
|
|
1180
|
+
threadId: input.threadId,
|
|
1181
|
+
resourceId: input.resourceId,
|
|
1182
|
+
running: false
|
|
1183
|
+
});
|
|
1184
|
+
}
|
|
1165
1185
|
}
|
|
1166
1186
|
}
|
|
1167
1187
|
#createGithubNotificationInput(input) {
|
|
@@ -1253,18 +1273,19 @@ var GithubSignals = class extends _mastra_core_signals.SignalProvider {
|
|
|
1253
1273
|
dedupeSuffix: `baseline:${input.subscription.lastSubscribeSignalId}`
|
|
1254
1274
|
});
|
|
1255
1275
|
}
|
|
1256
|
-
async #isAuthorizedAuthor(owner, repo, user, metadata = {}) {
|
|
1276
|
+
async #isAuthorizedAuthor(owner, repo, user, metadata = {}, isCurrentGeneration) {
|
|
1257
1277
|
if (!user) return false;
|
|
1258
1278
|
const normalizedUser = user.toLowerCase();
|
|
1259
1279
|
if (metadata.isBot === true || metadata.authorType?.toLowerCase() === "bot" || normalizedUser.endsWith("[bot]")) {
|
|
1260
1280
|
if ((this.#options.ignoredBots ?? []).some((bot) => bot.toLowerCase() === normalizedUser)) return false;
|
|
1261
1281
|
return (this.#options.authorizedBots ?? DEFAULT_AUTHORIZED_BOTS).some((bot) => bot.toLowerCase() === normalizedUser);
|
|
1262
1282
|
}
|
|
1263
|
-
const permission = await this.#loadAuthorPermission(owner, repo, user);
|
|
1283
|
+
const permission = await this.#loadAuthorPermission(owner, repo, user, isCurrentGeneration);
|
|
1284
|
+
if (isCurrentGeneration && !isCurrentGeneration()) return false;
|
|
1264
1285
|
const authorizedPermissions = this.#options.authorizedPermissions ?? DEFAULT_AUTHORIZED_PERMISSIONS;
|
|
1265
1286
|
return !!permission && authorizedPermissions.includes(permission);
|
|
1266
1287
|
}
|
|
1267
|
-
async #filterUnauthorizedLatestComment(owner, repo, snapshot) {
|
|
1288
|
+
async #filterUnauthorizedLatestComment(owner, repo, snapshot, isCurrentGeneration) {
|
|
1268
1289
|
const comments = snapshot.latestComments?.length ? snapshot.latestComments : [{
|
|
1269
1290
|
author: snapshot.latestCommentAuthor,
|
|
1270
1291
|
authorType: snapshot.latestCommentAuthorType,
|
|
@@ -1276,10 +1297,11 @@ var GithubSignals = class extends _mastra_core_signals.SignalProvider {
|
|
|
1276
1297
|
if (!comments.some((comment) => comment.author)) return snapshot;
|
|
1277
1298
|
if (!comments.some((comment) => comment.body || comment.url || comment.updatedAt)) return snapshot;
|
|
1278
1299
|
for (const comment of comments) {
|
|
1300
|
+
if (isCurrentGeneration && !isCurrentGeneration()) return snapshot;
|
|
1279
1301
|
if (!await this.#isAuthorizedAuthor(owner, repo, comment.author, {
|
|
1280
1302
|
authorType: comment.authorType,
|
|
1281
1303
|
isBot: comment.isBot
|
|
1282
|
-
})) continue;
|
|
1304
|
+
}, isCurrentGeneration)) continue;
|
|
1283
1305
|
return {
|
|
1284
1306
|
...snapshot,
|
|
1285
1307
|
latestCommentAuthor: comment.author,
|
|
@@ -1300,7 +1322,7 @@ var GithubSignals = class extends _mastra_core_signals.SignalProvider {
|
|
|
1300
1322
|
latestCommentUpdatedAt: void 0
|
|
1301
1323
|
};
|
|
1302
1324
|
}
|
|
1303
|
-
async #loadAuthorPermission(owner, repo, user) {
|
|
1325
|
+
async #loadAuthorPermission(owner, repo, user, isCurrentGeneration) {
|
|
1304
1326
|
const cacheKey = `${owner}/${repo}:${user.toLowerCase()}`;
|
|
1305
1327
|
const cached = this.#permissionCache.get(cacheKey);
|
|
1306
1328
|
if (cached && cached.expiresAt > Date.now()) return cached.permission;
|
|
@@ -1325,10 +1347,11 @@ var GithubSignals = class extends _mastra_core_signals.SignalProvider {
|
|
|
1325
1347
|
"none"
|
|
1326
1348
|
].includes(raw) ? raw : void 0;
|
|
1327
1349
|
}
|
|
1328
|
-
if (permission) this.#permissionCache.set(cacheKey, {
|
|
1350
|
+
if (permission && (!isCurrentGeneration || isCurrentGeneration())) this.#permissionCache.set(cacheKey, {
|
|
1329
1351
|
permission,
|
|
1330
1352
|
expiresAt: Date.now() + PERMISSION_CACHE_TTL_MS
|
|
1331
1353
|
});
|
|
1354
|
+
if (isCurrentGeneration && !isCurrentGeneration()) return void 0;
|
|
1332
1355
|
return permission;
|
|
1333
1356
|
} catch {
|
|
1334
1357
|
this.#permissionCache.delete(cacheKey);
|
|
@@ -1351,10 +1374,12 @@ var GithubSignals = class extends _mastra_core_signals.SignalProvider {
|
|
|
1351
1374
|
for (const notification of notifications.sort(compareGithubActivityNotifications)) {
|
|
1352
1375
|
if (!notification) continue;
|
|
1353
1376
|
if (AUTHOR_GATED_NOTIFICATION_KINDS.has(notification.kind)) {
|
|
1354
|
-
|
|
1377
|
+
const authorized = await this.#isAuthorizedAuthor(input.subscription.owner, input.subscription.repo, input.snapshot.latestCommentAuthor, {
|
|
1355
1378
|
authorType: input.snapshot.latestCommentAuthorType,
|
|
1356
1379
|
isBot: input.snapshot.latestCommentIsBot
|
|
1357
|
-
})
|
|
1380
|
+
}, input.isCurrentGeneration);
|
|
1381
|
+
if (!input.isCurrentGeneration()) return [];
|
|
1382
|
+
if (!authorized) continue;
|
|
1358
1383
|
}
|
|
1359
1384
|
notificationInputs.push(this.#createGithubNotificationInput({
|
|
1360
1385
|
subscription: input.subscription,
|
|
@@ -1371,11 +1396,14 @@ var GithubSignals = class extends _mastra_core_signals.SignalProvider {
|
|
|
1371
1396
|
resourceId: input.polling.resourceId,
|
|
1372
1397
|
threadId: input.polling.threadId
|
|
1373
1398
|
};
|
|
1399
|
+
if (!input.isCurrentGeneration()) return [];
|
|
1374
1400
|
const streamOptions = await this.#agentOptions.getNotificationStreamOptions?.(target);
|
|
1401
|
+
if (!input.isCurrentGeneration()) return [];
|
|
1375
1402
|
await agent.sendNotificationSignal(notificationInputs, streamOptions ? {
|
|
1376
1403
|
...target,
|
|
1377
1404
|
ifIdle: { streamOptions }
|
|
1378
1405
|
} : target);
|
|
1406
|
+
if (!input.isCurrentGeneration()) return [];
|
|
1379
1407
|
}
|
|
1380
1408
|
return sent;
|
|
1381
1409
|
}
|