@yemi33/minions 0.1.1787 → 0.1.1789
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 +10 -0
- package/dashboard.js +31 -5
- package/engine/copilot-models.json +1 -1
- package/engine/llm.js +1 -1
- package/engine/runtimes/claude.js +3 -0
- package/engine/runtimes/copilot.js +13 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/dashboard.js
CHANGED
|
@@ -1434,6 +1434,21 @@ function _ccRuntimeNeedsResumeCarryover(runtimeName) {
|
|
|
1434
1434
|
}
|
|
1435
1435
|
}
|
|
1436
1436
|
|
|
1437
|
+
const CC_RESUME_BOOKKEEPING_GUARD = [
|
|
1438
|
+
'System note for this resumed Minions Command Center request:',
|
|
1439
|
+
'Some runtimes insert synthetic resume bookkeeping turns such as `Continue from where you left off.` followed by `No response requested.`',
|
|
1440
|
+
'Do not treat those bookkeeping turns as user requests when answering questions about what the user asked or what happened in the conversation.',
|
|
1441
|
+
].join('\n');
|
|
1442
|
+
|
|
1443
|
+
function _ccRuntimeNeedsResumeBookkeepingGuard(runtimeName) {
|
|
1444
|
+
try {
|
|
1445
|
+
const runtime = resolveRuntime(runtimeName);
|
|
1446
|
+
return !!runtime?.capabilities?.resumeBookkeepingTurn;
|
|
1447
|
+
} catch {
|
|
1448
|
+
return false;
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1437
1452
|
function _joinCcPromptParts(...parts) {
|
|
1438
1453
|
return parts.filter(Boolean).join('\n\n---\n\n');
|
|
1439
1454
|
}
|
|
@@ -3058,13 +3073,16 @@ async function ccCall(message, { store = 'cc', sessionKey, extraContext, label =
|
|
|
3058
3073
|
|
|
3059
3074
|
const existing = resolveSession(store, sessionKey);
|
|
3060
3075
|
let sessionId = existing ? existing.sessionId : null;
|
|
3061
|
-
const
|
|
3076
|
+
const currentRuntime = shared.resolveCcCli(CONFIG.engine);
|
|
3077
|
+
const resumeNeedsCarryover = !!sessionId && _ccRuntimeNeedsResumeCarryover(currentRuntime);
|
|
3078
|
+
const resumeNeedsBookkeepingGuard = !!sessionId && _ccRuntimeNeedsResumeBookkeepingGuard(currentRuntime);
|
|
3062
3079
|
const resumeHasOutOfBandCarryover = !!sessionId && _transcriptHasCarryoverContext(transcript, { outOfBandOnly: true, currentMessage: message });
|
|
3063
3080
|
const freshNeedsCarryover = _transcriptHasCarryoverContext(transcript, { currentMessage: message });
|
|
3064
3081
|
|
|
3065
|
-
function buildPrompt({ includePreamble = true, includeCarryover = false, outOfBandOnly = false } = {}) {
|
|
3082
|
+
function buildPrompt({ includePreamble = true, includeCarryover = false, includeResumeGuard = false, outOfBandOnly = false } = {}) {
|
|
3066
3083
|
const parts = (!skipStatePreamble && includePreamble) ? [`## Current Minions State (${new Date().toISOString().slice(0, 16)})\n\n${buildCCStatePreamble()}`] : [];
|
|
3067
3084
|
if (extraContext) parts.push(extraContext);
|
|
3085
|
+
if (includeResumeGuard) parts.push(CC_RESUME_BOOKKEEPING_GUARD);
|
|
3068
3086
|
if (includeCarryover) {
|
|
3069
3087
|
const carryover = _buildTranscriptCarryover(transcript, { currentMessage: message, outOfBandOnly });
|
|
3070
3088
|
if (carryover) parts.push(carryover);
|
|
@@ -3079,6 +3097,7 @@ async function ccCall(message, { store = 'cc', sessionKey, extraContext, label =
|
|
|
3079
3097
|
if (sessionId && maxTurns > 1) {
|
|
3080
3098
|
const p1 = llm.callLLM(buildPrompt({
|
|
3081
3099
|
includePreamble: false,
|
|
3100
|
+
includeResumeGuard: resumeNeedsBookkeepingGuard,
|
|
3082
3101
|
includeCarryover: resumeNeedsCarryover || resumeHasOutOfBandCarryover,
|
|
3083
3102
|
outOfBandOnly: !resumeNeedsCarryover,
|
|
3084
3103
|
}), '', {
|
|
@@ -3165,13 +3184,16 @@ async function ccCallStreaming(message, { store = 'cc', sessionKey, extraContext
|
|
|
3165
3184
|
|
|
3166
3185
|
const existing = resolveSession(store, sessionKey);
|
|
3167
3186
|
let sessionId = existing ? existing.sessionId : null;
|
|
3168
|
-
const
|
|
3187
|
+
const currentRuntime = shared.resolveCcCli(CONFIG.engine);
|
|
3188
|
+
const resumeNeedsCarryover = !!sessionId && _ccRuntimeNeedsResumeCarryover(currentRuntime);
|
|
3189
|
+
const resumeNeedsBookkeepingGuard = !!sessionId && _ccRuntimeNeedsResumeBookkeepingGuard(currentRuntime);
|
|
3169
3190
|
const resumeHasOutOfBandCarryover = !!sessionId && _transcriptHasCarryoverContext(transcript, { outOfBandOnly: true, currentMessage: message });
|
|
3170
3191
|
const freshNeedsCarryover = _transcriptHasCarryoverContext(transcript, { currentMessage: message });
|
|
3171
3192
|
|
|
3172
|
-
function buildPrompt({ includePreamble = true, includeCarryover = false, outOfBandOnly = false } = {}) {
|
|
3193
|
+
function buildPrompt({ includePreamble = true, includeCarryover = false, includeResumeGuard = false, outOfBandOnly = false } = {}) {
|
|
3173
3194
|
const parts = (!skipStatePreamble && includePreamble) ? [`## Current Minions State (${new Date().toISOString().slice(0, 16)})\n\n${buildCCStatePreamble()}`] : [];
|
|
3174
3195
|
if (extraContext) parts.push(extraContext);
|
|
3196
|
+
if (includeResumeGuard) parts.push(CC_RESUME_BOOKKEEPING_GUARD);
|
|
3175
3197
|
if (includeCarryover) {
|
|
3176
3198
|
const carryover = _buildTranscriptCarryover(transcript, { currentMessage: message, outOfBandOnly });
|
|
3177
3199
|
if (carryover) parts.push(carryover);
|
|
@@ -3185,6 +3207,7 @@ async function ccCallStreaming(message, { store = 'cc', sessionKey, extraContext
|
|
|
3185
3207
|
if (sessionId && maxTurns > 1) {
|
|
3186
3208
|
const p1 = llm.callLLMStreaming(buildPrompt({
|
|
3187
3209
|
includePreamble: false,
|
|
3210
|
+
includeResumeGuard: resumeNeedsBookkeepingGuard,
|
|
3188
3211
|
includeCarryover: resumeNeedsCarryover || resumeHasOutOfBandCarryover,
|
|
3189
3212
|
outOfBandOnly: !resumeNeedsCarryover,
|
|
3190
3213
|
}), '', {
|
|
@@ -6708,9 +6731,11 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
6708
6731
|
const wasResume = !!tabSessionId;
|
|
6709
6732
|
const sessionId = tabSessionId || null;
|
|
6710
6733
|
const resumeNeedsCarryover = wasResume && _ccRuntimeNeedsResumeCarryover(currentRuntime);
|
|
6734
|
+
const resumeNeedsBookkeepingGuard = wasResume && _ccRuntimeNeedsResumeBookkeepingGuard(currentRuntime);
|
|
6711
6735
|
const resumeHasOutOfBandCarryover = wasResume && _transcriptHasCarryoverContext(body.transcript, { outOfBandOnly: true, currentMessage: body.message });
|
|
6712
6736
|
const preamble = wasResume ? '' : buildCCStatePreamble();
|
|
6713
6737
|
const includeFullCarryover = sessionReset || resumeNeedsCarryover;
|
|
6738
|
+
const resumeGuard = resumeNeedsBookkeepingGuard ? CC_RESUME_BOOKKEEPING_GUARD : '';
|
|
6714
6739
|
const carryover = (includeFullCarryover || resumeHasOutOfBandCarryover)
|
|
6715
6740
|
? _buildTranscriptCarryover(body.transcript, {
|
|
6716
6741
|
previousRuntime: sessionReset ? previousRuntime : null,
|
|
@@ -6718,7 +6743,7 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
6718
6743
|
outOfBandOnly: !includeFullCarryover,
|
|
6719
6744
|
})
|
|
6720
6745
|
: '';
|
|
6721
|
-
const prompt = _joinCcPromptParts(preamble, carryover, body.message);
|
|
6746
|
+
const prompt = _joinCcPromptParts(preamble, resumeGuard, carryover, body.message);
|
|
6722
6747
|
|
|
6723
6748
|
const { trackEngineUsage: trackUsage } = require('./engine/llm');
|
|
6724
6749
|
const streamModel = CONFIG.engine?.ccModel || shared.ENGINE_DEFAULTS.ccModel;
|
|
@@ -8462,6 +8487,7 @@ module.exports = {
|
|
|
8462
8487
|
_buildTranscriptCarryover,
|
|
8463
8488
|
_transcriptHasCarryoverContext,
|
|
8464
8489
|
_ccRuntimeNeedsResumeCarryover,
|
|
8490
|
+
_ccRuntimeNeedsResumeBookkeepingGuard,
|
|
8465
8491
|
_joinCcPromptParts,
|
|
8466
8492
|
_captureApiRoutesMeta,
|
|
8467
8493
|
_formatCcApiRoutesIndex,
|
package/engine/llm.js
CHANGED
|
@@ -22,7 +22,7 @@ const { resolveRuntime } = require('./runtimes');
|
|
|
22
22
|
|
|
23
23
|
const MINIONS_DIR = shared.MINIONS_DIR;
|
|
24
24
|
const ENGINE_DIR = path.join(MINIONS_DIR, 'engine');
|
|
25
|
-
const COPILOT_TASK_COMPLETE_GRACE_MS =
|
|
25
|
+
const COPILOT_TASK_COMPLETE_GRACE_MS = 15000;
|
|
26
26
|
const MISSING_RUNTIME_EXIT_CODE = 78;
|
|
27
27
|
// When the spawned process emits 'exit' but 'close' is delayed (a detached
|
|
28
28
|
// grandchild inherited stdio), wait this long for trailing stdout data to
|
|
@@ -719,6 +719,9 @@ const capabilities = {
|
|
|
719
719
|
sessionPersistenceControl: true,
|
|
720
720
|
// Claude resume reliably restores prior turns; do not duplicate browser transcript.
|
|
721
721
|
resumePromptCarryover: false,
|
|
722
|
+
// Claude CLI injects a synthetic "Continue from where you left off." meta
|
|
723
|
+
// turn on --resume; CC prompts must tell the model not to treat it as user intent.
|
|
724
|
+
resumeBookkeepingTurn: true,
|
|
722
725
|
// Adapter implements createStreamConsumer(ctx) — required by llm.js accumulator
|
|
723
726
|
streamConsumer: true,
|
|
724
727
|
};
|
|
@@ -817,11 +817,15 @@ function createStreamConsumer(ctx) {
|
|
|
817
817
|
// inspect...") is progress text only — terminal text comes from non-tool
|
|
818
818
|
// assistant messages or trailing deltas.
|
|
819
819
|
let copilotMessageBuffer = '';
|
|
820
|
+
let terminalText = '';
|
|
820
821
|
|
|
821
822
|
function _captureTaskComplete(summary, success = true) {
|
|
822
823
|
if (typeof summary !== 'string' || !summary) return;
|
|
823
824
|
copilotMessageBuffer = '';
|
|
824
|
-
|
|
825
|
+
if (!terminalText) {
|
|
826
|
+
terminalText = summary;
|
|
827
|
+
ctx.pushText(summary);
|
|
828
|
+
}
|
|
825
829
|
ctx.notifyTaskComplete(summary, success !== false);
|
|
826
830
|
}
|
|
827
831
|
|
|
@@ -830,6 +834,10 @@ function createStreamConsumer(ctx) {
|
|
|
830
834
|
|
|
831
835
|
if (obj.type === 'result' && typeof obj.sessionId === 'string') {
|
|
832
836
|
ctx.setSessionId(obj.sessionId);
|
|
837
|
+
// The result event is the first Copilot event that contains the resumable
|
|
838
|
+
// sessionId. Do not mark the earlier assistant.message as terminal or
|
|
839
|
+
// Minions can resolve before session persistence data is available.
|
|
840
|
+
if (terminalText) ctx.setText(terminalText);
|
|
833
841
|
}
|
|
834
842
|
|
|
835
843
|
if (obj.type === 'session.task_complete') {
|
|
@@ -859,7 +867,10 @@ function createStreamConsumer(ctx) {
|
|
|
859
867
|
// Tool-request narration is progress text only — don't let it become
|
|
860
868
|
// the terminal answer. A non-tool assistant.message overrides any
|
|
861
869
|
// streamed deltas (Copilot's authoritative final text for the turn).
|
|
862
|
-
if (content && !hasTools)
|
|
870
|
+
if (content && !hasTools) {
|
|
871
|
+
terminalText = content;
|
|
872
|
+
ctx.pushText(content);
|
|
873
|
+
}
|
|
863
874
|
copilotMessageBuffer = '';
|
|
864
875
|
}
|
|
865
876
|
if (Array.isArray(data.toolRequests)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1789",
|
|
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"
|