@antonbabenko/deliberation-mcp 3.5.4 → 3.6.1
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/index.js +155 -35
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -231,18 +231,71 @@ var require_provider = __commonJS({
|
|
|
231
231
|
var VERDICT_RE = /\bverdict\b[^A-Za-z0-9]*\b(APPROVE|REJECT|REQUEST[_\s]CHANGES)\b/i;
|
|
232
232
|
var BULLET_RE = /^([-*+•]|`?\[)/;
|
|
233
233
|
var BRACKET_CAT_RE = /\[\s*([A-Za-z_]+)\s*\]/g;
|
|
234
|
+
var SENTINEL_RE = /^[#>*_`\s]*verdict\s*[:=]\s*[*_`\s]*(APPROVE|REJECT|REQUEST[_\s]CHANGES)\b/i;
|
|
235
|
+
var VERDICT_WORD_RE = /^[#>*_`\s]*verdict[*_`:\s]*$/i;
|
|
236
|
+
var TOKEN_LINE_RE = /^(APPROVE|REJECT|REQUEST[_\s]CHANGES)$/i;
|
|
237
|
+
var MD_EMPHASIS = /[*_`~]/g;
|
|
238
|
+
var FENCE_RE = /^\s*(```|~~~)/;
|
|
239
|
+
var ARTIFACT_RE = /^[*_`~\s:.\-]*$/;
|
|
240
|
+
var STRIP_LEAD = /^[*_`~\s:.\-]+/;
|
|
241
|
+
var STRIP_TRAIL = /[*_`~\s]+$/;
|
|
242
|
+
var HEADING_RE = /^#{1,6}\s/;
|
|
243
|
+
function normVerdict(tok) {
|
|
244
|
+
return tok.replace(/\s+/g, "_").toUpperCase();
|
|
245
|
+
}
|
|
234
246
|
function parseReview(text) {
|
|
235
247
|
const raw = safeString(text);
|
|
236
|
-
const lines =
|
|
237
|
-
let
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
if (vm) verdict = /** @type {ParsedReview["verdict"]} */
|
|
243
|
-
vm[1].replace(/\s+/g, "_").toUpperCase();
|
|
248
|
+
const lines = [];
|
|
249
|
+
let inFence = false;
|
|
250
|
+
for (const ln of raw.split(/\r?\n/)) {
|
|
251
|
+
if (FENCE_RE.test(ln)) {
|
|
252
|
+
inFence = !inFence;
|
|
253
|
+
continue;
|
|
244
254
|
}
|
|
245
|
-
|
|
255
|
+
if (!inFence) lines.push(ln);
|
|
256
|
+
}
|
|
257
|
+
return { verdict: resolveVerdict(lines), criticalIssues: resolveIssues(lines) };
|
|
258
|
+
}
|
|
259
|
+
function resolveVerdict(lines) {
|
|
260
|
+
for (const ln of lines) {
|
|
261
|
+
const m = ln.match(SENTINEL_RE);
|
|
262
|
+
if (m) return (
|
|
263
|
+
/** @type {any} */
|
|
264
|
+
normVerdict(m[1])
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
for (const ln of lines) {
|
|
268
|
+
const m = ln.match(VERDICT_RE);
|
|
269
|
+
if (m) return (
|
|
270
|
+
/** @type {any} */
|
|
271
|
+
normVerdict(m[1])
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
for (let i = 0; i < lines.length; i++) {
|
|
275
|
+
if (!VERDICT_WORD_RE.test(lines[i].trim())) continue;
|
|
276
|
+
for (let j = i + 1; j < lines.length && j <= i + 3; j++) {
|
|
277
|
+
const t = lines[j].replace(MD_EMPHASIS, "").trim();
|
|
278
|
+
if (!t) continue;
|
|
279
|
+
if (TOKEN_LINE_RE.test(t)) return (
|
|
280
|
+
/** @type {any} */
|
|
281
|
+
normVerdict(t)
|
|
282
|
+
);
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
for (const ln of lines) {
|
|
287
|
+
const t = ln.replace(MD_EMPHASIS, "").trim();
|
|
288
|
+
if (TOKEN_LINE_RE.test(t)) return (
|
|
289
|
+
/** @type {any} */
|
|
290
|
+
normVerdict(t)
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
295
|
+
function resolveIssues(lines) {
|
|
296
|
+
const out = [];
|
|
297
|
+
for (let i = 0; i < lines.length; i++) {
|
|
298
|
+
const trimmed = lines[i].trim();
|
|
246
299
|
if (!BULLET_RE.test(trimmed)) continue;
|
|
247
300
|
let chosen = null;
|
|
248
301
|
for (const mm of trimmed.matchAll(BRACKET_CAT_RE)) {
|
|
@@ -258,10 +311,20 @@ var require_provider = __commonJS({
|
|
|
258
311
|
/** @type {ReviewCriticalIssue["category"]} */
|
|
259
312
|
REVIEW_CATEGORIES.includes(cat) ? cat : REVIEW_FALLBACK_CATEGORY
|
|
260
313
|
);
|
|
261
|
-
|
|
262
|
-
if (description
|
|
314
|
+
let description = trimmed.slice(chosen.index + chosen[0].length).replace(STRIP_LEAD, "").replace(STRIP_TRAIL, "").trim();
|
|
315
|
+
if (!description || ARTIFACT_RE.test(description)) {
|
|
316
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
317
|
+
const nt = lines[j].trim();
|
|
318
|
+
if (!nt) break;
|
|
319
|
+
if (BULLET_RE.test(nt) || HEADING_RE.test(nt)) break;
|
|
320
|
+
if (SENTINEL_RE.test(nt) || VERDICT_WORD_RE.test(nt) || VERDICT_RE.test(nt)) break;
|
|
321
|
+
description = nt.replace(STRIP_LEAD, "").replace(STRIP_TRAIL, "").trim();
|
|
322
|
+
break;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
if (description && !ARTIFACT_RE.test(description)) out.push({ category, description });
|
|
263
326
|
}
|
|
264
|
-
return
|
|
327
|
+
return out;
|
|
265
328
|
}
|
|
266
329
|
module2.exports = {
|
|
267
330
|
toErrorResult,
|
|
@@ -324,12 +387,12 @@ ${state.currentPlan}`
|
|
|
324
387
|
const peerPrompt = [
|
|
325
388
|
body,
|
|
326
389
|
"Review the plan for correctness, security, scope, ambiguity, performance, and ops gaps.",
|
|
327
|
-
"End with:
|
|
390
|
+
"End with a line by itself in exactly this form (no markdown, token on the SAME line): VERDICT: APPROVE (or VERDICT: REQUEST_CHANGES, or VERDICT: REJECT). Then list any critical issues, one per line as: - [category] description where category is one of security, correctness, scope, ambiguity, performance, ops."
|
|
328
391
|
].join("\n\n");
|
|
329
392
|
const blindPrompt = [
|
|
330
393
|
body,
|
|
331
394
|
"Give your own independent verdict BEFORE seeing peer opinions.",
|
|
332
|
-
"End with:
|
|
395
|
+
"End with a line by itself in exactly this form (no markdown, token on the SAME line): VERDICT: APPROVE (or VERDICT: REQUEST_CHANGES, or VERDICT: REJECT). Then list any critical issues, one per line as: - [category] description where category is one of security, correctness, scope, ambiguity, performance, ops."
|
|
333
396
|
].join("\n\n");
|
|
334
397
|
return { peerPrompt, blindPrompt };
|
|
335
398
|
}
|
|
@@ -520,7 +583,14 @@ var require_orchestrate = __commonJS({
|
|
|
520
583
|
} catch {
|
|
521
584
|
}
|
|
522
585
|
}
|
|
523
|
-
|
|
586
|
+
function withOrientation(provider, req, orientationFiles) {
|
|
587
|
+
if (Array.isArray(orientationFiles) && orientationFiles.length && !(Array.isArray(req.files) && req.files.length) && provider.capabilities && provider.capabilities.walksFilesystem === false) {
|
|
588
|
+
return { ...req, files: orientationFiles };
|
|
589
|
+
}
|
|
590
|
+
return req;
|
|
591
|
+
}
|
|
592
|
+
async function callProvider(provider, req, logger, tool, cache, orientationFiles) {
|
|
593
|
+
req = withOrientation(provider, req, orientationFiles);
|
|
524
594
|
const useCache = cache && !(Array.isArray(req.files) && req.files.length);
|
|
525
595
|
if (useCache) {
|
|
526
596
|
const hit = cache.get(provider.name, req);
|
|
@@ -553,7 +623,7 @@ var require_orchestrate = __commonJS({
|
|
|
553
623
|
const logger = opts.logger || NULL_LOGGER;
|
|
554
624
|
const tool = opts.tool || "ask-all";
|
|
555
625
|
const settled = await Promise.allSettled(
|
|
556
|
-
providers.map((p) => callProvider(p, req, logger, tool, opts.cache))
|
|
626
|
+
providers.map((p) => callProvider(p, req, logger, tool, opts.cache, opts.orientationFiles))
|
|
557
627
|
);
|
|
558
628
|
return settled.map(
|
|
559
629
|
(s, i) => s.status === "fulfilled" ? s.value : {
|
|
@@ -568,7 +638,7 @@ var require_orchestrate = __commonJS({
|
|
|
568
638
|
);
|
|
569
639
|
}
|
|
570
640
|
async function askOne2(provider, req, opts = {}) {
|
|
571
|
-
return callProvider(provider, req, opts.logger || NULL_LOGGER, opts.tool || "ask-one", opts.cache);
|
|
641
|
+
return callProvider(provider, req, opts.logger || NULL_LOGGER, opts.tool || "ask-one", opts.cache, opts.orientationFiles);
|
|
572
642
|
}
|
|
573
643
|
function buildArbiterPrompt(question, opinions) {
|
|
574
644
|
const blocks = opinions.map((o, i) => `### Opinion ${i + 1}
|
|
@@ -593,17 +663,17 @@ ${blocks}`,
|
|
|
593
663
|
// Promise.resolve().then(...) so even a SYNCHRONOUS throw in ask() is caught
|
|
594
664
|
// by the rejection handler (a bare arbiter.ask() could throw before awaiting).
|
|
595
665
|
Promise.resolve().then(
|
|
596
|
-
() => arbiter.ask({
|
|
666
|
+
() => arbiter.ask(withOrientation(arbiter, {
|
|
597
667
|
...req,
|
|
598
668
|
files: req.files ? req.files.map((f) => ({ ...f })) : void 0,
|
|
599
669
|
developerInstructions: opts.arbiterInstructions || req.developerInstructions
|
|
600
|
-
})
|
|
670
|
+
}, opts.orientationFiles))
|
|
601
671
|
).then((v) => v, () => null)
|
|
602
672
|
) : Promise.resolve(
|
|
603
673
|
/** @type {DelegationResult|null} */
|
|
604
674
|
null
|
|
605
675
|
);
|
|
606
|
-
const [opinions, blindVerdict] = await Promise.all([askAll2(providers, req, { logger: opts.logger, tool: "consensus" }), blindPromise]);
|
|
676
|
+
const [opinions, blindVerdict] = await Promise.all([askAll2(providers, req, { logger: opts.logger, tool: "consensus", orientationFiles: opts.orientationFiles }), blindPromise]);
|
|
607
677
|
const ok = (
|
|
608
678
|
/** @type {DelegationSuccess[]} */
|
|
609
679
|
opinions.filter((o) => !o.isError)
|
|
@@ -666,8 +736,8 @@ ${feedback || "(reviewers gave no specific issues; tighten the weakest part)"}`
|
|
|
666
736
|
const { peerPrompt, blindPrompt } = loop.prepareRound(state);
|
|
667
737
|
const roundNo = state.round;
|
|
668
738
|
const [blindRes, peerResults] = await Promise.all([
|
|
669
|
-
Promise.resolve().then(() => arbiter.ask({ ...req, prompt: blindPrompt })).then((r) => r, () => null),
|
|
670
|
-
askAll2(providers, { ...req, prompt: peerPrompt }, { logger, tool: "consensus" })
|
|
739
|
+
Promise.resolve().then(() => arbiter.ask(withOrientation(arbiter, { ...req, prompt: blindPrompt }, opts.orientationFiles))).then((r) => r, () => null),
|
|
740
|
+
askAll2(providers, { ...req, prompt: peerPrompt }, { logger, tool: "consensus", orientationFiles: opts.orientationFiles })
|
|
671
741
|
]);
|
|
672
742
|
state = loop.recordBlindVerdict(state, okText(blindRes) || "(blind pass unavailable)");
|
|
673
743
|
lastResults = peerResults.map(
|
|
@@ -732,6 +802,52 @@ ${feedback || "(reviewers gave no specific issues; tighten the weakest part)"}`
|
|
|
732
802
|
}
|
|
733
803
|
});
|
|
734
804
|
|
|
805
|
+
// ../../core/orientation.js
|
|
806
|
+
var require_orientation = __commonJS({
|
|
807
|
+
"../../core/orientation.js"(exports2, module2) {
|
|
808
|
+
"use strict";
|
|
809
|
+
var fs = require("node:fs");
|
|
810
|
+
var path = require("node:path");
|
|
811
|
+
var ORIENTATION_CANDIDATES = [
|
|
812
|
+
"CLAUDE.md",
|
|
813
|
+
"AGENTS.md",
|
|
814
|
+
"README.md",
|
|
815
|
+
"package.json",
|
|
816
|
+
"pyproject.toml",
|
|
817
|
+
"Cargo.toml",
|
|
818
|
+
"go.mod",
|
|
819
|
+
"tsconfig.json",
|
|
820
|
+
"main.tf"
|
|
821
|
+
];
|
|
822
|
+
var DEFAULT_MAX_FILES = 6;
|
|
823
|
+
function resolveOrientationFiles(cwd, opts = {}) {
|
|
824
|
+
const base = cwd || process.cwd();
|
|
825
|
+
const max = Number.isInteger(opts.maxFiles) && /** @type {number} */
|
|
826
|
+
opts.maxFiles > 0 ? (
|
|
827
|
+
/** @type {number} */
|
|
828
|
+
opts.maxFiles
|
|
829
|
+
) : DEFAULT_MAX_FILES;
|
|
830
|
+
const candidates = opts.candidates || ORIENTATION_CANDIDATES;
|
|
831
|
+
const out = [];
|
|
832
|
+
for (const name of candidates) {
|
|
833
|
+
if (out.length >= max) break;
|
|
834
|
+
const abs = path.join(base, name);
|
|
835
|
+
try {
|
|
836
|
+
if (fs.statSync(abs).isFile()) out.push({ path: abs });
|
|
837
|
+
} catch {
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
return out;
|
|
841
|
+
}
|
|
842
|
+
function orientationFilesFor2(config, cwd) {
|
|
843
|
+
const o = config && config.orientation;
|
|
844
|
+
if (!o || o.enabled !== true) return void 0;
|
|
845
|
+
return resolveOrientationFiles(cwd, { maxFiles: o.maxFiles });
|
|
846
|
+
}
|
|
847
|
+
module2.exports = { resolveOrientationFiles, orientationFilesFor: orientationFilesFor2, ORIENTATION_CANDIDATES, DEFAULT_MAX_FILES };
|
|
848
|
+
}
|
|
849
|
+
});
|
|
850
|
+
|
|
735
851
|
// ../../core/prompts/index.js
|
|
736
852
|
var require_prompts = __commonJS({
|
|
737
853
|
"../../core/prompts/index.js"(exports2, module2) {
|
|
@@ -1443,7 +1559,7 @@ var require_openai_compatible = __commonJS({
|
|
|
1443
1559
|
/** @type {any} */
|
|
1444
1560
|
{
|
|
1445
1561
|
name,
|
|
1446
|
-
capabilities: { canImplement: false, fileUpload: false, multiTurn: true },
|
|
1562
|
+
capabilities: { canImplement: false, fileUpload: false, multiTurn: true, walksFilesystem: false },
|
|
1447
1563
|
/** Test-only: current number of cached sessions. */
|
|
1448
1564
|
get __sessionCount() {
|
|
1449
1565
|
return sessions.size;
|
|
@@ -1525,7 +1641,7 @@ var require_grok = __commonJS({
|
|
|
1525
1641
|
name: "grok",
|
|
1526
1642
|
// multiTurn is not wired through Core (runGrok/runWithFiles return no threadId),
|
|
1527
1643
|
// so report false to match reality.
|
|
1528
|
-
capabilities: { canImplement: false, fileUpload: true, multiTurn: false },
|
|
1644
|
+
capabilities: { canImplement: false, fileUpload: true, multiTurn: false, walksFilesystem: false },
|
|
1529
1645
|
async health() {
|
|
1530
1646
|
return process.env.XAI_API_KEY ? { ok: true } : { ok: false, reason: "XAI_API_KEY unset" };
|
|
1531
1647
|
},
|
|
@@ -1585,7 +1701,7 @@ var require_antigravity = __commonJS({
|
|
|
1585
1701
|
const model = opts.model || process.env.GEMINI_DEFAULT_MODEL || "auto-gemini-3";
|
|
1586
1702
|
return {
|
|
1587
1703
|
name: "gemini",
|
|
1588
|
-
capabilities: { canImplement: true, fileUpload: false, multiTurn: true },
|
|
1704
|
+
capabilities: { canImplement: true, fileUpload: false, multiTurn: true, walksFilesystem: true },
|
|
1589
1705
|
async health() {
|
|
1590
1706
|
return typeof bridge.runGemini === "function" ? { ok: true } : { ok: false, reason: "agy bridge unavailable" };
|
|
1591
1707
|
},
|
|
@@ -1666,7 +1782,7 @@ var require_codex = __commonJS({
|
|
|
1666
1782
|
const model = opts.model || "default";
|
|
1667
1783
|
return {
|
|
1668
1784
|
name: "codex",
|
|
1669
|
-
capabilities: { canImplement: true, fileUpload: false, multiTurn: false },
|
|
1785
|
+
capabilities: { canImplement: true, fileUpload: false, multiTurn: false, walksFilesystem: true },
|
|
1670
1786
|
// Option A: no threadId continuity
|
|
1671
1787
|
async health() {
|
|
1672
1788
|
return { ok: true };
|
|
@@ -4525,6 +4641,7 @@ var require_openrouter = __commonJS({
|
|
|
4525
4641
|
// index.js
|
|
4526
4642
|
var { makeRegistry, pinAlias } = require_registry();
|
|
4527
4643
|
var { askAll, askOne, consensus, runToConvergence } = require_orchestrate();
|
|
4644
|
+
var { orientationFilesFor } = require_orientation();
|
|
4528
4645
|
var { PROMPTS } = require_prompts();
|
|
4529
4646
|
var analyzeCore = require_analyze();
|
|
4530
4647
|
var ADVISORY = { readOnlyHint: true };
|
|
@@ -4801,6 +4918,9 @@ function buildServer({ providers, getConfig, getConfigError, sessionsDir, notify
|
|
|
4801
4918
|
if (!persona) return request;
|
|
4802
4919
|
return { ...request, developerInstructions: persona };
|
|
4803
4920
|
}
|
|
4921
|
+
function orient(req) {
|
|
4922
|
+
return orientationFilesFor(getConfig(), req && req.cwd);
|
|
4923
|
+
}
|
|
4804
4924
|
function sessionsCfg() {
|
|
4805
4925
|
const c = getConfig() || {};
|
|
4806
4926
|
const s = c.sessions || {};
|
|
@@ -4898,7 +5018,7 @@ function buildServer({ providers, getConfig, getConfigError, sessionsDir, notify
|
|
|
4898
5018
|
lg.logEvent({ event: "dispatch_start", at: Date.now(), tool: "ask-all", voices: selected.length });
|
|
4899
5019
|
} catch {
|
|
4900
5020
|
}
|
|
4901
|
-
const results = await askAll(selected, withPersona(req, expert), { logger: lg, tool: "ask-all", cache: opts.noCache ? void 0 : resultCache });
|
|
5021
|
+
const results = await askAll(selected, withPersona(req, expert), { logger: lg, tool: "ask-all", cache: opts.noCache ? void 0 : resultCache, orientationFiles: orient(req) });
|
|
4902
5022
|
return {
|
|
4903
5023
|
payload: { results, omitted },
|
|
4904
5024
|
parts: { opinions: results, blindVerdict: null, verdict: null, arbiter: null, warnings: [] }
|
|
@@ -4916,13 +5036,13 @@ function buildServer({ providers, getConfig, getConfigError, sessionsDir, notify
|
|
|
4916
5036
|
const resolved = await resolveArbiter(arbiterSpec, selected, registry, getConfig);
|
|
4917
5037
|
if (resolved.warning) warnings.push(resolved.warning);
|
|
4918
5038
|
if (resolved.mode === "host") {
|
|
4919
|
-
const opinions = await askAll(selected, withPersona(req, expert), { logger: currentLogger(), tool: "consensus" });
|
|
5039
|
+
const opinions = await askAll(selected, withPersona(req, expert), { logger: currentLogger(), tool: "consensus", orientationFiles: orient(req) });
|
|
4920
5040
|
const arbiter2 = { mode: "host" };
|
|
4921
5041
|
const body = { opinions, blindVerdict: null, verdict: null, arbiter: arbiter2, warnings };
|
|
4922
5042
|
return { payload: body, parts: body };
|
|
4923
5043
|
}
|
|
4924
5044
|
if (!resolved.provider) {
|
|
4925
|
-
const out2 = await consensus(selected, withPersona(req, expert), { arbiterInstructions: PROMPTS.arbiter, logger: currentLogger() });
|
|
5045
|
+
const out2 = await consensus(selected, withPersona(req, expert), { arbiterInstructions: PROMPTS.arbiter, logger: currentLogger(), orientationFiles: orient(req) });
|
|
4926
5046
|
const arbiter2 = { mode: "server", provider: null };
|
|
4927
5047
|
return {
|
|
4928
5048
|
payload: { opinions: out2.opinions, blindVerdict: out2.blindVerdict, verdict: out2.verdict, error: out2.error, arbiter: arbiter2, warnings },
|
|
@@ -4935,7 +5055,7 @@ function buildServer({ providers, getConfig, getConfigError, sessionsDir, notify
|
|
|
4935
5055
|
peers = selected;
|
|
4936
5056
|
warnings.push(`panel too small to exclude arbiter '${arbiterP.name}'; kept it in the peer panel (floor of 2)`);
|
|
4937
5057
|
}
|
|
4938
|
-
const out = await consensus(peers, withPersona(req, expert), { arbiter: arbiterP, arbiterInstructions: PROMPTS.arbiter, blindVote, logger: currentLogger() });
|
|
5058
|
+
const out = await consensus(peers, withPersona(req, expert), { arbiter: arbiterP, arbiterInstructions: PROMPTS.arbiter, blindVote, logger: currentLogger(), orientationFiles: orient(req) });
|
|
4939
5059
|
const arbiter = { mode: "server", provider: arbiterP.name };
|
|
4940
5060
|
return {
|
|
4941
5061
|
payload: { opinions: out.opinions, blindVerdict: out.blindVerdict, verdict: out.verdict, error: out.error, arbiter, warnings },
|
|
@@ -4965,7 +5085,7 @@ function buildServer({ providers, getConfig, getConfigError, sessionsDir, notify
|
|
|
4965
5085
|
}
|
|
4966
5086
|
const maxRounds = Number.isInteger(maxRoundsOverride) && /** @type {number} */
|
|
4967
5087
|
maxRoundsOverride > 0 ? maxRoundsOverride : Number.isInteger(cc.maxRounds) && cc.maxRounds > 0 ? cc.maxRounds : void 0;
|
|
4968
|
-
const out = await runToConvergence(peers, withPersona(req, expert), { arbiter: arbiterP, maxRounds, logger: currentLogger() });
|
|
5088
|
+
const out = await runToConvergence(peers, withPersona(req, expert), { arbiter: arbiterP, maxRounds, logger: currentLogger(), orientationFiles: orient(req) });
|
|
4969
5089
|
const allWarnings = out.error ? warnings.concat([`loop: ${out.error}`]) : warnings;
|
|
4970
5090
|
const rounds = Array.isArray(out.rounds) ? out.rounds.length : 0;
|
|
4971
5091
|
const arbiter = { mode: "server", provider: arbiterP.name };
|
|
@@ -5106,7 +5226,7 @@ function buildServer({ providers, getConfig, getConfigError, sessionsDir, notify
|
|
|
5106
5226
|
lg.logEvent({ event: "dispatch_start", at: Date.now(), tool: "consensus", round: cur.round, voices: selected.length });
|
|
5107
5227
|
} catch {
|
|
5108
5228
|
}
|
|
5109
|
-
const peerResults = await askAll(selected, withPersona(peerReq, ex), { logger: lg, tool: "consensus" });
|
|
5229
|
+
const peerResults = await askAll(selected, withPersona(peerReq, ex), { logger: lg, tool: "consensus", orientationFiles: orient(peerReq) });
|
|
5110
5230
|
const results = peerResults.map(
|
|
5111
5231
|
(r) => r.isError ? { source: r.provider, isError: true, errorKind: r.errorKind, verdict: null, criticalIssues: [], model: r.model, reasoningEffort: r.reasoningEffort ?? null, ms: r.ms } : { ...parseReview(typeof r.text === "string" ? r.text : ""), source: r.provider, isError: false, model: r.model, reasoningEffort: r.reasoningEffort ?? null, ms: r.ms }
|
|
5112
5232
|
);
|
|
@@ -5230,7 +5350,7 @@ function buildServer({ providers, getConfig, getConfigError, sessionsDir, notify
|
|
|
5230
5350
|
if (!p) {
|
|
5231
5351
|
return jsonResult({ error: `provider "${want}" is not in the active panel`, panel: selected.map((x) => x.name) });
|
|
5232
5352
|
}
|
|
5233
|
-
const result = await askOne(p, withPersona(req, expert), { logger: currentLogger(), tool: "ask-one", cache: resultCache });
|
|
5353
|
+
const result = await askOne(p, withPersona(req, expert), { logger: currentLogger(), tool: "ask-one", cache: resultCache, orientationFiles: orient(req) });
|
|
5234
5354
|
return jsonResult({ result });
|
|
5235
5355
|
}
|
|
5236
5356
|
if (name === "analyze") {
|
|
@@ -5299,12 +5419,12 @@ function buildServer({ providers, getConfig, getConfigError, sessionsDir, notify
|
|
|
5299
5419
|
if (Object.prototype.hasOwnProperty.call(ASK_PROVIDER, name)) {
|
|
5300
5420
|
const p = registry.get(ASK_PROVIDER[name]);
|
|
5301
5421
|
if (!p) return { content: [{ type: "text", text: JSON.stringify({ error: `provider ${ASK_PROVIDER[name]} not registered` }) }] };
|
|
5302
|
-
const result = await askOne(p, withPersona(req, expert), { logger: currentLogger(), tool: "ask-one", cache: resultCache });
|
|
5422
|
+
const result = await askOne(p, withPersona(req, expert), { logger: currentLogger(), tool: "ask-one", cache: resultCache, orientationFiles: orient(req) });
|
|
5303
5423
|
return { content: [{ type: "text", text: JSON.stringify({ result }) }] };
|
|
5304
5424
|
}
|
|
5305
5425
|
if (EXPERTS.includes(name)) {
|
|
5306
5426
|
const { providers: selected } = registry.selectForAskAll({ config: getConfig(), expert: name });
|
|
5307
|
-
const results = await askAll(selected, withPersona({ ...req, expert: name }, expert), { logger: currentLogger(), tool: name, cache: resultCache });
|
|
5427
|
+
const results = await askAll(selected, withPersona({ ...req, expert: name }, expert), { logger: currentLogger(), tool: name, cache: resultCache, orientationFiles: orient(req) });
|
|
5308
5428
|
return { content: [{ type: "text", text: JSON.stringify({ results }) }] };
|
|
5309
5429
|
}
|
|
5310
5430
|
throw new Error(`unknown tool: ${name}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antonbabenko/deliberation-mcp",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.6.1",
|
|
4
4
|
"description": "Deliberation for Claude Code and any MCP host - GPT, Gemini, Grok, and OpenRouter expert subagents.",
|
|
5
5
|
"mcpName": "io.github.antonbabenko/deliberation",
|
|
6
6
|
"repository": { "type": "git", "url": "git+https://github.com/antonbabenko/deliberation.git", "directory": "server/mcp" },
|