jinzd-ai-cli 0.4.153 → 0.4.154
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/dist/{batch-DBRN4MCC.js → batch-W57MV5OT.js} +2 -2
- package/dist/{chunk-LJPB4ZER.js → chunk-2IODI5TI.js} +1 -1
- package/dist/{chunk-EYJQJZJ6.js → chunk-HVNEBTSF.js} +1 -1
- package/dist/{chunk-OT2HLGSO.js → chunk-NP7WOVIH.js} +1 -1
- package/dist/{chunk-M4GJOBWN.js → chunk-O6MLS5QO.js} +63 -23
- package/dist/{chunk-UWW3EWER.js → chunk-OSTMMSOV.js} +1 -1
- package/dist/{chunk-TURORFH2.js → chunk-SH7NTECG.js} +1 -1
- package/dist/{chunk-D62BVFP7.js → chunk-UE26B3RO.js} +1 -1
- package/dist/{chunk-OP3I24WL.js → chunk-XWYWASPT.js} +3 -3
- package/dist/{chunk-EIIMBVXN.js → chunk-ZAYDVWY4.js} +2 -2
- package/dist/{ci-UEEUSELV.js → ci-JYZGZSMP.js} +2 -2
- package/dist/{constants-43EVHE2E.js → constants-S4Y6A25E.js} +1 -1
- package/dist/{doctor-cli-ZT674MCQ.js → doctor-cli-FMTMDO2Z.js} +4 -4
- package/dist/electron-server.js +2 -2
- package/dist/{hub-MDQNJOMV.js → hub-OP7EWTQQ.js} +63 -5
- package/dist/{hub-server-VPXCBWLA.js → hub-server-OH7AYQIW.js} +1 -1
- package/dist/index.js +20 -16
- package/dist/{run-tests-EYZ2JZ4X.js → run-tests-3QAZGHP2.js} +2 -2
- package/dist/{run-tests-DCT5LWBB.js → run-tests-4XNY7QB4.js} +1 -1
- package/dist/{server-OIYBFKS2.js → server-UL42EXOA.js} +7 -7
- package/dist/{server-MQWFO2GJ.js → server-W4TBZN6I.js} +4 -4
- package/dist/{task-orchestrator-BGQBNKAI.js → task-orchestrator-RLAZK5EB.js} +4 -4
- package/package.json +1 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ConfigManager
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-OSTMMSOV.js";
|
|
5
5
|
import "./chunk-2ZD3YTVM.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-UE26B3RO.js";
|
|
7
7
|
import "./chunk-PDX44BCA.js";
|
|
8
8
|
|
|
9
9
|
// src/cli/batch.ts
|
|
@@ -1,7 +1,33 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
// src/hub/convergence.ts
|
|
4
|
+
function convergenceThreshold(total) {
|
|
5
|
+
if (total <= 0) return Infinity;
|
|
6
|
+
return Math.ceil(total * 2 / 3);
|
|
7
|
+
}
|
|
8
|
+
function isConverged(convergedCount, total) {
|
|
9
|
+
if (convergedCount <= 0) return false;
|
|
10
|
+
return convergedCount >= convergenceThreshold(total);
|
|
11
|
+
}
|
|
12
|
+
var CONVERGED_MARKER = /\[CONVERGED\]/i;
|
|
13
|
+
function hasConvergedMarker(content) {
|
|
14
|
+
return CONVERGED_MARKER.test(content);
|
|
15
|
+
}
|
|
16
|
+
function stripConvergedMarker(content) {
|
|
17
|
+
return content.replace(/\s*\[CONVERGED\]\s*/gi, " ").trim();
|
|
18
|
+
}
|
|
19
|
+
|
|
3
20
|
// src/hub/agent.ts
|
|
4
21
|
var PASS_MARKER = "[PASS]";
|
|
22
|
+
function parseTurn(raw) {
|
|
23
|
+
const trimmed = raw.trim();
|
|
24
|
+
const upper = trimmed.toUpperCase();
|
|
25
|
+
if (upper.startsWith(PASS_MARKER) || upper === PASS_MARKER) {
|
|
26
|
+
return { content: "", passed: true, converged: false };
|
|
27
|
+
}
|
|
28
|
+
const converged = hasConvergedMarker(trimmed);
|
|
29
|
+
return { content: converged ? stripConvergedMarker(trimmed) : trimmed, passed: false, converged };
|
|
30
|
+
}
|
|
5
31
|
var HubAgent = class {
|
|
6
32
|
role;
|
|
7
33
|
providers;
|
|
@@ -27,12 +53,12 @@ var HubAgent = class {
|
|
|
27
53
|
*
|
|
28
54
|
* Returns a DiscussionMessage, with `passed: true` if the agent outputs [PASS].
|
|
29
55
|
*/
|
|
30
|
-
async speak(topic, history, round, maxRounds) {
|
|
56
|
+
async speak(topic, history, round, maxRounds, opts) {
|
|
31
57
|
const provider = this.providers.get(this.providerId);
|
|
32
58
|
if (!provider) {
|
|
33
59
|
throw new Error(`Provider "${this.providerId}" not available for agent "${this.role.id}"`);
|
|
34
60
|
}
|
|
35
|
-
const systemPrompt = this.buildSystemPrompt(topic, round, maxRounds);
|
|
61
|
+
const systemPrompt = this.buildSystemPrompt(topic, round, maxRounds, opts?.voteConverge);
|
|
36
62
|
const messages = this.buildMessages(history);
|
|
37
63
|
const response = await provider.chat({
|
|
38
64
|
messages,
|
|
@@ -42,31 +68,31 @@ var HubAgent = class {
|
|
|
42
68
|
temperature: 0.7,
|
|
43
69
|
maxTokens: 4096
|
|
44
70
|
});
|
|
45
|
-
const content = response.content
|
|
46
|
-
const passed = content.toUpperCase().startsWith(PASS_MARKER) || content.toUpperCase() === PASS_MARKER;
|
|
71
|
+
const { content, passed, converged } = parseTurn(response.content);
|
|
47
72
|
return {
|
|
48
73
|
speaker: this.role.id,
|
|
49
74
|
speakerName: this.role.name,
|
|
50
|
-
content
|
|
75
|
+
content,
|
|
51
76
|
timestamp: /* @__PURE__ */ new Date(),
|
|
52
|
-
passed
|
|
77
|
+
passed,
|
|
78
|
+
converged
|
|
53
79
|
};
|
|
54
80
|
}
|
|
55
81
|
/**
|
|
56
82
|
* Streaming version of speak() — yields tokens as they arrive.
|
|
57
83
|
* Falls back to non-streaming speak() if the provider doesn't support chatStream.
|
|
58
84
|
*/
|
|
59
|
-
async speakStream(topic, history, round, maxRounds, onToken) {
|
|
85
|
+
async speakStream(topic, history, round, maxRounds, onToken, opts) {
|
|
60
86
|
const provider = this.providers.get(this.providerId);
|
|
61
87
|
if (!provider) {
|
|
62
88
|
throw new Error(`Provider "${this.providerId}" not available for agent "${this.role.id}"`);
|
|
63
89
|
}
|
|
64
90
|
if (!provider.chatStream) {
|
|
65
|
-
return this.speak(topic, history, round, maxRounds);
|
|
91
|
+
return this.speak(topic, history, round, maxRounds, opts);
|
|
66
92
|
}
|
|
67
|
-
const systemPrompt = this.buildSystemPrompt(topic, round, maxRounds);
|
|
93
|
+
const systemPrompt = this.buildSystemPrompt(topic, round, maxRounds, opts?.voteConverge);
|
|
68
94
|
const messages = this.buildMessages(history);
|
|
69
|
-
let
|
|
95
|
+
let raw = "";
|
|
70
96
|
const stream = provider.chatStream({
|
|
71
97
|
messages,
|
|
72
98
|
model: this.modelId,
|
|
@@ -77,18 +103,18 @@ var HubAgent = class {
|
|
|
77
103
|
});
|
|
78
104
|
for await (const chunk of stream) {
|
|
79
105
|
if (chunk.delta) {
|
|
80
|
-
|
|
106
|
+
raw += chunk.delta;
|
|
81
107
|
onToken?.(chunk.delta);
|
|
82
108
|
}
|
|
83
109
|
}
|
|
84
|
-
content =
|
|
85
|
-
const passed = content.toUpperCase().startsWith(PASS_MARKER) || content.toUpperCase() === PASS_MARKER;
|
|
110
|
+
const { content, passed, converged } = parseTurn(raw);
|
|
86
111
|
return {
|
|
87
112
|
speaker: this.role.id,
|
|
88
113
|
speakerName: this.role.name,
|
|
89
|
-
content
|
|
114
|
+
content,
|
|
90
115
|
timestamp: /* @__PURE__ */ new Date(),
|
|
91
|
-
passed
|
|
116
|
+
passed,
|
|
117
|
+
converged
|
|
92
118
|
};
|
|
93
119
|
}
|
|
94
120
|
/**
|
|
@@ -116,11 +142,13 @@ var HubAgent = class {
|
|
|
116
142
|
return response.content.trim();
|
|
117
143
|
}
|
|
118
144
|
// ── Private ──────────────────────────────────────────────────────
|
|
119
|
-
buildSystemPrompt(topic, round, maxRounds) {
|
|
145
|
+
buildSystemPrompt(topic, round, maxRounds, voteConverge) {
|
|
120
146
|
const contextSection = this.context ? `
|
|
121
147
|
|
|
122
148
|
## Reference Documents
|
|
123
149
|
${this.context}` : "";
|
|
150
|
+
const convergeRule = voteConverge ? `
|
|
151
|
+
- If you believe the group has reached a sufficient conclusion and further rounds would add little, append the marker [CONVERGED] at the very end of your message (you may still make your substantive point above it). When a 2/3 majority converges, the discussion ends.` : "";
|
|
124
152
|
return `# Multi-Agent Discussion \u2014 Role: ${this.role.name}
|
|
125
153
|
|
|
126
154
|
${this.role.persona}
|
|
@@ -130,7 +158,7 @@ ${this.role.persona}
|
|
|
130
158
|
- You can see what other participants have said. Build on their ideas, challenge them, or add your own perspective.
|
|
131
159
|
- Stay in character as ${this.role.name}. Respond from your role's expertise and viewpoint.
|
|
132
160
|
- Keep responses concise and focused (2-6 paragraphs). Do not repeat what others have already said.
|
|
133
|
-
- If you have nothing meaningful to add (others have covered your points), respond with exactly: [PASS]
|
|
161
|
+
- If you have nothing meaningful to add (others have covered your points), respond with exactly: [PASS]${convergeRule}
|
|
134
162
|
- This is round ${round} of ${maxRounds}. ${round >= maxRounds - 1 ? "This is one of the final rounds \u2014 try to converge on conclusions." : ""}
|
|
135
163
|
- Use the language that the topic is written in (if the topic is in Chinese, respond in Chinese).
|
|
136
164
|
|
|
@@ -184,13 +212,15 @@ ${topic}
|
|
|
184
212
|
${transcript}
|
|
185
213
|
|
|
186
214
|
## Instructions
|
|
187
|
-
Produce a
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
215
|
+
Produce a structured, decision-oriented synthesis with these exact sections:
|
|
216
|
+
|
|
217
|
+
1. **Decision / Recommendation** \u2014 the single clearest recommendation the discussion points to. If the group genuinely did not converge, say so and give the leading option plus what would settle it.
|
|
218
|
+
2. **Key Points of Agreement** \u2014 what participants agreed on.
|
|
219
|
+
3. **Points of Debate** \u2014 where they disagreed, with the competing perspectives.
|
|
220
|
+
4. **Action Items** \u2014 concrete next steps as a checklist. For each, suggest which role/expertise should own it, e.g. "- [ ] (\u67B6\u6784\u5E08) \u8BC4\u4F30\u670D\u52A1\u62C6\u5206\u8FB9\u754C".
|
|
221
|
+
5. **Risks & Open Questions** \u2014 unresolved issues and what to watch.
|
|
192
222
|
|
|
193
|
-
Keep
|
|
223
|
+
Keep it tight (within ~600 words). Use the same language as the discussion.`;
|
|
194
224
|
}
|
|
195
225
|
};
|
|
196
226
|
|
|
@@ -358,9 +388,18 @@ function renderHubEvent(event) {
|
|
|
358
388
|
clearSpeakingLine();
|
|
359
389
|
streamHeaderPrinted = false;
|
|
360
390
|
break;
|
|
391
|
+
case "converge_vote":
|
|
392
|
+
console.log(chalk.dim(` \u{1F5F3} Convergence vote: ${event.converged}/${event.total} agent(s) marked [CONVERGED]`));
|
|
393
|
+
break;
|
|
394
|
+
case "human_steer":
|
|
395
|
+
console.log(chalk.cyan(` \u{1F9ED} You steered: ${truncate(event.message, 80)}`));
|
|
396
|
+
console.log();
|
|
397
|
+
break;
|
|
361
398
|
case "discussion_end":
|
|
362
399
|
if (event.reason === "consensus") renderConsensus();
|
|
400
|
+
else if (event.reason === "vote_converged") console.log(chalk.bold.green("\n \u2713 Converged by vote (2/3 majority).\n"));
|
|
363
401
|
else if (event.reason === "max_rounds") renderMaxRounds(event.maxRounds ?? 0);
|
|
402
|
+
else if (event.reason === "human_stop") console.log(chalk.bold.yellow("\n \u23F9 Stopped by you \u2014 generating summary.\n"));
|
|
364
403
|
else renderUserInterrupt();
|
|
365
404
|
break;
|
|
366
405
|
case "summary":
|
|
@@ -379,6 +418,7 @@ function stripAnsi(s) {
|
|
|
379
418
|
}
|
|
380
419
|
|
|
381
420
|
export {
|
|
421
|
+
isConverged,
|
|
382
422
|
HubAgent,
|
|
383
423
|
assignRoleColors,
|
|
384
424
|
renderHubBanner,
|
|
@@ -5,10 +5,10 @@ import {
|
|
|
5
5
|
} from "./chunk-HDSKW7Q3.js";
|
|
6
6
|
import {
|
|
7
7
|
runTestsTool
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-NP7WOVIH.js";
|
|
9
9
|
import {
|
|
10
10
|
runTool
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-HVNEBTSF.js";
|
|
12
12
|
import {
|
|
13
13
|
getDangerLevel,
|
|
14
14
|
isFileWriteTool
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
SUBAGENT_ALLOWED_TOOLS,
|
|
26
26
|
SUBAGENT_DEFAULT_MAX_ROUNDS,
|
|
27
27
|
SUBAGENT_MAX_ROUNDS_LIMIT
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-UE26B3RO.js";
|
|
29
29
|
import {
|
|
30
30
|
fileCheckpoints
|
|
31
31
|
} from "./chunk-4BKXL7SM.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
truncateForPersist
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-XWYWASPT.js";
|
|
5
5
|
import {
|
|
6
6
|
APP_NAME,
|
|
7
7
|
CONFIG_DIR_NAME,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
MCP_PROTOCOL_VERSION,
|
|
12
12
|
MCP_TOOL_PREFIX,
|
|
13
13
|
VERSION
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-UE26B3RO.js";
|
|
15
15
|
import {
|
|
16
16
|
redactJson
|
|
17
17
|
} from "./chunk-RXM76HB7.js";
|
|
@@ -9,12 +9,12 @@ import {
|
|
|
9
9
|
} from "./chunk-AIZOARZY.js";
|
|
10
10
|
import {
|
|
11
11
|
ConfigManager
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-OSTMMSOV.js";
|
|
13
13
|
import "./chunk-NXXNLLSG.js";
|
|
14
14
|
import "./chunk-2ZD3YTVM.js";
|
|
15
15
|
import {
|
|
16
16
|
VERSION
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-UE26B3RO.js";
|
|
18
18
|
import "./chunk-PDX44BCA.js";
|
|
19
19
|
|
|
20
20
|
// src/cli/ci.ts
|
|
@@ -2,26 +2,26 @@
|
|
|
2
2
|
import {
|
|
3
3
|
getConfigDirUsage,
|
|
4
4
|
listRecentCrashes
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-SH7NTECG.js";
|
|
6
6
|
import {
|
|
7
7
|
ProviderRegistry
|
|
8
8
|
} from "./chunk-AIZOARZY.js";
|
|
9
9
|
import {
|
|
10
10
|
ConfigManager
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-OSTMMSOV.js";
|
|
12
12
|
import {
|
|
13
13
|
getStatsSnapshot,
|
|
14
14
|
getTopFailingTools,
|
|
15
15
|
getTopUsedTools,
|
|
16
16
|
resetStats
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-HVNEBTSF.js";
|
|
18
18
|
import "./chunk-NXXNLLSG.js";
|
|
19
19
|
import "./chunk-2ZD3YTVM.js";
|
|
20
20
|
import {
|
|
21
21
|
DEV_STATE_FILE_NAME,
|
|
22
22
|
MEMORY_FILE_NAME,
|
|
23
23
|
VERSION
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-UE26B3RO.js";
|
|
25
25
|
import "./chunk-PDX44BCA.js";
|
|
26
26
|
|
|
27
27
|
// src/diagnostics/doctor-cli.ts
|
package/dist/electron-server.js
CHANGED
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
VERSION,
|
|
37
37
|
buildUserIdentityPrompt,
|
|
38
38
|
runTestsTool
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-2IODI5TI.js";
|
|
40
40
|
import {
|
|
41
41
|
hasSemanticIndex,
|
|
42
42
|
semanticSearch
|
|
@@ -12715,7 +12715,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
|
|
|
12715
12715
|
case "test": {
|
|
12716
12716
|
this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
|
|
12717
12717
|
try {
|
|
12718
|
-
const { executeTests } = await import("./run-tests-
|
|
12718
|
+
const { executeTests } = await import("./run-tests-4XNY7QB4.js");
|
|
12719
12719
|
const argStr = args.join(" ").trim();
|
|
12720
12720
|
let testArgs = {};
|
|
12721
12721
|
if (argStr) {
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
HubAgent,
|
|
4
4
|
assignRoleColors,
|
|
5
|
+
isConverged,
|
|
5
6
|
renderHubBanner,
|
|
6
7
|
renderHubEvent
|
|
7
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-O6MLS5QO.js";
|
|
8
9
|
import "./chunk-PDX44BCA.js";
|
|
9
10
|
|
|
10
11
|
// src/hub/discuss.ts
|
|
@@ -12,12 +13,22 @@ var DiscussionOrchestrator = class {
|
|
|
12
13
|
agents = [];
|
|
13
14
|
state;
|
|
14
15
|
aborted = false;
|
|
16
|
+
humanSteer;
|
|
17
|
+
voteConverge;
|
|
15
18
|
/** Callback for rendering events */
|
|
16
19
|
onEvent;
|
|
20
|
+
/**
|
|
21
|
+
* P2: human-in-the-loop. When `config.humanSteer` is on, the orchestrator
|
|
22
|
+
* awaits this between rounds so a person can inject guidance or stop. The
|
|
23
|
+
* CLI layer supplies the actual prompt; the orchestrator stays UI-agnostic.
|
|
24
|
+
*/
|
|
25
|
+
onRoundReview;
|
|
17
26
|
constructor(config, providers) {
|
|
18
27
|
this.agents = config.roles.map(
|
|
19
28
|
(role) => new HubAgent(role, providers, config.defaultProvider, config.defaultModel, config.context)
|
|
20
29
|
);
|
|
30
|
+
this.humanSteer = config.humanSteer ?? false;
|
|
31
|
+
this.voteConverge = config.voteConverge ?? false;
|
|
21
32
|
this.state = {
|
|
22
33
|
topic: "",
|
|
23
34
|
messages: [],
|
|
@@ -52,6 +63,7 @@ var DiscussionOrchestrator = class {
|
|
|
52
63
|
this.state.round = round;
|
|
53
64
|
this.emit({ type: "round_start", round, maxRounds: this.state.maxRounds });
|
|
54
65
|
let allPassed = true;
|
|
66
|
+
let convergedCount = 0;
|
|
55
67
|
for (const agent of this.agents) {
|
|
56
68
|
if (this.aborted) break;
|
|
57
69
|
this.emit({ type: "agent_speaking", roleId: agent.role.id, roleName: agent.role.name });
|
|
@@ -61,9 +73,11 @@ var DiscussionOrchestrator = class {
|
|
|
61
73
|
this.state.messages,
|
|
62
74
|
round,
|
|
63
75
|
this.state.maxRounds,
|
|
64
|
-
(token) => this.emit({ type: "agent_token", roleId: agent.role.id, token })
|
|
76
|
+
(token) => this.emit({ type: "agent_token", roleId: agent.role.id, token }),
|
|
77
|
+
{ voteConverge: this.voteConverge }
|
|
65
78
|
);
|
|
66
79
|
this.state.messages.push(message);
|
|
80
|
+
if (message.converged) convergedCount++;
|
|
67
81
|
if (message.passed) {
|
|
68
82
|
this.emit({ type: "agent_passed", roleId: agent.role.id });
|
|
69
83
|
this.emit({ type: "agent_spoke", roleId: agent.role.id, message });
|
|
@@ -87,8 +101,33 @@ var DiscussionOrchestrator = class {
|
|
|
87
101
|
this.emit({ type: "discussion_end", reason: "consensus" });
|
|
88
102
|
break;
|
|
89
103
|
}
|
|
104
|
+
if (this.voteConverge && convergedCount > 0) {
|
|
105
|
+
this.emit({ type: "converge_vote", converged: convergedCount, total: this.agents.length });
|
|
106
|
+
if (isConverged(convergedCount, this.agents.length)) {
|
|
107
|
+
this.emit({ type: "discussion_end", reason: "vote_converged" });
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
90
111
|
if (round === this.state.maxRounds) {
|
|
91
112
|
this.emit({ type: "discussion_end", reason: "max_rounds", maxRounds: this.state.maxRounds });
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
if (this.humanSteer && this.onRoundReview && !this.aborted) {
|
|
116
|
+
const steer = await this.onRoundReview({ round, maxRounds: this.state.maxRounds, state: this.state });
|
|
117
|
+
if (steer.action === "stop") {
|
|
118
|
+
this.emit({ type: "discussion_end", reason: "human_stop" });
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
const guidance = steer.message?.trim();
|
|
122
|
+
if (guidance) {
|
|
123
|
+
this.state.messages.push({
|
|
124
|
+
speaker: "human",
|
|
125
|
+
speakerName: "\u4E3B\u6301\u4EBA (You)",
|
|
126
|
+
content: guidance,
|
|
127
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
128
|
+
});
|
|
129
|
+
this.emit({ type: "human_steer", message: guidance });
|
|
130
|
+
}
|
|
92
131
|
}
|
|
93
132
|
}
|
|
94
133
|
} catch (err) {
|
|
@@ -431,7 +470,9 @@ ${content}`);
|
|
|
431
470
|
enableTools: mode === "task",
|
|
432
471
|
maxToolRoundsPerTurn: mode === "task" ? options.taskRounds ?? 30 : void 0,
|
|
433
472
|
context,
|
|
434
|
-
contextFiles: contextFileNames.length > 0 ? contextFileNames : void 0
|
|
473
|
+
contextFiles: contextFileNames.length > 0 ? contextFileNames : void 0,
|
|
474
|
+
humanSteer: options.steer === true,
|
|
475
|
+
voteConverge: options.vote === true
|
|
435
476
|
};
|
|
436
477
|
if (mode === "discuss") {
|
|
437
478
|
if (options.distributed) {
|
|
@@ -444,7 +485,7 @@ ${content}`);
|
|
|
444
485
|
}
|
|
445
486
|
}
|
|
446
487
|
async function runTaskMode(config, providers, configManager, topic) {
|
|
447
|
-
const { TaskOrchestrator } = await import("./task-orchestrator-
|
|
488
|
+
const { TaskOrchestrator } = await import("./task-orchestrator-RLAZK5EB.js");
|
|
448
489
|
const orchestrator = new TaskOrchestrator(config, providers, configManager);
|
|
449
490
|
let interrupted = false;
|
|
450
491
|
const onSigint = () => {
|
|
@@ -480,7 +521,7 @@ async function runTaskMode(config, providers, configManager, topic) {
|
|
|
480
521
|
}
|
|
481
522
|
}
|
|
482
523
|
async function runDistributedDiscussion(config, providers, topic, port) {
|
|
483
|
-
const { HubServer } = await import("./hub-server-
|
|
524
|
+
const { HubServer } = await import("./hub-server-OH7AYQIW.js");
|
|
484
525
|
const hub = new HubServer(config, providers, port);
|
|
485
526
|
let interrupted = false;
|
|
486
527
|
const onSigint = () => {
|
|
@@ -506,6 +547,23 @@ async function runDiscussion(config, providers, topic) {
|
|
|
506
547
|
assignRoleColors(config.roles);
|
|
507
548
|
const orchestrator = new DiscussionOrchestrator(config, providers);
|
|
508
549
|
orchestrator.onEvent = renderHubEvent;
|
|
550
|
+
if (config.humanSteer) {
|
|
551
|
+
const { createInterface } = await import("readline");
|
|
552
|
+
orchestrator.onRoundReview = async ({ round, maxRounds }) => {
|
|
553
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
554
|
+
const answer = await new Promise((resolve) => {
|
|
555
|
+
rl.question(
|
|
556
|
+
chalk.cyan(`
|
|
557
|
+
\u{1F9ED} Round ${round}/${maxRounds} done. Steer next round? `) + chalk.dim("[Enter=continue \xB7 type guidance \xB7 /stop=end] "),
|
|
558
|
+
resolve
|
|
559
|
+
);
|
|
560
|
+
});
|
|
561
|
+
rl.close();
|
|
562
|
+
const t = answer.trim();
|
|
563
|
+
if (t === "/stop" || t.toLowerCase() === "stop") return { action: "stop" };
|
|
564
|
+
return { action: "continue", message: t || void 0 };
|
|
565
|
+
};
|
|
566
|
+
}
|
|
509
567
|
let interrupted = false;
|
|
510
568
|
const onSigint = () => {
|
|
511
569
|
if (interrupted) {
|
package/dist/index.js
CHANGED
|
@@ -20,12 +20,12 @@ import {
|
|
|
20
20
|
saveDevState,
|
|
21
21
|
sessionHasMeaningfulContent,
|
|
22
22
|
setupProxy
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-ZAYDVWY4.js";
|
|
24
24
|
import {
|
|
25
25
|
getConfigDirUsage,
|
|
26
26
|
listRecentCrashes,
|
|
27
27
|
writeCrashLog
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-SH7NTECG.js";
|
|
29
29
|
import {
|
|
30
30
|
CONTENT_ONLY_STREAM_REMINDER,
|
|
31
31
|
HALLUCINATION_CORRECTION_MESSAGE,
|
|
@@ -46,7 +46,7 @@ import {
|
|
|
46
46
|
} from "./chunk-AIZOARZY.js";
|
|
47
47
|
import {
|
|
48
48
|
ConfigManager
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-OSTMMSOV.js";
|
|
50
50
|
import {
|
|
51
51
|
ToolExecutor,
|
|
52
52
|
ToolRegistry,
|
|
@@ -65,16 +65,16 @@ import {
|
|
|
65
65
|
spawnAgentContext,
|
|
66
66
|
theme,
|
|
67
67
|
undoStack
|
|
68
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-XWYWASPT.js";
|
|
69
69
|
import "./chunk-HDSKW7Q3.js";
|
|
70
70
|
import "./chunk-ZWVIDFGY.js";
|
|
71
|
-
import "./chunk-
|
|
71
|
+
import "./chunk-NP7WOVIH.js";
|
|
72
72
|
import {
|
|
73
73
|
getStatsSnapshot,
|
|
74
74
|
getTopFailingTools,
|
|
75
75
|
getTopUsedTools,
|
|
76
76
|
installFlushOnExit
|
|
77
|
-
} from "./chunk-
|
|
77
|
+
} from "./chunk-HVNEBTSF.js";
|
|
78
78
|
import "./chunk-NXXNLLSG.js";
|
|
79
79
|
import {
|
|
80
80
|
AuthError,
|
|
@@ -102,7 +102,7 @@ import {
|
|
|
102
102
|
SKILLS_DIR_NAME,
|
|
103
103
|
VERSION,
|
|
104
104
|
buildUserIdentityPrompt
|
|
105
|
-
} from "./chunk-
|
|
105
|
+
} from "./chunk-UE26B3RO.js";
|
|
106
106
|
import {
|
|
107
107
|
formatGitContextForPrompt,
|
|
108
108
|
getGitContext,
|
|
@@ -1769,7 +1769,7 @@ No tools match "${filter}".
|
|
|
1769
1769
|
const { join: join6 } = await import("path");
|
|
1770
1770
|
const { existsSync: existsSync6 } = await import("fs");
|
|
1771
1771
|
const { getGitRoot: getGitRoot2 } = await import("./git-context-7KIP4X2V.js");
|
|
1772
|
-
const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-
|
|
1772
|
+
const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-S4Y6A25E.js");
|
|
1773
1773
|
const { approveProject, hashMcpFile } = await import("./project-trust-IFM7FXEV.js");
|
|
1774
1774
|
const cwd = process.cwd();
|
|
1775
1775
|
const projectRoot = getGitRoot2(cwd) ?? cwd;
|
|
@@ -2830,7 +2830,7 @@ ${hint}` : "")
|
|
|
2830
2830
|
usage: "/test [command|filter]",
|
|
2831
2831
|
async execute(args, ctx) {
|
|
2832
2832
|
try {
|
|
2833
|
-
const { executeTests } = await import("./run-tests-
|
|
2833
|
+
const { executeTests } = await import("./run-tests-3QAZGHP2.js");
|
|
2834
2834
|
const argStr = args.join(" ").trim();
|
|
2835
2835
|
let testArgs = {};
|
|
2836
2836
|
if (argStr) {
|
|
@@ -7530,7 +7530,7 @@ program.command("web").description("Start Web UI server with browser-based chat
|
|
|
7530
7530
|
console.error("Error: Invalid port number. Must be between 1 and 65535.");
|
|
7531
7531
|
process.exit(1);
|
|
7532
7532
|
}
|
|
7533
|
-
const { startWebServer } = await import("./server-
|
|
7533
|
+
const { startWebServer } = await import("./server-UL42EXOA.js");
|
|
7534
7534
|
await startWebServer({ port, host: options.host });
|
|
7535
7535
|
});
|
|
7536
7536
|
program.command("user [action] [username]").description("Manage Web UI users (list | create <name> | delete <name> | reset-password <name> | logout-all <name> | migrate <name>)").action(async (action, username) => {
|
|
@@ -7697,12 +7697,12 @@ program.command("sessions").description("List recent conversation sessions").opt
|
|
|
7697
7697
|
console.log(footer + "\n");
|
|
7698
7698
|
});
|
|
7699
7699
|
program.command("doctor").description("Health check: API keys, config, MCP, recent crashes, tool usage, disk usage").option("--json", "Output as JSON (for scripting)").option("--reset-stats", "Reset accumulated tool usage statistics").action(async (options) => {
|
|
7700
|
-
const { runDoctorCli } = await import("./doctor-cli-
|
|
7700
|
+
const { runDoctorCli } = await import("./doctor-cli-FMTMDO2Z.js");
|
|
7701
7701
|
await runDoctorCli({ json: !!options.json, resetStats: !!options.resetStats });
|
|
7702
7702
|
});
|
|
7703
7703
|
program.command("batch <action> [arg] [arg2]").description("Anthropic Message Batches: submit | list | status <id> | results <id> [out] | cancel <id>").option("--dry-run", "Parse and validate input without submitting (submit only)").action(async (action, arg, arg2, options) => {
|
|
7704
7704
|
try {
|
|
7705
|
-
const batch = await import("./batch-
|
|
7705
|
+
const batch = await import("./batch-W57MV5OT.js");
|
|
7706
7706
|
switch (action) {
|
|
7707
7707
|
case "submit":
|
|
7708
7708
|
if (!arg) {
|
|
@@ -7745,7 +7745,7 @@ program.command("batch <action> [arg] [arg2]").description("Anthropic Message Ba
|
|
|
7745
7745
|
}
|
|
7746
7746
|
});
|
|
7747
7747
|
program.command("mcp-serve").description("Start an MCP server over STDIO, exposing aicli's built-in tools to Claude Desktop / Cursor / other MCP clients").option("--allow-destructive", "Allow bash / run_interactive / task_create (always destructive in MCP mode)").option("--allow-outside-cwd", "Allow tool path arguments to escape the sandbox root \u2014 disabled by default").option("--tools <list>", "Comma-separated whitelist of tools to expose (default: all eligible tools)").option("--cwd <path>", "Working directory AND sandbox root (default: current directory)").action(async (options) => {
|
|
7748
|
-
const { startMcpServer } = await import("./server-
|
|
7748
|
+
const { startMcpServer } = await import("./server-W4TBZN6I.js");
|
|
7749
7749
|
await startMcpServer({
|
|
7750
7750
|
allowDestructive: !!options.allowDestructive,
|
|
7751
7751
|
allowOutsideCwd: !!options.allowOutsideCwd,
|
|
@@ -7754,7 +7754,7 @@ program.command("mcp-serve").description("Start an MCP server over STDIO, exposi
|
|
|
7754
7754
|
});
|
|
7755
7755
|
});
|
|
7756
7756
|
program.command("ci").description("Headless PR review (code + security) \u2014 reads git/gh diff, optionally posts to PR. Designed for GitHub Actions.").option("--pr <num>", "PR number; diff fetched via `gh pr diff <num>`", (v) => parseInt(v, 10)).option("--base <ref>", "Base ref for `git diff <ref>...HEAD` (ignored when --pr set)").option("--post", "Post review as a PR comment (requires gh CLI + GH_TOKEN, needs --pr)").option("--no-update", "Always create a new comment instead of updating the previous aicli review").option("--skip-code", "Skip the code review section").option("--skip-security", "Skip the security review section").option("--detailed", "Use the detailed code-review prompt").option("--max-diff <n>", "Max diff chars sent to the model (default 30000)", (v) => parseInt(v, 10)).option("--provider <id>", "Override provider (default: config.defaultProvider)").option("--model <id>", "Override model").option("--dry-run", "Print result to stdout instead of posting (overrides --post)").action(async (options) => {
|
|
7757
|
-
const { runCi } = await import("./ci-
|
|
7757
|
+
const { runCi } = await import("./ci-JYZGZSMP.js");
|
|
7758
7758
|
const result = await runCi({
|
|
7759
7759
|
pr: options.pr,
|
|
7760
7760
|
base: options.base,
|
|
@@ -7828,6 +7828,8 @@ program.command("help").description("Show a comprehensive guide to all aicli fea
|
|
|
7828
7828
|
` ${Y}--preset <name>${R} Role preset (tech-review/brainstorm/code-review/debate)`,
|
|
7829
7829
|
` ${Y}--roles <file>${R} Custom roles JSON file`,
|
|
7830
7830
|
` ${Y}--mix [providers]${R} Mixed multi-model: spread providers across roles (e.g. claude,openai,deepseek)`,
|
|
7831
|
+
` ${Y}--steer${R} Human-in-the-loop: steer/stop between rounds`,
|
|
7832
|
+
` ${Y}--vote${R} Convergence voting: 2/3 [CONVERGED] majority ends early`,
|
|
7831
7833
|
` ${Y}-c, --context <file>${R} Inject context doc (repeatable: -c a.md -c b.md)`,
|
|
7832
7834
|
` ${Y}--task${R} Task mode: agents plan & write code with tools`,
|
|
7833
7835
|
` ${Y}--distributed${R} Distributed mode (WebSocket, multi-process)`,
|
|
@@ -7885,7 +7887,7 @@ program.command("help").description("Show a comprehensive guide to all aicli fea
|
|
|
7885
7887
|
];
|
|
7886
7888
|
console.log(lines.join("\n"));
|
|
7887
7889
|
});
|
|
7888
|
-
program.command("hub [topic]").description("Start multi-agent hub (discuss / brainstorm with multiple AI roles)").option("--preset <name>", "Use a built-in role preset (default: tech-review)").option("--roles <file>", "Load roles from a JSON file").option("--provider <name>", "Override default AI provider").option("-m, --model <name>", "Override default model").option("--mix [providers]", "Mixed multi-model: spread configured providers across roles (or --mix claude,openai,deepseek)").option("--max-rounds <n>", "Max discussion rounds (default: 10)").option("--presets", "List available role presets").option("--task", "Task mode: plan \u2192 approve \uFFFD\uFFFD execute with tools (agents write code)").option("--task-rounds <n>", "Max tool-call rounds per task (default: 30)").option("-c, --context <file>", "Inject context document (repeatable: -c a.md -c b.md)", (val, prev) => prev.concat(val), []).option("--distributed", "Start WebSocket server so remote aicli instances can join as agents").option("--port <n>", "WebSocket port for distributed mode (default: 9527)", "9527").action(async (topic, options) => {
|
|
7890
|
+
program.command("hub [topic]").description("Start multi-agent hub (discuss / brainstorm with multiple AI roles)").option("--preset <name>", "Use a built-in role preset (default: tech-review)").option("--roles <file>", "Load roles from a JSON file").option("--provider <name>", "Override default AI provider").option("-m, --model <name>", "Override default model").option("--mix [providers]", "Mixed multi-model: spread configured providers across roles (or --mix claude,openai,deepseek)").option("--steer", "Human-in-the-loop: pause between rounds to inject guidance or stop (discuss mode)").option("--vote", "Convergence voting: agents may [CONVERGED]; 2/3 majority ends early (discuss mode)").option("--max-rounds <n>", "Max discussion rounds (default: 10)").option("--presets", "List available role presets").option("--task", "Task mode: plan \u2192 approve \uFFFD\uFFFD execute with tools (agents write code)").option("--task-rounds <n>", "Max tool-call rounds per task (default: 30)").option("-c, --context <file>", "Inject context document (repeatable: -c a.md -c b.md)", (val, prev) => prev.concat(val), []).option("--distributed", "Start WebSocket server so remote aicli instances can join as agents").option("--port <n>", "WebSocket port for distributed mode (default: 9527)", "9527").action(async (topic, options) => {
|
|
7889
7891
|
const config = new ConfigManager();
|
|
7890
7892
|
const registry = new ProviderRegistry();
|
|
7891
7893
|
await registry.initialize(
|
|
@@ -7896,7 +7898,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
|
|
|
7896
7898
|
}),
|
|
7897
7899
|
config.get("customProviders")
|
|
7898
7900
|
);
|
|
7899
|
-
const { startHub } = await import("./hub-
|
|
7901
|
+
const { startHub } = await import("./hub-OP7EWTQQ.js");
|
|
7900
7902
|
await startHub(
|
|
7901
7903
|
{
|
|
7902
7904
|
topic: topic ?? "",
|
|
@@ -7905,6 +7907,8 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
|
|
|
7905
7907
|
provider: options.provider,
|
|
7906
7908
|
model: options.model,
|
|
7907
7909
|
mix: options.mix,
|
|
7910
|
+
steer: options.steer === true,
|
|
7911
|
+
vote: options.vote === true,
|
|
7908
7912
|
mode: options.task === true ? "task" : void 0,
|
|
7909
7913
|
maxRounds: options.maxRounds ? parseInt(options.maxRounds, 10) : void 0,
|
|
7910
7914
|
listPresets: options.presets === true,
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
loadDevState,
|
|
15
15
|
persistToolRound,
|
|
16
16
|
setupProxy
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-ZAYDVWY4.js";
|
|
18
18
|
import {
|
|
19
19
|
CONTENT_ONLY_STREAM_REMINDER,
|
|
20
20
|
HALLUCINATION_CORRECTION_MESSAGE,
|
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
} from "./chunk-AIZOARZY.js";
|
|
32
32
|
import {
|
|
33
33
|
ConfigManager
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-OSTMMSOV.js";
|
|
35
35
|
import {
|
|
36
36
|
ToolExecutor,
|
|
37
37
|
ToolRegistry,
|
|
@@ -49,13 +49,13 @@ import {
|
|
|
49
49
|
spawnAgentContext,
|
|
50
50
|
truncateOutput,
|
|
51
51
|
undoStack
|
|
52
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-XWYWASPT.js";
|
|
53
53
|
import "./chunk-HDSKW7Q3.js";
|
|
54
54
|
import "./chunk-ZWVIDFGY.js";
|
|
55
|
-
import "./chunk-
|
|
55
|
+
import "./chunk-NP7WOVIH.js";
|
|
56
56
|
import {
|
|
57
57
|
runTool
|
|
58
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-HVNEBTSF.js";
|
|
59
59
|
import {
|
|
60
60
|
getDangerLevel
|
|
61
61
|
} from "./chunk-NXXNLLSG.js";
|
|
@@ -78,7 +78,7 @@ import {
|
|
|
78
78
|
SKILLS_DIR_NAME,
|
|
79
79
|
VERSION,
|
|
80
80
|
buildUserIdentityPrompt
|
|
81
|
-
} from "./chunk-
|
|
81
|
+
} from "./chunk-UE26B3RO.js";
|
|
82
82
|
import {
|
|
83
83
|
formatGitContextForPrompt,
|
|
84
84
|
getGitContext,
|
|
@@ -2462,7 +2462,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
|
|
|
2462
2462
|
case "test": {
|
|
2463
2463
|
this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
|
|
2464
2464
|
try {
|
|
2465
|
-
const { executeTests } = await import("./run-tests-
|
|
2465
|
+
const { executeTests } = await import("./run-tests-3QAZGHP2.js");
|
|
2466
2466
|
const argStr = args.join(" ").trim();
|
|
2467
2467
|
let testArgs = {};
|
|
2468
2468
|
if (argStr) {
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ToolRegistry
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-XWYWASPT.js";
|
|
5
5
|
import "./chunk-HDSKW7Q3.js";
|
|
6
6
|
import "./chunk-ZWVIDFGY.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-NP7WOVIH.js";
|
|
8
8
|
import {
|
|
9
9
|
runTool
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-HVNEBTSF.js";
|
|
11
11
|
import {
|
|
12
12
|
getDangerLevel,
|
|
13
13
|
schemaToJsonSchema
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
import "./chunk-2ZD3YTVM.js";
|
|
16
16
|
import {
|
|
17
17
|
VERSION
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-UE26B3RO.js";
|
|
19
19
|
import "./chunk-4BKXL7SM.js";
|
|
20
20
|
import "./chunk-RXM76HB7.js";
|
|
21
21
|
import "./chunk-KHYD3WXE.js";
|
|
@@ -3,20 +3,20 @@ import {
|
|
|
3
3
|
ToolRegistry,
|
|
4
4
|
googleSearchContext,
|
|
5
5
|
truncateOutput
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-XWYWASPT.js";
|
|
7
7
|
import "./chunk-HDSKW7Q3.js";
|
|
8
8
|
import "./chunk-ZWVIDFGY.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-NP7WOVIH.js";
|
|
10
10
|
import {
|
|
11
11
|
runTool
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-HVNEBTSF.js";
|
|
13
13
|
import {
|
|
14
14
|
getDangerLevel
|
|
15
15
|
} from "./chunk-NXXNLLSG.js";
|
|
16
16
|
import "./chunk-2ZD3YTVM.js";
|
|
17
17
|
import {
|
|
18
18
|
SUBAGENT_ALLOWED_TOOLS
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-UE26B3RO.js";
|
|
20
20
|
import "./chunk-4BKXL7SM.js";
|
|
21
21
|
import "./chunk-RXM76HB7.js";
|
|
22
22
|
import "./chunk-KHYD3WXE.js";
|