@yemi33/minions 0.1.1912 → 0.1.1914
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/README.md +0 -2
- package/dashboard/js/settings.js +2 -0
- package/dashboard.js +128 -1
- package/docs/pr-review-fix-loop.md +3 -11
- package/engine/cli.js +1 -0
- package/engine/shared.js +1 -0
- package/package.json +1 -1
- package/engine/copilot-models.json +0 -5
package/README.md
CHANGED
|
@@ -565,14 +565,12 @@ Engine behavior is controlled via `config.json`. Key settings:
|
|
|
565
565
|
| `autoDecompose` | true | Auto-decompose `implement:large` items into sub-tasks before dispatch |
|
|
566
566
|
| `autoApprovePlans` | false | Auto-approve PRDs without waiting for human approval |
|
|
567
567
|
| `evalLoop` | true | Auto-dispatch review → fix cycles after implementation completes |
|
|
568
|
-
| `evalMaxIterations` | 3 | Max minion review → fix cycles before pausing minion review automation; human feedback, build fixes, and conflict fixes continue |
|
|
569
568
|
| `evalMaxCost` | null | USD ceiling per work item across all eval iterations (null = no limit) |
|
|
570
569
|
| `meetingRoundTimeout` | 600000 (10min) | Timeout per meeting round before auto-advance |
|
|
571
570
|
| `ccModel` | `sonnet` | Model for Command Center and doc-chat (sonnet/haiku/opus) |
|
|
572
571
|
| `ccEffort` | null | Effort level for CC/doc-chat (null/low/medium/high) |
|
|
573
572
|
| `agentEffort` | null | Override effort level for all agent dispatches |
|
|
574
573
|
| `maxTurnsByType` | `{}` | Per-type max-turns override (e.g., `{"explore": 40, "fix": 100}`) |
|
|
575
|
-
| `maxBuildFixAttempts` | 3 | Max auto-fix dispatches per PR before escalating |
|
|
576
574
|
|
|
577
575
|
Per-type max-turns defaults (when `maxTurnsByType` not set): explore=30, ask=20, review=30, plan=30, decompose=15, plan-to-prd=20, implement=75, fix=75, test=50, verify=100. Configurable from the Settings page.
|
|
578
576
|
|
package/dashboard/js/settings.js
CHANGED
|
@@ -230,6 +230,7 @@ async function openSettings() {
|
|
|
230
230
|
settingsToggle('Copilot: suppress AGENTS.md', 'set-copilotSuppressAgentsMd', e.copilotSuppressAgentsMd !== false, '--no-custom-instructions: stops AGENTS.md auto-load from fighting Minions playbook prompts') +
|
|
231
231
|
settingsToggle('Copilot: reasoning summaries', 'set-copilotReasoningSummaries', !!e.copilotReasoningSummaries, '--enable-reasoning-summaries (Anthropic-family models only)') +
|
|
232
232
|
settingsToggle('Disable model discovery', 'set-disableModelDiscovery', !!e.disableModelDiscovery, 'Skip /api/runtimes/<name>/models REST calls fleet-wide. Settings UI falls back to free-text.') +
|
|
233
|
+
settingsToggle('Use persistent Copilot worker pool (faster CC responses)', 'set-ccUseWorkerPool', !!e.ccUseWorkerPool, 'Experimental — sub-task C of W-mp2w003600196c51 (CC perf). When ON, Command Center routes through engine/cc-worker-pool.js (one persistent `copilot --acp` process per CC tab) instead of spawning a fresh CLI per turn. Saves ~14s of cold-start cost on warm follow-up turns. Engine/agent dispatch path is unchanged. Off by default.') +
|
|
233
234
|
'</div>' +
|
|
234
235
|
'<div style="display:grid;grid-template-columns:1fr 3fr;gap:8px;margin-top:8px">' +
|
|
235
236
|
'<div>' +
|
|
@@ -625,6 +626,7 @@ async function saveSettings() {
|
|
|
625
626
|
copilotReasoningSummaries: !!document.getElementById('set-copilotReasoningSummaries')?.checked,
|
|
626
627
|
maxBudgetUsd: (document.getElementById('set-maxBudgetUsd')?.value ?? '').trim(),
|
|
627
628
|
disableModelDiscovery: !!document.getElementById('set-disableModelDiscovery')?.checked,
|
|
629
|
+
ccUseWorkerPool: !!document.getElementById('set-ccUseWorkerPool')?.checked,
|
|
628
630
|
maxTurnsByType: (function() {
|
|
629
631
|
var mbt = {};
|
|
630
632
|
var types = ['explore', 'ask', 'review', 'implement', 'fix', 'test', 'verify', 'plan', 'decompose'];
|
package/dashboard.js
CHANGED
|
@@ -32,6 +32,7 @@ const dispatchMod = require('./engine/dispatch');
|
|
|
32
32
|
const steering = require('./engine/steering');
|
|
33
33
|
const projectDiscovery = require('./engine/project-discovery');
|
|
34
34
|
const features = require('./engine/features');
|
|
35
|
+
const ccWorkerPool = require('./engine/cc-worker-pool');
|
|
35
36
|
const os = require('os');
|
|
36
37
|
|
|
37
38
|
const { safeRead, safeReadDir, safeWrite, safeJson, safeJsonObj, safeJsonArr, safeJsonNoRestore, safeUnlink, mutateJsonFileLocked, mutateTextFileLocked, mutateControl, mutateCooldowns, mutateWorkItems, getProjects: _getProjects, DONE_STATUSES, WI_STATUS, WORK_TYPE, reopenWorkItem } = shared;
|
|
@@ -5826,6 +5827,18 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
5826
5827
|
const abort = ccInFlightAborts.get(tabId);
|
|
5827
5828
|
if (abort) { try { abort(); } catch {} }
|
|
5828
5829
|
}
|
|
5830
|
+
// Sub-task C of W-mp2w003600196c51: when the worker pool is on, abort
|
|
5831
|
+
// must also fire `session/cancel` on the persistent ACP process so the
|
|
5832
|
+
// remote daemon stops generating into a torn-down session. The pool
|
|
5833
|
+
// exposes cancellation via the SessionHandle returned from getSession;
|
|
5834
|
+
// we don't keep that handle around here, so route through closeTab to
|
|
5835
|
+
// both cancel inflight and tear down the worker (cheaper than tracking
|
|
5836
|
+
// per-tab handles in dashboard state, and matches "tab close" semantics
|
|
5837
|
+
// — if the user explicitly aborted, we don't owe them a warm process).
|
|
5838
|
+
// Off when the flag is off so legacy SIGTERM-only behavior is preserved.
|
|
5839
|
+
if (CONFIG.engine && CONFIG.engine.ccUseWorkerPool) {
|
|
5840
|
+
try { ccWorkerPool.closeTab(tabId); } catch { /* swallow */ }
|
|
5841
|
+
}
|
|
5829
5842
|
_clearCcLiveStream(tabId);
|
|
5830
5843
|
_releaseCCTab(tabId);
|
|
5831
5844
|
return jsonReply(res, 200, { ok: true });
|
|
@@ -5846,6 +5859,11 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
5846
5859
|
const sessions = _filterCcTabSessions(raw);
|
|
5847
5860
|
return sessions.filter(s => s.id !== id);
|
|
5848
5861
|
}, { defaultValue: [] });
|
|
5862
|
+
// Sub-task C of W-mp2w003600196c51: tear down the persistent ACP worker
|
|
5863
|
+
// for this tab so we don't leak a Copilot process after the user closes
|
|
5864
|
+
// the tab. closeTab is a no-op when the pool has no entry for the tabId,
|
|
5865
|
+
// so it's safe to call regardless of whether the flag is on.
|
|
5866
|
+
try { ccWorkerPool.closeTab(id); } catch { /* swallow */ }
|
|
5849
5867
|
return jsonReply(res, 200, { ok: true });
|
|
5850
5868
|
}
|
|
5851
5869
|
|
|
@@ -5875,6 +5893,14 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
5875
5893
|
if (body.sessionId && ccSession._promptHash && ccSession._promptHash !== _ccPromptHash) {
|
|
5876
5894
|
ccSession = { sessionId: null, createdAt: null, lastActiveAt: null, turnCount: 0 };
|
|
5877
5895
|
sessionReset = true;
|
|
5896
|
+
// Sub-task C of W-mp2w003600196c51: drop the persistent ACP worker
|
|
5897
|
+
// for this tab so the next turn rebuilds against the new prompt.
|
|
5898
|
+
// The pool's getSession() handles systemPromptHash deltas via
|
|
5899
|
+
// newSession() (warm-process reuse), but evicting the tab here is
|
|
5900
|
+
// belt-and-suspenders — matches the spec's "call closeTab on
|
|
5901
|
+
// _ccPromptHash change" requirement and matches the way we just
|
|
5902
|
+
// dropped ccSession entirely.
|
|
5903
|
+
try { ccWorkerPool.closeTab(tabId); } catch { /* swallow */ }
|
|
5878
5904
|
}
|
|
5879
5905
|
const wasResume = !!(body.sessionId && body.sessionId === ccSession.sessionId && ccSessionValid());
|
|
5880
5906
|
|
|
@@ -5943,8 +5969,21 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
5943
5969
|
* onChunk/onToolUse shape — only `sessionId` differs (set on
|
|
5944
5970
|
* initial call, undefined on retry). Hoisted to keep the two call sites
|
|
5945
5971
|
* in lock-step.
|
|
5972
|
+
*
|
|
5973
|
+
* Sub-task C of W-mp2w003600196c51 (CC perf): when
|
|
5974
|
+
* `engineConfig.ccUseWorkerPool` is true the call routes through
|
|
5975
|
+
* engine/cc-worker-pool.js (`copilot --acp`, one persistent process per
|
|
5976
|
+
* CC tab) instead of spawning a fresh CLI per turn. The pool path
|
|
5977
|
+
* preserves the existing onChunk/onToolUse/result shape so callers
|
|
5978
|
+
* (handleCommandCenterStream, retry path) need no change. Engine/agent
|
|
5979
|
+
* dispatch path is intentionally NOT routed through the pool; that
|
|
5980
|
+
* lives on the per-dispatch _spawnProcess model in engine.js (regression
|
|
5981
|
+
* test enforces engine.js does not import cc-worker-pool).
|
|
5946
5982
|
*/
|
|
5947
|
-
function _invokeCcStream({ prompt, sessionId, liveState, toolUses, model, effort, maxTurns, engineConfig, systemPrompt = CC_STATIC_SYSTEM_PROMPT }) {
|
|
5983
|
+
function _invokeCcStream({ prompt, sessionId, liveState, toolUses, model, effort, maxTurns, engineConfig, systemPrompt = CC_STATIC_SYSTEM_PROMPT, tabId }) {
|
|
5984
|
+
if (engineConfig && engineConfig.ccUseWorkerPool) {
|
|
5985
|
+
return _invokeCcStreamViaPool({ prompt, liveState, model, effort, engineConfig, systemPrompt, tabId });
|
|
5986
|
+
}
|
|
5948
5987
|
const { callLLMStreaming } = require('./engine/llm');
|
|
5949
5988
|
return callLLMStreaming(prompt, systemPrompt, {
|
|
5950
5989
|
timeout: CC_CALL_TIMEOUT_MS, label: 'command-center', model, maxTurns,
|
|
@@ -5965,6 +6004,87 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
5965
6004
|
});
|
|
5966
6005
|
}
|
|
5967
6006
|
|
|
6007
|
+
/**
|
|
6008
|
+
* Pool-routed implementation of _invokeCcStream. Keeps the public contract
|
|
6009
|
+
* identical: returns a Promise that resolves to a result envelope shaped like
|
|
6010
|
+
* callLLMStreaming's (`{ text, sessionId, code, usage, raw, stderr,
|
|
6011
|
+
* missingRuntime }`) and exposes an `.abort` property so the SSE handler can
|
|
6012
|
+
* cancel the in-flight stream by calling `_ccStreamAbort()`.
|
|
6013
|
+
*
|
|
6014
|
+
* Differences vs the direct path:
|
|
6015
|
+
* - Pool's `onChunk(text)` from agent_message_chunk is a DELTA, but
|
|
6016
|
+
* callLLMStreaming's contract is "full accumulated text"; we accumulate
|
|
6017
|
+
* here so `liveState.text` and downstream chunk events keep the same
|
|
6018
|
+
* semantics consumers already depend on.
|
|
6019
|
+
* - Tool calls are not surfaced in sub-task B (the pool ignores
|
|
6020
|
+
* `tool_call` notifications). `toolUses` stays empty on this path; if
|
|
6021
|
+
* sub-task C/D adds tool_call surfacing in the pool we'll plumb a
|
|
6022
|
+
* callback here too.
|
|
6023
|
+
* - `usage` is reported as an empty object — ACP doesn't expose token
|
|
6024
|
+
* counts in the in-flight session/update notifications, and the pool's
|
|
6025
|
+
* long-lived process makes per-turn usage attribution non-trivial.
|
|
6026
|
+
* trackEngineUsage is a no-op on `{}`.
|
|
6027
|
+
*/
|
|
6028
|
+
function _invokeCcStreamViaPool({ prompt, liveState, model, effort, engineConfig, systemPrompt, tabId }) {
|
|
6029
|
+
const resolvedTabId = tabId || 'default';
|
|
6030
|
+
let cancelled = false;
|
|
6031
|
+
let accumulated = '';
|
|
6032
|
+
let sessionHandle = null;
|
|
6033
|
+
let resolveResult;
|
|
6034
|
+
const promise = new Promise((resolve) => { resolveResult = resolve; });
|
|
6035
|
+
promise.abort = () => {
|
|
6036
|
+
cancelled = true;
|
|
6037
|
+
try { sessionHandle && sessionHandle.cancel(); } catch { /* swallow */ }
|
|
6038
|
+
};
|
|
6039
|
+
(async () => {
|
|
6040
|
+
try {
|
|
6041
|
+
sessionHandle = await ccWorkerPool.getSession({
|
|
6042
|
+
tabId: resolvedTabId,
|
|
6043
|
+
model,
|
|
6044
|
+
effort,
|
|
6045
|
+
mcpServers: (engineConfig && engineConfig.mcpServers) || [],
|
|
6046
|
+
systemPromptHash: _ccPromptHash,
|
|
6047
|
+
});
|
|
6048
|
+
} catch (err) {
|
|
6049
|
+
return resolveResult({
|
|
6050
|
+
text: '',
|
|
6051
|
+
sessionId: null,
|
|
6052
|
+
code: 1,
|
|
6053
|
+
usage: {},
|
|
6054
|
+
raw: '',
|
|
6055
|
+
stderr: String((err && err.message) || err || 'cc-worker-pool spawn failed'),
|
|
6056
|
+
});
|
|
6057
|
+
}
|
|
6058
|
+
if (cancelled) {
|
|
6059
|
+
try { sessionHandle.cancel(); } catch { /* swallow */ }
|
|
6060
|
+
return resolveResult({ text: accumulated, sessionId: sessionHandle.sessionId, code: 0, usage: {}, raw: accumulated, stderr: '' });
|
|
6061
|
+
}
|
|
6062
|
+
await sessionHandle.stream(prompt, {
|
|
6063
|
+
systemPromptText: systemPrompt,
|
|
6064
|
+
onChunk: (delta) => {
|
|
6065
|
+
accumulated += delta;
|
|
6066
|
+
_touchCcLiveStream(liveState);
|
|
6067
|
+
liveState.text = accumulated;
|
|
6068
|
+
if (liveState.writer) liveState.writer({ type: 'chunk', text: accumulated });
|
|
6069
|
+
},
|
|
6070
|
+
onDone: () => {
|
|
6071
|
+
resolveResult({ text: accumulated, sessionId: sessionHandle.sessionId, code: 0, usage: {}, raw: accumulated, stderr: '' });
|
|
6072
|
+
},
|
|
6073
|
+
onError: (err) => {
|
|
6074
|
+
resolveResult({
|
|
6075
|
+
text: accumulated,
|
|
6076
|
+
sessionId: sessionHandle.sessionId,
|
|
6077
|
+
code: cancelled ? 0 : 1,
|
|
6078
|
+
usage: {},
|
|
6079
|
+
raw: accumulated,
|
|
6080
|
+
stderr: String((err && err.message) || err || 'cc-worker-pool stream error'),
|
|
6081
|
+
});
|
|
6082
|
+
},
|
|
6083
|
+
});
|
|
6084
|
+
})();
|
|
6085
|
+
return promise;
|
|
6086
|
+
}
|
|
6087
|
+
|
|
5968
6088
|
async function handleCommandCenterStream(req, res) {
|
|
5969
6089
|
// SSE Origin gate (belt-and-suspenders: the top-level dispatcher has
|
|
5970
6090
|
// already rejected disallowed origins on POST, but validate again here
|
|
@@ -6106,6 +6226,11 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
6106
6226
|
tabSessionId = null;
|
|
6107
6227
|
sessionReset = true;
|
|
6108
6228
|
sessionResetReason = 'promptChanged';
|
|
6229
|
+
// Sub-task C of W-mp2w003600196c51: matched dashboard reload with
|
|
6230
|
+
// a new prompt template — evict the persistent ACP worker so the
|
|
6231
|
+
// next turn rebuilds against the new prompt. (See same hook in
|
|
6232
|
+
// handleCommandCenter above.)
|
|
6233
|
+
try { ccWorkerPool.closeTab(body.tabId || 'default'); } catch { /* swallow */ }
|
|
6109
6234
|
} else if (tabEntry.runtime && tabEntry.runtime !== currentRuntime) {
|
|
6110
6235
|
tabSessionId = null;
|
|
6111
6236
|
sessionReset = true;
|
|
@@ -6149,6 +6274,7 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
6149
6274
|
model: streamModel, effort: streamEffort, maxTurns: ccMaxTurns,
|
|
6150
6275
|
engineConfig: CONFIG.engine,
|
|
6151
6276
|
systemPrompt: turnSystemPrompt,
|
|
6277
|
+
tabId,
|
|
6152
6278
|
});
|
|
6153
6279
|
_ccStreamAbort = llmPromise.abort;
|
|
6154
6280
|
liveState.abortFn = _ccStreamAbort;
|
|
@@ -6174,6 +6300,7 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
6174
6300
|
model: streamModel, effort: streamEffort, maxTurns: ccMaxTurns,
|
|
6175
6301
|
engineConfig: CONFIG.engine,
|
|
6176
6302
|
systemPrompt: turnSystemPrompt,
|
|
6303
|
+
tabId,
|
|
6177
6304
|
});
|
|
6178
6305
|
_ccStreamAbort = retryPromise.abort;
|
|
6179
6306
|
liveState.abortFn = _ccStreamAbort;
|
|
@@ -34,7 +34,7 @@ How the engine manages the lifecycle of a PR from creation through review, fix,
|
|
|
34
34
|
|
|
35
35
|
When multiple problems coexist, earlier triggers get the first chance to enqueue work. The local `fixDispatched` flag is declared before the fix triggers and set after human-feedback, review-feedback, and build-failure dispatches. Conflict fixes run last and explicitly require `!fixDispatched`, so any earlier successful fix dispatch suppresses the conflict fix for that PR in the same discovery pass. Build fixes are evaluated after human and minion review feedback, but the build-fix condition itself is not gated by `!fixDispatched`.
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
The engine does not cap review→fix cycles or build-fix attempts. Each trigger evaluates its own gates on every discovery pass; loops stop only when the underlying condition clears (reviewer approves, build passes, conflict resolves, human feedback handled). Operators who need to halt automation on a runaway PR should disable the relevant feature flag (`evalLoop`, `autoFixBuilds`, `autoFixConflicts`) or close the PR.
|
|
38
38
|
|
|
39
39
|
### A. Human comments (`humanFeedback.pendingFix`)
|
|
40
40
|
|
|
@@ -42,16 +42,14 @@ When multiple problems coexist, earlier triggers get the first chance to enqueue
|
|
|
42
42
|
- Agent comments filtered out via `/\bMinions\s*\(/i` regex on comment body
|
|
43
43
|
- Coalesces multiple comments arriving during cooldown into single fix
|
|
44
44
|
- Routes to author
|
|
45
|
-
- Not gated by `_evalEscalated` — humans can always force more fixes via PR comments even after the minion review loop escalates.
|
|
46
45
|
- Fix agents must treat human comments as claims to verify, not commands. They inspect or reproduce each claimed issue, make the smallest correct fix only when the claim is valid, and otherwise reply with evidence-backed rationale.
|
|
47
46
|
|
|
48
47
|
### B. Review feedback (`changes-requested`)
|
|
49
48
|
|
|
50
|
-
- Gate: `reviewStatus === 'changes-requested'` + `!awaitingReReview` +
|
|
49
|
+
- Gate: `reviewStatus === 'changes-requested'` + `!awaitingReReview` + not dispatched + not on cooldown
|
|
51
50
|
- Routes to PR author via `_author_` routing token
|
|
52
51
|
- `review_note` = reviewer's feedback
|
|
53
52
|
- Sets `fixDispatched = true` — prevents the later conflict fix from also firing this pass
|
|
54
|
-
- **Review-loop escalation**: after `evalMaxIterations` review→fix cycles (default 3), `_evalEscalated` is set on the PR and *only this trigger plus minion review/re-review* stop. Triggers A (human comments), C (build failures), and D (merge conflicts) keep running. The dashboard PR row distinguishes the two states with separate badges (review badge `review-escalated` vs. build badge `build-escalated`).
|
|
55
53
|
- Fix agents validate each requested-change claim before editing. Invalid, stale, already-addressed, out-of-scope, or harmful feedback should get a respectful evidence-backed rebuttal rather than a success-shaped code change.
|
|
56
54
|
|
|
57
55
|
### C. Build failures (`buildStatus === 'failing'`)
|
|
@@ -59,8 +57,6 @@ When multiple problems coexist, earlier triggers get the first chance to enqueue
|
|
|
59
57
|
- Gate: provider polling enabled (`adoPollEnabled` or `ghPollEnabled`) + `autoFixBuilds` + `buildStatus === 'failing'` + grace period expired
|
|
60
58
|
- **Grace period** (`_buildFixPushedAt`): after fix dispatches, waits `buildFixGracePeriod` (default 10min, configurable in `ENGINE_DEFAULTS`) for CI to run before re-dispatching. Cleared when poller detects build status transition (CI actually ran).
|
|
61
59
|
- **Error logs**: GitHub fetches annotations (failures only, not warnings) + Actions job log (always). ADO queries builds API directly (not status checks), fetches build timeline → failed task logs (up to 10 per build, up to 10 failing pipelines).
|
|
62
|
-
- **Build-fix escalation**: after 3 failed attempts, writes an inbox alert, sets `buildFixEscalated = true`, and stops *only this trigger* (auto-dispatch for build fixes). The counter resets when the build recovers. Independent of `_evalEscalated`.
|
|
63
|
-
- Not gated by `_evalEscalated` — build-fix is mechanical and runs even if the review loop has escalated.
|
|
64
60
|
- Sets `fixDispatched = true` after dispatch so the later conflict trigger is suppressed in the same pass.
|
|
65
61
|
|
|
66
62
|
### D. Merge conflicts (`_mergeConflict`)
|
|
@@ -88,7 +84,7 @@ When multiple problems coexist, earlier triggers get the first chance to enqueue
|
|
|
88
84
|
- Fix agent pushes → `_buildFixPushedAt` stamped
|
|
89
85
|
- Poller detects new commit → CI starts → `buildStatus` transitions (`failing` → `running`)
|
|
90
86
|
- `_buildFixPushedAt` cleared on any transition
|
|
91
|
-
- If CI passes → `
|
|
87
|
+
- If CI passes → `buildErrorLog` cleared → done
|
|
92
88
|
- If CI fails again → fresh error logs fetched → new fix dispatches immediately (grace already cleared by transition)
|
|
93
89
|
|
|
94
90
|
## Race prevention
|
|
@@ -125,10 +121,6 @@ When multiple problems coexist, earlier triggers get the first chance to enqueue
|
|
|
125
121
|
| `reviewStatus` | Poller + post-completion | `pending` / `approved` / `changes-requested` / `waiting` |
|
|
126
122
|
| `buildStatus` | Poller | `none` / `passing` / `failing` / `running` |
|
|
127
123
|
| `buildErrorLog` | Poller | Actual CI error output for fix agents |
|
|
128
|
-
| `buildFixAttempts` | Discovery (on dispatch) | Counter for build-fix escalation cap |
|
|
129
|
-
| `buildFixEscalated` | Discovery (on cap) | Stops *build-fix* auto-dispatch only (review/re-review and other fix triggers continue) |
|
|
130
|
-
| `_reviewFixCycles` | Discovery (on dispatch) | Counter for review→fix cycle cap (`evalMaxIterations`) |
|
|
131
|
-
| `_evalEscalated` | Discovery (on cap) | Stops *review/re-review and review-feedback fix* auto-dispatch only (build-fix, conflict-fix, and human-feedback fix continue). Cleared when reviewer eventually approves the PR. |
|
|
132
124
|
| `_buildFixPushedAt` | Discovery (on dispatch) | Grace period timestamp |
|
|
133
125
|
| `_buildFailNotified` | Discovery | Dedup for inbox alert |
|
|
134
126
|
| `lastPushedAt` | Poller (new commit) | Tracks latest push for re-review logic |
|
package/engine/cli.js
CHANGED
|
@@ -992,6 +992,7 @@ const commands = {
|
|
|
992
992
|
'claudeBareMode', 'claudeFallbackModel',
|
|
993
993
|
'copilotDisableBuiltinMcps', 'copilotSuppressAgentsMd', 'copilotStreamMode', 'copilotReasoningSummaries',
|
|
994
994
|
'maxBudgetUsd', 'disableModelDiscovery',
|
|
995
|
+
'ccUseWorkerPool',
|
|
995
996
|
];
|
|
996
997
|
const activeFlags = [];
|
|
997
998
|
for (const f of flagFields) {
|
package/engine/shared.js
CHANGED
|
@@ -1119,6 +1119,7 @@ const ENGINE_DEFAULTS = {
|
|
|
1119
1119
|
copilotSuppressAgentsMd: true, // Copilot --no-custom-instructions: stop AGENTS.md auto-load from fighting Minions playbook prompts
|
|
1120
1120
|
copilotStreamMode: 'on', // Copilot --stream <on|off>: 'on' streams assistant.message_delta events live; 'off' batches them
|
|
1121
1121
|
copilotReasoningSummaries: false, // Copilot --enable-reasoning-summaries (Anthropic-family models only)
|
|
1122
|
+
ccUseWorkerPool: false, // Sub-task C of W-mp2w003600196c51 (CC perf): when true, _invokeCcStream routes through engine/cc-worker-pool.js (persistent `copilot --acp` per CC tab) instead of spawning a fresh CLI per turn. Off by default — opt-in feature flag. Engine/agent dispatch path stays per-process regardless.
|
|
1122
1123
|
maxBudgetUsd: undefined, // fleet USD ceiling for --max-budget-usd (per-agent override: agents.<id>.maxBudgetUsd). Honors 0 via ?? so a literal cap of $0 works
|
|
1123
1124
|
disableModelDiscovery: false, // skip runtime.listModels() REST calls fleet-wide (settings UI falls back to free-text)
|
|
1124
1125
|
maxPendingContexts: 20, // cap pendingContexts arrays in cooldowns.json to prevent unbounded growth
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1914",
|
|
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"
|