@yemi33/minions 0.1.1928 → 0.1.1929
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/cc-worker-pool.js +30 -9
- package/engine/copilot-models.json +5 -0
- package/engine/features.js +34 -9
- package/package.json +1 -1
package/engine/cc-worker-pool.js
CHANGED
|
@@ -98,6 +98,19 @@ function _hashMcpServers(mcpServers) {
|
|
|
98
98
|
return crypto.createHash('sha256').update(json).digest('hex');
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
// Bug B (issue #2479): `model` and `effort` were stored on the Worker but
|
|
102
|
+
// never forwarded to ACP `session/new`, so any `ccModel` override was silently
|
|
103
|
+
// dropped on the pool path. Build the params object here and only include
|
|
104
|
+
// fields that are defined — sending `model: undefined` would force the daemon
|
|
105
|
+
// onto its built-in default instead of letting it pick whatever the user has
|
|
106
|
+
// configured globally.
|
|
107
|
+
function _buildSessionNewParams({ cwd, mcpServers, model, effort }) {
|
|
108
|
+
const params = { cwd, mcpServers: mcpServers || [] };
|
|
109
|
+
if (model !== undefined && model !== null && model !== '') params.model = model;
|
|
110
|
+
if (effort !== undefined && effort !== null && effort !== '') params.effort = effort;
|
|
111
|
+
return params;
|
|
112
|
+
}
|
|
113
|
+
|
|
101
114
|
class Worker {
|
|
102
115
|
constructor({ tabId, model, effort, mcpServers, mcpServersHash, systemPromptHash, cwd }) {
|
|
103
116
|
this.tabId = tabId;
|
|
@@ -170,7 +183,9 @@ class Worker {
|
|
|
170
183
|
earlyExitPromise,
|
|
171
184
|
]);
|
|
172
185
|
const result = await Promise.race([
|
|
173
|
-
this._call('session/new', {
|
|
186
|
+
this._call('session/new', _buildSessionNewParams({
|
|
187
|
+
cwd: this.cwd, mcpServers: this.mcpServers, model: this.model, effort: this.effort,
|
|
188
|
+
})),
|
|
174
189
|
earlyExitPromise,
|
|
175
190
|
]);
|
|
176
191
|
this.sessionId = result && result.sessionId;
|
|
@@ -344,7 +359,7 @@ class Worker {
|
|
|
344
359
|
this._notify('session/cancel', { sessionId: this.inflight.sessionId });
|
|
345
360
|
}
|
|
346
361
|
|
|
347
|
-
async newSession({ mcpServers, systemPromptHash }) {
|
|
362
|
+
async newSession({ mcpServers, systemPromptHash, model, effort }) {
|
|
348
363
|
// Cancel any inflight before swapping the underlying session.
|
|
349
364
|
if (this.inflight) {
|
|
350
365
|
this.cancel();
|
|
@@ -360,10 +375,15 @@ class Worker {
|
|
|
360
375
|
wait();
|
|
361
376
|
});
|
|
362
377
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
378
|
+
// Bug B (issue #2479): if the caller is rotating the session because the
|
|
379
|
+
// system prompt changed, they may also be passing a fresh model/effort —
|
|
380
|
+
// update bookkeeping BEFORE session/new so the new fields land on the
|
|
381
|
+
// daemon. Falls through to whatever we already had when callers omit them.
|
|
382
|
+
if (model !== undefined) this.model = model;
|
|
383
|
+
if (effort !== undefined) this.effort = effort;
|
|
384
|
+
const result = await this._call('session/new', _buildSessionNewParams({
|
|
385
|
+
cwd: this.cwd, mcpServers: mcpServers || [], model: this.model, effort: this.effort,
|
|
386
|
+
}));
|
|
367
387
|
this.sessionId = result && result.sessionId;
|
|
368
388
|
this.systemPromptHash = systemPromptHash;
|
|
369
389
|
this.firstSystemPromptSent = false;
|
|
@@ -425,9 +445,9 @@ async function getSession({ tabId, model, effort, mcpServers, systemPromptHash,
|
|
|
425
445
|
} else if (worker.systemPromptHash !== systemPromptHash) {
|
|
426
446
|
// System prompt changed → keep the warm process, drop the session
|
|
427
447
|
// and create a fresh one. Saves the ~2.1 s initialize handshake.
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
worker.
|
|
448
|
+
// Pass model/effort so the NEW session picks up any override the
|
|
449
|
+
// caller has rotated in (Bug B / issue #2479).
|
|
450
|
+
await worker.newSession({ mcpServers, systemPromptHash, model, effort });
|
|
431
451
|
worker.lastUsedAt = _internals.now();
|
|
432
452
|
} else {
|
|
433
453
|
// Warm reuse — only update bookkeeping. model/effort changes on a
|
|
@@ -507,6 +527,7 @@ module.exports = {
|
|
|
507
527
|
_internals,
|
|
508
528
|
_tabs,
|
|
509
529
|
_reapIdleTabs,
|
|
530
|
+
_buildSessionNewParams,
|
|
510
531
|
IDLE_REAPER_MS,
|
|
511
532
|
REAPER_INTERVAL_MS,
|
|
512
533
|
};
|
package/engine/features.js
CHANGED
|
@@ -2,27 +2,51 @@
|
|
|
2
2
|
* engine/features.js — Feature flag registry. Recipe in CLAUDE.md → "Feature Flags".
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
// Entry shape: id → { description, default: bool, addedIn?: version, expires?: ISO-date }
|
|
5
|
+
// Entry shape: id → { description, default: bool, addedIn?: version, expires?: ISO-date, requiredCcRuntime?: string }
|
|
6
6
|
//
|
|
7
|
-
//
|
|
7
|
+
// Optional fields:
|
|
8
|
+
// `requiredCcRuntime` (e.g. 'copilot') signals that the flag only takes
|
|
9
|
+
// effect when `resolveCcCli(engine)` matches. The dashboard uses this to
|
|
10
|
+
// render the toggle as disabled with a tooltip when the configured CC
|
|
11
|
+
// runtime is incompatible. Engine code still has to gate explicitly via
|
|
12
|
+
// `isFeatureOn` + a runtime check — `requiredCcRuntime` is a UX hint only.
|
|
13
|
+
//
|
|
14
|
+
// REGISTRY GROWTH POLICY — DO NOT DELETE THE FRAMEWORK.
|
|
8
15
|
//
|
|
9
|
-
// The `FEATURES = {}` literal below is intentional scaffolding, not dead code.
|
|
10
16
|
// The surrounding framework (isFeatureOn, listFeatures, hasFeature, env-var
|
|
11
17
|
// override resolver, expiration timestamps) is load-bearing: dashboard.js
|
|
12
18
|
// boot wires it into /api/features (list), /api/features/toggle, and the
|
|
13
19
|
// `window.MINIONS_FEATURES` client bootstrap. Deleting the registry — even
|
|
14
|
-
//
|
|
20
|
+
// if it became empty — would break dashboard startup and the experimental-flags UI.
|
|
15
21
|
//
|
|
16
22
|
// New flags belong here. Register them in this object instead of removing
|
|
17
|
-
//
|
|
18
|
-
// until then the empty object is the correct, expected shape.
|
|
23
|
+
// entries. Keep at least one entry so the framework remains demonstrably wired.
|
|
19
24
|
//
|
|
20
25
|
// Decision logged in the 2026-05-13 daily architecture & bug review meeting
|
|
21
26
|
// (knowledge/architecture/2026-05-13-ripley-meeting-conclusion-daily-architecture-bug-review-2.md,
|
|
22
|
-
// PR-C, Option B — keep framework, document the
|
|
27
|
+
// PR-C, Option B — keep framework, document the registry).
|
|
23
28
|
const FEATURES = {
|
|
24
|
-
//
|
|
25
|
-
//
|
|
29
|
+
// ccUseWorkerPool — sub-tasks B/C/D of W-mp2w003600196c51 (CC perf).
|
|
30
|
+
// Routes Command Center / doc-chat through engine/cc-worker-pool.js
|
|
31
|
+
// (persistent `copilot --acp` per CC tab) instead of spawning a fresh CLI
|
|
32
|
+
// per turn. Saves ~14 s of cold-start cost. Copilot-only — the pool drives
|
|
33
|
+
// ACP which Claude does not implement.
|
|
34
|
+
//
|
|
35
|
+
// Resolution: `shared.resolveCcUseWorkerPool(engine)` (engine/shared.js)
|
|
36
|
+
// is the canonical predicate every dashboard.js call site uses. Explicit
|
|
37
|
+
// `engine.ccUseWorkerPool` true/false in config wins; otherwise the helper
|
|
38
|
+
// defaults ON for `copilot` and OFF for `claude`. PR #2492 flipped the
|
|
39
|
+
// default ON for copilot; see that PR for the cold-spawn measurements.
|
|
40
|
+
//
|
|
41
|
+
// `requiredCcRuntime: 'copilot'` here is a UX hint — the Settings panel
|
|
42
|
+
// greys out the toggle when the resolved CC runtime mismatches so users
|
|
43
|
+
// see the constraint instead of toggling a no-op.
|
|
44
|
+
'ccUseWorkerPool': {
|
|
45
|
+
description: 'Route Command Center / doc-chat through a persistent `copilot --acp` worker per tab instead of spawning a fresh CLI per turn (~14s cold-start savings). Copilot-only — has no effect when the CC runtime is Claude.',
|
|
46
|
+
default: false,
|
|
47
|
+
addedIn: '0.1.1916',
|
|
48
|
+
requiredCcRuntime: 'copilot',
|
|
49
|
+
},
|
|
26
50
|
};
|
|
27
51
|
|
|
28
52
|
const ENV_TRUTHY = new Set(['1', 'true', 'on', 'yes']);
|
|
@@ -64,6 +88,7 @@ function listFeatures(config, registry = FEATURES) {
|
|
|
64
88
|
addedIn: meta.addedIn || null,
|
|
65
89
|
expires: meta.expires || null,
|
|
66
90
|
expired: expiresAt < now,
|
|
91
|
+
requiredCcRuntime: meta.requiredCcRuntime || null,
|
|
67
92
|
};
|
|
68
93
|
});
|
|
69
94
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1929",
|
|
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"
|