@yemi33/minions 0.1.1905 → 0.1.1906
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/engine/copilot-models.json +5 -0
- package/engine/lifecycle.js +34 -8
- package/engine.js +17 -10
- package/package.json +1 -1
package/engine/lifecycle.js
CHANGED
|
@@ -1847,15 +1847,32 @@ function recordPrNoOpFixAttempt(target, cause, source, dispatchItem, branchChang
|
|
|
1847
1847
|
// filter can short-circuit duplicate build-fix dispatches against an
|
|
1848
1848
|
// unchanged commit. Reset happens implicitly when headSha advances and the
|
|
1849
1849
|
// discovery filter compares lastDispatchHeadSha to the current head.
|
|
1850
|
+
//
|
|
1851
|
+
// Tracking is partitioned by cause (`_lastDispatchByCause[cause]`) so a
|
|
1852
|
+
// human-feedback noop on head X never suppresses an unrelated build-failure
|
|
1853
|
+
// dispatch on head X (the PR-wide top-level fields would, see
|
|
1854
|
+
// W-mp2vohea00112739). The legacy top-level fields are kept in sync for
|
|
1855
|
+
// any external consumer (dashboards, debugging) but the build-fix
|
|
1856
|
+
// eligibility filter reads ONLY the per-cause map.
|
|
1850
1857
|
const headSha = getPrFixBaselineHead(target);
|
|
1851
|
-
|
|
1852
|
-
target.lastDispatchOutcome = 'noop';
|
|
1853
|
-
target.lastDispatchHeadSha = headSha;
|
|
1854
|
-
target.lastDispatchReason = String(
|
|
1858
|
+
const reasonText = String(
|
|
1855
1859
|
noopReason
|
|
1856
1860
|
|| branchChange?.reason
|
|
1857
1861
|
|| 'fix completed without changing the PR branch'
|
|
1858
1862
|
).slice(0, 500);
|
|
1863
|
+
target._lastDispatchByCause = target._lastDispatchByCause
|
|
1864
|
+
&& typeof target._lastDispatchByCause === 'object' ? target._lastDispatchByCause : {};
|
|
1865
|
+
target._lastDispatchByCause[cause] = {
|
|
1866
|
+
outcome: 'noop',
|
|
1867
|
+
headSha,
|
|
1868
|
+
reason: reasonText,
|
|
1869
|
+
dispatchedAt: now,
|
|
1870
|
+
dispatchId: dispatchItem?.id || null,
|
|
1871
|
+
};
|
|
1872
|
+
target.lastDispatchedAt = now;
|
|
1873
|
+
target.lastDispatchOutcome = 'noop';
|
|
1874
|
+
target.lastDispatchHeadSha = headSha;
|
|
1875
|
+
target.lastDispatchReason = reasonText;
|
|
1859
1876
|
|
|
1860
1877
|
if (cause === shared.PR_FIX_CAUSE.HUMAN_FEEDBACK && target.humanFeedback) {
|
|
1861
1878
|
target.humanFeedback.pendingFix = !paused;
|
|
@@ -1877,10 +1894,19 @@ function clearPrNoOpFixAttempt(target, cause) {
|
|
|
1877
1894
|
// the same head; once the agent actually pushed a fix we no longer want them
|
|
1878
1895
|
// to suppress a fresh dispatch (the SHA may have moved or the next failure
|
|
1879
1896
|
// is genuinely new).
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1897
|
+
if (target._lastDispatchByCause && typeof target._lastDispatchByCause === 'object') {
|
|
1898
|
+
delete target._lastDispatchByCause[cause];
|
|
1899
|
+
if (Object.keys(target._lastDispatchByCause).length === 0) delete target._lastDispatchByCause;
|
|
1900
|
+
}
|
|
1901
|
+
// Only clear the legacy top-level fields when no other cause still has a
|
|
1902
|
+
// tracked noop — otherwise a successful fix for cause A would silently wipe
|
|
1903
|
+
// out the same-head suppression record for unrelated cause B.
|
|
1904
|
+
if (!target._lastDispatchByCause) {
|
|
1905
|
+
delete target.lastDispatchedAt;
|
|
1906
|
+
delete target.lastDispatchOutcome;
|
|
1907
|
+
delete target.lastDispatchHeadSha;
|
|
1908
|
+
delete target.lastDispatchReason;
|
|
1909
|
+
}
|
|
1884
1910
|
}
|
|
1885
1911
|
|
|
1886
1912
|
function updatePrAfterFix(pr, project, source, options = {}, legacyDispatchId = '') {
|
package/engine.js
CHANGED
|
@@ -2971,18 +2971,25 @@ async function discoverFromPrs(config, project) {
|
|
|
2971
2971
|
const autoFixBuilds = config.engine?.autoFixBuilds ?? ENGINE_DEFAULTS.autoFixBuilds;
|
|
2972
2972
|
if (pollEnabled && autoFixBuilds && pr.status === PR_STATUS.ACTIVE && pr.buildStatus === 'failing'
|
|
2973
2973
|
&& !isPrNoOpFixCauseSuppressed(pr, shared.PR_FIX_CAUSE.BUILD_FAILURE)) {
|
|
2974
|
-
// P-b7e1c4d2: skip when the most recent dispatch already
|
|
2975
|
-
// the same head SHA — chronic across PRs #2315–#2323
|
|
2976
|
-
// agent rebutted "this is a pre-existing master baseline"
|
|
2977
|
-
// cached buildStatus:failing kept re-triggering the loop. The
|
|
2978
|
-
// clears automatically once a new commit lands (
|
|
2979
|
-
// stops matching the current head).
|
|
2974
|
+
// P-b7e1c4d2: skip when the most recent BUILD-FAILURE dispatch already
|
|
2975
|
+
// noop'd against the same head SHA — chronic across PRs #2315–#2323
|
|
2976
|
+
// where every fix agent rebutted "this is a pre-existing master baseline"
|
|
2977
|
+
// but the cached buildStatus:failing kept re-triggering the loop. The
|
|
2978
|
+
// check clears automatically once a new commit lands (the per-cause
|
|
2979
|
+
// headSha stops matching the current head).
|
|
2980
|
+
//
|
|
2981
|
+
// W-mp2vohea00112739: this guard reads `_lastDispatchByCause['build-failure']`
|
|
2982
|
+
// instead of the PR-wide `lastDispatch*` fields. The PR-wide fields are
|
|
2983
|
+
// shared across all causes, so a `human-feedback` noop on head X used to
|
|
2984
|
+
// suppress an unrelated `build-failure` dispatch on the same head until
|
|
2985
|
+
// a new commit landed (live repro on PR #2433).
|
|
2980
2986
|
const currentHeadSha = String(pr.headSha || pr._adoSourceCommit || pr._adoHeadCommit || '').trim();
|
|
2981
|
-
|
|
2982
|
-
|
|
2987
|
+
const lastBuildDispatch = pr._lastDispatchByCause?.[shared.PR_FIX_CAUSE.BUILD_FAILURE];
|
|
2988
|
+
if (lastBuildDispatch?.outcome === 'noop'
|
|
2989
|
+
&& lastBuildDispatch.headSha
|
|
2983
2990
|
&& currentHeadSha
|
|
2984
|
-
&&
|
|
2985
|
-
log('info', `Skipping build-fix for ${pr.id}: last dispatch was noop on the same head ${currentHeadSha.slice(0, 8)} (${(
|
|
2991
|
+
&& lastBuildDispatch.headSha === currentHeadSha) {
|
|
2992
|
+
log('info', `Skipping build-fix for ${pr.id}: last build-failure dispatch was noop on the same head ${currentHeadSha.slice(0, 8)} (${(lastBuildDispatch.reason || '').slice(0, 120)})`);
|
|
2986
2993
|
continue;
|
|
2987
2994
|
}
|
|
2988
2995
|
const buildCauseKey = getPrAutomationCauseKey('build', pr);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1906",
|
|
4
4
|
"description": "Multi-agent AI dev team that runs from ~/.minions/ — five autonomous agents share a single engine, dashboard, and knowledge base",
|
|
5
5
|
"bin": {
|
|
6
6
|
"minions": "bin/minions.js"
|