@yemi33/minions 0.1.924 → 0.1.926
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 +3 -1
- package/dashboard/js/modal-qa.js +3 -0
- package/dashboard.js +16 -5
- package/engine/llm.js +6 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.1.
|
|
3
|
+
## 0.1.926 (2026-04-13)
|
|
4
4
|
|
|
5
5
|
### Features
|
|
6
|
+
- doc-chat abort kills LLM process + queued messages auto-process
|
|
6
7
|
- add /api/work-items/reopen endpoint and reopen-work-item CC action (#982)
|
|
7
8
|
- CC tab unread dot + reopened badge on work items
|
|
8
9
|
- fix dep re-merge failure on retry with existing commits (#977)
|
|
@@ -19,6 +20,7 @@
|
|
|
19
20
|
- add red dot notification on CC tab when response completes (#934) (#946)
|
|
20
21
|
|
|
21
22
|
### Fixes
|
|
23
|
+
- doc-chat Stop button actually works — release server guard on disconnect
|
|
22
24
|
- CC streaming auto-retries fresh session when resume fails
|
|
23
25
|
- 429 retry on abort race applies to all sends, not just queued
|
|
24
26
|
- show actionable failure context instead of Unknown error (#1003)
|
package/dashboard/js/modal-qa.js
CHANGED
|
@@ -340,6 +340,9 @@ function qaAbort() {
|
|
|
340
340
|
_qaAbortController.abort();
|
|
341
341
|
_qaAbortController = null;
|
|
342
342
|
}
|
|
343
|
+
// Force-reset processing state so UI isn't stuck if abort races with response
|
|
344
|
+
_qaProcessing = false;
|
|
345
|
+
// Don't clear _qaQueue — queued messages should auto-process after abort
|
|
343
346
|
}
|
|
344
347
|
|
|
345
348
|
function toggleDocChat() {
|
package/dashboard.js
CHANGED
|
@@ -741,7 +741,7 @@ function updateSession(store, key, sessionId, existing) {
|
|
|
741
741
|
* @param {number} opts.maxTurns - Max tool-use turns
|
|
742
742
|
* @param {string} opts.allowedTools - Comma-separated tool list
|
|
743
743
|
*/
|
|
744
|
-
async function ccCall(message, { store = 'cc', sessionKey, extraContext, label = 'command-center', timeout = 900000, maxTurns, allowedTools = 'Bash,Read,Write,Edit,Glob,Grep,WebFetch,WebSearch', skipStatePreamble = false, model } = {}) {
|
|
744
|
+
async function ccCall(message, { store = 'cc', sessionKey, extraContext, label = 'command-center', timeout = 900000, maxTurns, allowedTools = 'Bash,Read,Write,Edit,Glob,Grep,WebFetch,WebSearch', skipStatePreamble = false, model, onAbortReady } = {}) {
|
|
745
745
|
if (!maxTurns) maxTurns = CONFIG.engine?.ccMaxTurns || shared.ENGINE_DEFAULTS.ccMaxTurns;
|
|
746
746
|
if (!model) model = CONFIG.engine?.ccModel || shared.ENGINE_DEFAULTS.ccModel;
|
|
747
747
|
const ccEffort = CONFIG.engine?.ccEffort || shared.ENGINE_DEFAULTS.ccEffort;
|
|
@@ -759,9 +759,11 @@ async function ccCall(message, { store = 'cc', sessionKey, extraContext, label =
|
|
|
759
759
|
|
|
760
760
|
// Attempt 1: resume existing session — skip preamble (session already has context)
|
|
761
761
|
if (sessionId && maxTurns > 1) {
|
|
762
|
-
|
|
762
|
+
const p1 = llm.callLLM(buildPrompt({ includePreamble: false }), '', {
|
|
763
763
|
timeout, label, model, maxTurns, allowedTools, sessionId, effort: ccEffort, direct: true,
|
|
764
764
|
});
|
|
765
|
+
if (onAbortReady) onAbortReady(p1.abort);
|
|
766
|
+
result = await p1;
|
|
765
767
|
llm.trackEngineUsage(label, result.usage);
|
|
766
768
|
|
|
767
769
|
if (result.text) {
|
|
@@ -792,9 +794,11 @@ async function ccCall(message, { store = 'cc', sessionKey, extraContext, label =
|
|
|
792
794
|
|
|
793
795
|
// Attempt 2: fresh session (include preamble for full context)
|
|
794
796
|
const freshPrompt = buildPrompt();
|
|
795
|
-
|
|
797
|
+
const p2 = llm.callLLM(freshPrompt, CC_STATIC_SYSTEM_PROMPT, {
|
|
796
798
|
timeout, label, model, maxTurns, allowedTools, effort: ccEffort, direct: true,
|
|
797
799
|
});
|
|
800
|
+
if (onAbortReady) onAbortReady(p2.abort);
|
|
801
|
+
result = await p2;
|
|
798
802
|
llm.trackEngineUsage(label, result.usage);
|
|
799
803
|
|
|
800
804
|
if (result.text) {
|
|
@@ -806,9 +810,11 @@ async function ccCall(message, { store = 'cc', sessionKey, extraContext, label =
|
|
|
806
810
|
if (maxTurns <= 1) return result;
|
|
807
811
|
console.log(`[${label}] Fresh call also failed (code=${result.code}, empty=${!result.text}), retrying once more...`);
|
|
808
812
|
await new Promise(r => setTimeout(r, 2000));
|
|
809
|
-
|
|
813
|
+
const p3 = llm.callLLM(freshPrompt, CC_STATIC_SYSTEM_PROMPT, {
|
|
810
814
|
timeout, label, model, maxTurns, allowedTools, effort: ccEffort, direct: true,
|
|
811
815
|
});
|
|
816
|
+
if (onAbortReady) onAbortReady(p3.abort);
|
|
817
|
+
result = await p3;
|
|
812
818
|
llm.trackEngineUsage(label, result.usage);
|
|
813
819
|
|
|
814
820
|
if (result.text) {
|
|
@@ -818,7 +824,7 @@ async function ccCall(message, { store = 'cc', sessionKey, extraContext, label =
|
|
|
818
824
|
}
|
|
819
825
|
|
|
820
826
|
// Doc-specific wrapper — adds document context, parses ---DOCUMENT---
|
|
821
|
-
async function ccDocCall({ message, document, title, filePath, selection, canEdit, isJson, model, freshSession }) {
|
|
827
|
+
async function ccDocCall({ message, document, title, filePath, selection, canEdit, isJson, model, freshSession, onAbortReady }) {
|
|
822
828
|
const sessionKey = filePath || title;
|
|
823
829
|
const docSlice = document.slice(0, 20000);
|
|
824
830
|
|
|
@@ -850,6 +856,7 @@ async function ccDocCall({ message, document, title, filePath, selection, canEdi
|
|
|
850
856
|
maxTurns: canEdit ? 25 : 10,
|
|
851
857
|
skipStatePreamble: true,
|
|
852
858
|
...(model ? { model } : {}),
|
|
859
|
+
onAbortReady,
|
|
853
860
|
});
|
|
854
861
|
|
|
855
862
|
if (freshSession && sessionKey) {
|
|
@@ -2935,6 +2942,9 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
2935
2942
|
return jsonReply(res, 429, { error: 'This document is already being processed — wait for the current response.' });
|
|
2936
2943
|
}
|
|
2937
2944
|
docChatInFlight.add(docKey);
|
|
2945
|
+
// Kill LLM process + release guard if client disconnects (abort/navigation)
|
|
2946
|
+
let _docAbort = null;
|
|
2947
|
+
req.on('close', () => { docChatInFlight.delete(docKey); if (_docAbort) _docAbort(); });
|
|
2938
2948
|
|
|
2939
2949
|
try {
|
|
2940
2950
|
const canEdit = !!body.filePath;
|
|
@@ -2953,6 +2963,7 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
2953
2963
|
filePath: body.filePath, selection: body.selection, canEdit, isJson,
|
|
2954
2964
|
model: body.model || undefined,
|
|
2955
2965
|
freshSession: !!body.freshSession,
|
|
2966
|
+
onAbortReady: (abort) => { _docAbort = abort; },
|
|
2956
2967
|
});
|
|
2957
2968
|
|
|
2958
2969
|
if (!content) return jsonReply(res, 200, { ok: true, answer, edited: false, actions });
|
package/engine/llm.js
CHANGED
|
@@ -130,10 +130,13 @@ function _spawnProcess(promptText, sysPromptText, { direct, label, model, maxTur
|
|
|
130
130
|
// ── Core LLM Call ───────────────────────────────────────────────────────────
|
|
131
131
|
|
|
132
132
|
function callLLM(promptText, sysPromptText, { timeout = 120000, label = 'llm', model = 'sonnet', maxTurns = 1, allowedTools = '', sessionId = null, effort = null, direct = false } = {}) {
|
|
133
|
-
|
|
133
|
+
let _abort = null;
|
|
134
|
+
const promise = new Promise((resolve) => {
|
|
134
135
|
const _startMs = Date.now();
|
|
135
136
|
const { proc, cleanupFiles } = _spawnProcess(promptText, sysPromptText, { direct, label, model, maxTurns, allowedTools, effort, sessionId });
|
|
136
137
|
|
|
138
|
+
_abort = () => { shared.killImmediate(proc); };
|
|
139
|
+
|
|
137
140
|
let stdout = '';
|
|
138
141
|
let stderr = '';
|
|
139
142
|
proc.stdout.on('data', d => { stdout += d.toString(); });
|
|
@@ -156,6 +159,8 @@ function callLLM(promptText, sysPromptText, { timeout = 120000, label = 'llm', m
|
|
|
156
159
|
resolve({ text: '', usage: null, sessionId: null, code: 1, stderr: err.message, raw: '' });
|
|
157
160
|
});
|
|
158
161
|
});
|
|
162
|
+
promise.abort = () => { if (_abort) _abort(); };
|
|
163
|
+
return promise;
|
|
159
164
|
}
|
|
160
165
|
|
|
161
166
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.926",
|
|
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"
|