crosscheck-mcp 0.2.30 → 0.2.31
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/browser-ext.cjs +1106 -981
- package/dist/browser-ext.cjs.map +1 -1
- package/dist/browser-ext.d.cts +2 -0
- package/dist/browser-ext.d.ts +2 -0
- package/dist/browser-ext.js +1106 -981
- package/dist/browser-ext.js.map +1 -1
- package/dist/embed.cjs +363 -235
- package/dist/embed.cjs.map +1 -1
- package/dist/embed.d.cts +2 -1
- package/dist/embed.d.ts +2 -1
- package/dist/embed.js +363 -235
- package/dist/embed.js.map +1 -1
- package/dist/node-stdio.cjs +335 -202
- package/dist/node-stdio.cjs.map +1 -1
- package/dist/node-stdio.js +335 -202
- package/dist/node-stdio.js.map +1 -1
- package/package.json +1 -1
package/dist/embed.js
CHANGED
|
@@ -6,11 +6,35 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
6
6
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
7
|
});
|
|
8
8
|
|
|
9
|
-
// src/
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
// src/core/retarget.ts
|
|
10
|
+
function retargetProvider(p, newModel, fallbackModels) {
|
|
11
|
+
const chain = fallbackModels && fallbackModels.length > 0 ? fallbackModels : void 0;
|
|
12
|
+
if (p.model === newModel && chain === void 0) return p;
|
|
13
|
+
return {
|
|
14
|
+
name: p.name,
|
|
15
|
+
model: newModel,
|
|
16
|
+
...chain ? { fallbackModels: chain } : {},
|
|
17
|
+
send: (args) => p.send({ ...args, modelOverride: newModel })
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
async function loadProviderWeights(storage, names) {
|
|
21
|
+
const out = {};
|
|
22
|
+
for (const raw of names) {
|
|
23
|
+
const name = raw.toLowerCase();
|
|
24
|
+
if (name in out) continue;
|
|
25
|
+
const row = await storage.getProviderStats(name);
|
|
26
|
+
if (!row) {
|
|
27
|
+
out[name] = 0.5;
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const total = row.wins + row.losses + row.abstains;
|
|
31
|
+
out[name] = total <= 0 ? 0.5 : (row.wins + 0.5 * row.abstains) / total;
|
|
32
|
+
}
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// src/core/super-mode.ts
|
|
37
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
14
38
|
|
|
15
39
|
// src/core/pricing.ts
|
|
16
40
|
import { readFileSync } from "fs";
|
|
@@ -1300,12 +1324,238 @@ function makeGeminiProvider(model, apiKey, opts, fallbackModels = []) {
|
|
|
1300
1324
|
};
|
|
1301
1325
|
}
|
|
1302
1326
|
|
|
1327
|
+
// src/core/reasoning-upgrade.ts
|
|
1328
|
+
var UPGRADE_MODEL = "claude-fable-5";
|
|
1329
|
+
var UPGRADE_LABEL = "Fable 5";
|
|
1330
|
+
function isUpgradeRequested(args) {
|
|
1331
|
+
if (args["upgrade"] === true) return true;
|
|
1332
|
+
const reasoning = args["reasoning"];
|
|
1333
|
+
if (typeof reasoning === "string" && reasoning.trim().toLowerCase() === "max") {
|
|
1334
|
+
return true;
|
|
1335
|
+
}
|
|
1336
|
+
const model = args["model"];
|
|
1337
|
+
if (typeof model === "string") {
|
|
1338
|
+
const m = model.trim().toLowerCase();
|
|
1339
|
+
if (m === "fable5" || m === "fable-5" || m === "fable" || m === UPGRADE_MODEL) {
|
|
1340
|
+
return true;
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
return false;
|
|
1344
|
+
}
|
|
1345
|
+
var HEAVY_TERMS = [
|
|
1346
|
+
/\bprov(e|ing|en)\b|\bproof\b|\btheorem\b|\bderiv(e|ation)\b/i,
|
|
1347
|
+
/\barchitect(ure|ing)?\b|\bdesign\s+(a|the|an)\b|\bhigh[-\s]?level\s+design\b/i,
|
|
1348
|
+
/\btrade[-\s]?offs?\b|\bpros?\s+and\s+cons?\b|\bweigh\b/i,
|
|
1349
|
+
/\boptimi[sz]e\b|\bcomplexity\b|\bO\(|\balgorithm(ic)?\b/i,
|
|
1350
|
+
/\brace\s+condition\b|\bconcurren(t|cy)\b|\bdeadlock\b|\bdistributed\b|\bconsensus\b/i,
|
|
1351
|
+
/\broot[-\s]?cause\b|\bdebug(ging)?\b|\bwhy\s+(does|is|would|might)\b/i,
|
|
1352
|
+
/\bsecurity\b|\bthreat\s+model\b|\bexploit\b|\bvulnerabilit(y|ies)\b/i,
|
|
1353
|
+
/\bmigrat(e|ion)\b|\brefactor\b|\bre[-\s]?architect\b/i,
|
|
1354
|
+
/\binvariant\b|\bcorrectness\b|\bedge\s+cases?\b|\bformal(ly)?\b/i,
|
|
1355
|
+
/\bstrateg(y|ic|ies)\b|\bplan\s+(the|a|an|out)\b|\broadmap\b/i,
|
|
1356
|
+
/\breason\s+(through|about)\b|\bstep[-\s]?by[-\s]?step\b|\bthink\s+deeply\b/i,
|
|
1357
|
+
/\bnp[-\s]?(hard|complete)\b|\bgraph\b|\bstate\s+machine\b|\bconstraint\b/i
|
|
1358
|
+
];
|
|
1359
|
+
var DIFFICULTY_TERMS = /\b(hard|tricky|subtle|complex|complicated|non[-\s]?trivial|thorny|gnarly|difficult|deep)\b/i;
|
|
1360
|
+
function assessReasoning(text) {
|
|
1361
|
+
const s = typeof text === "string" ? text : "";
|
|
1362
|
+
const signals = [];
|
|
1363
|
+
let score = 0;
|
|
1364
|
+
let termHits = 0;
|
|
1365
|
+
for (const re of HEAVY_TERMS) {
|
|
1366
|
+
if (re.test(s)) termHits += 1;
|
|
1367
|
+
}
|
|
1368
|
+
if (termHits > 0) {
|
|
1369
|
+
const add = Math.min(termHits, 4);
|
|
1370
|
+
score += add;
|
|
1371
|
+
signals.push(`${termHits} reasoning cue${termHits === 1 ? "" : "s"}`);
|
|
1372
|
+
}
|
|
1373
|
+
if (DIFFICULTY_TERMS.test(s)) {
|
|
1374
|
+
score += 1;
|
|
1375
|
+
signals.push("explicit difficulty marker");
|
|
1376
|
+
}
|
|
1377
|
+
const words = s.split(/\s+/).filter(Boolean).length;
|
|
1378
|
+
if (words >= 120) {
|
|
1379
|
+
score += 2;
|
|
1380
|
+
signals.push("long, detailed prompt");
|
|
1381
|
+
} else if (words >= 50) {
|
|
1382
|
+
score += 1;
|
|
1383
|
+
signals.push("substantial prompt");
|
|
1384
|
+
}
|
|
1385
|
+
const constraints = (s.match(/\b(must|should|need to|ensure|require[ds]?|constraint)\b/gi) ?? []).length + (s.match(/(^|\n)\s*(?:[-*]|\d+[.)])\s+/g) ?? []).length;
|
|
1386
|
+
if (constraints >= 3) {
|
|
1387
|
+
score += 1;
|
|
1388
|
+
signals.push(`${constraints} constraints/steps`);
|
|
1389
|
+
}
|
|
1390
|
+
const heavy = score >= 3;
|
|
1391
|
+
const reason = heavy ? `Task looks reasoning-heavy (${signals.join(", ") || "score " + score}).` : `Task looks routine (score ${score}).`;
|
|
1392
|
+
return { heavy, score, reason, signals };
|
|
1393
|
+
}
|
|
1394
|
+
function buildSuggestedUpgrade(toolName, assessment) {
|
|
1395
|
+
return {
|
|
1396
|
+
model: UPGRADE_MODEL,
|
|
1397
|
+
label: UPGRADE_LABEL,
|
|
1398
|
+
reason: assessment.reason,
|
|
1399
|
+
how: `re-run \`${toolName}\` with reasoning:"max" (or upgrade:true) to route the lead reasoning seat to ${UPGRADE_LABEL}, and \u2014 when an OpenAI key is configured \u2014 add an OpenAI second-opinion pass that ${UPGRADE_LABEL} weighs before finalizing (the result names which model ran). Other panel seats stay on their normal models.`
|
|
1400
|
+
};
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1403
|
+
// src/core/super-mode.ts
|
|
1404
|
+
var SUPER_MODELS = {
|
|
1405
|
+
// Fable 5.1 verified present on the account; 5 as the fallback for accounts
|
|
1406
|
+
// that haven't been granted 5.1 yet.
|
|
1407
|
+
anthropic: ["claude-fable-5-1", UPGRADE_MODEL],
|
|
1408
|
+
// Astra is live (verified against the account's model list 2026-09-23).
|
|
1409
|
+
// The fallback is named explicitly rather than reusing CO_REASON_MODEL:
|
|
1410
|
+
// that constant means "OpenAI's top reasoning model" for the max-reasoning
|
|
1411
|
+
// co-reasoner, which is a different question from "what should super fall
|
|
1412
|
+
// back to". Sharing the symbol silently coupled two unrelated decisions.
|
|
1413
|
+
openai: ["gpt-6-astra", "gpt-6-sol"],
|
|
1414
|
+
// Explicitly left as-is per product decision. Note grok-4-latest is not in
|
|
1415
|
+
// xAI's published model list, but it resolves in practice — real panel calls
|
|
1416
|
+
// on it succeeded as recently as 2026-08-30 — so it is an unlisted alias
|
|
1417
|
+
// rather than a dead id.
|
|
1418
|
+
xai: [DEFAULT_MODELS["xai"]],
|
|
1419
|
+
// 3.8 Flash is now BOTH the everyday default and the super pick for Gemini,
|
|
1420
|
+
// so this can no longer borrow DEFAULT_MODELS as its fallback — that would
|
|
1421
|
+
// repeat the same model and retry one that just failed. Named explicitly.
|
|
1422
|
+
gemini: ["gemini-3.8-flash", "gemini-3.1-pro-preview"],
|
|
1423
|
+
kimi: [DEFAULT_MODELS["kimi"]],
|
|
1424
|
+
qwen: [DEFAULT_MODELS["qwen"]]
|
|
1425
|
+
};
|
|
1426
|
+
var SUPER_ENV_VARS = {
|
|
1427
|
+
anthropic: "ANTHROPIC_SUPER_MODEL",
|
|
1428
|
+
openai: "OPENAI_SUPER_MODEL",
|
|
1429
|
+
xai: "XAI_SUPER_MODEL",
|
|
1430
|
+
gemini: "GEMINI_SUPER_MODEL",
|
|
1431
|
+
kimi: "KIMI_SUPER_MODEL",
|
|
1432
|
+
qwen: "QWEN_SUPER_MODEL",
|
|
1433
|
+
mistral: "MISTRAL_SUPER_MODEL",
|
|
1434
|
+
groq: "GROQ_SUPER_MODEL",
|
|
1435
|
+
deepseek: "DEEPSEEK_SUPER_MODEL"
|
|
1436
|
+
};
|
|
1437
|
+
function parseChain(v) {
|
|
1438
|
+
if (!v) return [];
|
|
1439
|
+
const out = [];
|
|
1440
|
+
for (const raw of v.split(",")) {
|
|
1441
|
+
const m = raw.trim();
|
|
1442
|
+
if (m && !out.includes(m)) out.push(m);
|
|
1443
|
+
}
|
|
1444
|
+
return out;
|
|
1445
|
+
}
|
|
1446
|
+
var superEnvStore = new AsyncLocalStorage();
|
|
1447
|
+
function withSuperEnv(env, fn) {
|
|
1448
|
+
return superEnvStore.run(env, fn);
|
|
1449
|
+
}
|
|
1450
|
+
var currentEnv = () => superEnvStore.getStore() ?? process.env;
|
|
1451
|
+
function superChainFor(provider, env = currentEnv()) {
|
|
1452
|
+
const varName = SUPER_ENV_VARS[provider];
|
|
1453
|
+
const user = varName ? parseChain(env[varName]) : [];
|
|
1454
|
+
if (user.length > 0) {
|
|
1455
|
+
const fallbacks = varName ? parseChain(env[`${varName}_FALLBACKS`]) : [];
|
|
1456
|
+
return [...user, ...fallbacks.filter((m) => !user.includes(m))];
|
|
1457
|
+
}
|
|
1458
|
+
return SUPER_MODELS[provider] ?? [];
|
|
1459
|
+
}
|
|
1460
|
+
function superPrimary(provider, env = currentEnv()) {
|
|
1461
|
+
return superChainFor(provider, env)[0];
|
|
1462
|
+
}
|
|
1463
|
+
var SUPER_PROVIDER_NAMES = Object.keys(SUPER_MODELS);
|
|
1464
|
+
function isSuperRequested(args) {
|
|
1465
|
+
return args["super"] === true;
|
|
1466
|
+
}
|
|
1467
|
+
function retargetForSuper(p, env = currentEnv()) {
|
|
1468
|
+
const chain = superChainFor(p.name, env);
|
|
1469
|
+
if (chain.length === 0) return p;
|
|
1470
|
+
const [primary, ...fallbacks] = chain;
|
|
1471
|
+
return retargetProvider(p, primary, fallbacks);
|
|
1472
|
+
}
|
|
1473
|
+
var SUPER_BUDGET_MULTIPLIER = 3;
|
|
1474
|
+
var SUPER_BUDGET_CEILING = 16e3;
|
|
1475
|
+
function superBudget(base) {
|
|
1476
|
+
return Math.min(base * SUPER_BUDGET_MULTIPLIER, SUPER_BUDGET_CEILING);
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
// src/core/moderator.ts
|
|
1480
|
+
var DEFAULT_MODERATOR = "anthropic";
|
|
1481
|
+
var PROVIDER_ALIASES = {
|
|
1482
|
+
grok: "xai",
|
|
1483
|
+
claude: "anthropic",
|
|
1484
|
+
google: "gemini",
|
|
1485
|
+
chatgpt: "openai",
|
|
1486
|
+
gpt: "openai",
|
|
1487
|
+
moonshot: "kimi"
|
|
1488
|
+
};
|
|
1489
|
+
function parseModeratorSpec(raw) {
|
|
1490
|
+
if (typeof raw !== "string") return null;
|
|
1491
|
+
const s = raw.trim();
|
|
1492
|
+
if (!s) return null;
|
|
1493
|
+
const i = s.indexOf(":");
|
|
1494
|
+
const providerPart = (i < 0 ? s : s.slice(0, i)).trim().toLowerCase();
|
|
1495
|
+
const modelPart = i < 0 ? "" : s.slice(i + 1).trim();
|
|
1496
|
+
if (!providerPart) return null;
|
|
1497
|
+
return {
|
|
1498
|
+
provider: PROVIDER_ALIASES[providerPart] ?? providerPart,
|
|
1499
|
+
model: modelPart || null
|
|
1500
|
+
};
|
|
1501
|
+
}
|
|
1502
|
+
function moderatorProviderName(raw, fallback = DEFAULT_MODERATOR) {
|
|
1503
|
+
return (parseModeratorSpec(raw) ?? parseModeratorSpec(fallback))?.provider ?? DEFAULT_MODERATOR;
|
|
1504
|
+
}
|
|
1505
|
+
function pickModeratorSpec(...candidates) {
|
|
1506
|
+
for (const c of candidates) {
|
|
1507
|
+
const s = parseModeratorSpec(c);
|
|
1508
|
+
if (s) return s;
|
|
1509
|
+
}
|
|
1510
|
+
return { provider: DEFAULT_MODERATOR, model: null };
|
|
1511
|
+
}
|
|
1512
|
+
function resolveModerator(providers, ...candidates) {
|
|
1513
|
+
const spec = pickModeratorSpec(...candidates);
|
|
1514
|
+
const base = providers[spec.provider];
|
|
1515
|
+
if (!base) return { provider: void 0, spec, pinned: false };
|
|
1516
|
+
if (!spec.model) return { provider: base, spec, pinned: false };
|
|
1517
|
+
return { provider: retargetProvider(base, spec.model), spec, pinned: true };
|
|
1518
|
+
}
|
|
1519
|
+
function synthesisSeat(o) {
|
|
1520
|
+
const { moderator, pinned, superRequested, upgradeRequested } = o;
|
|
1521
|
+
const wantsMore = superRequested || upgradeRequested;
|
|
1522
|
+
if (!wantsMore) return { provider: moderator, upgraded: false, label: null, skipReason: null };
|
|
1523
|
+
if (pinned) {
|
|
1524
|
+
return {
|
|
1525
|
+
provider: moderator,
|
|
1526
|
+
upgraded: false,
|
|
1527
|
+
label: null,
|
|
1528
|
+
skipReason: `the moderator is pinned to ${moderator.name}:${moderator.model}; a pinned model is used as-is.`
|
|
1529
|
+
};
|
|
1530
|
+
}
|
|
1531
|
+
if (moderator.name === "anthropic" && !superRequested) {
|
|
1532
|
+
return { provider: retargetProvider(moderator, UPGRADE_MODEL), upgraded: true, label: UPGRADE_LABEL, skipReason: null };
|
|
1533
|
+
}
|
|
1534
|
+
if (superChainFor(moderator.name).length === 0) {
|
|
1535
|
+
return {
|
|
1536
|
+
provider: moderator,
|
|
1537
|
+
upgraded: false,
|
|
1538
|
+
label: null,
|
|
1539
|
+
skipReason: `no flagship model is known for ${moderator.name}; the moderator ran at ${moderator.model}.`
|
|
1540
|
+
};
|
|
1541
|
+
}
|
|
1542
|
+
const seat = retargetForSuper(moderator);
|
|
1543
|
+
const label = moderator.name === "anthropic" ? UPGRADE_LABEL : seat.model;
|
|
1544
|
+
return { provider: seat, upgraded: true, label, skipReason: null };
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1547
|
+
// src/entrypoints/embed.ts
|
|
1548
|
+
import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
|
|
1549
|
+
import { existsSync as existsSync11 } from "fs";
|
|
1550
|
+
import path12 from "path";
|
|
1551
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1552
|
+
|
|
1303
1553
|
// src/tools/index.ts
|
|
1304
1554
|
import { z } from "zod";
|
|
1305
1555
|
|
|
1306
1556
|
// src/server-meta.ts
|
|
1307
1557
|
var SERVER_NAME = "crosscheck-agent";
|
|
1308
|
-
var SERVER_VERSION = true ? "0.2.
|
|
1558
|
+
var SERVER_VERSION = true ? "0.2.31" : "0.0.0-dev";
|
|
1309
1559
|
|
|
1310
1560
|
// src/tools/audit.ts
|
|
1311
1561
|
import { readdirSync, readFileSync as readFileSync3, statSync } from "fs";
|
|
@@ -1988,33 +2238,6 @@ function operatorCeiling(purpose, provider) {
|
|
|
1988
2238
|
return null;
|
|
1989
2239
|
}
|
|
1990
2240
|
|
|
1991
|
-
// src/core/retarget.ts
|
|
1992
|
-
function retargetProvider(p, newModel, fallbackModels) {
|
|
1993
|
-
const chain = fallbackModels && fallbackModels.length > 0 ? fallbackModels : void 0;
|
|
1994
|
-
if (p.model === newModel && chain === void 0) return p;
|
|
1995
|
-
return {
|
|
1996
|
-
name: p.name,
|
|
1997
|
-
model: newModel,
|
|
1998
|
-
...chain ? { fallbackModels: chain } : {},
|
|
1999
|
-
send: (args) => p.send({ ...args, modelOverride: newModel })
|
|
2000
|
-
};
|
|
2001
|
-
}
|
|
2002
|
-
async function loadProviderWeights(storage, names) {
|
|
2003
|
-
const out = {};
|
|
2004
|
-
for (const raw of names) {
|
|
2005
|
-
const name = raw.toLowerCase();
|
|
2006
|
-
if (name in out) continue;
|
|
2007
|
-
const row = await storage.getProviderStats(name);
|
|
2008
|
-
if (!row) {
|
|
2009
|
-
out[name] = 0.5;
|
|
2010
|
-
continue;
|
|
2011
|
-
}
|
|
2012
|
-
const total = row.wins + row.losses + row.abstains;
|
|
2013
|
-
out[name] = total <= 0 ? 0.5 : (row.wins + 0.5 * row.abstains) / total;
|
|
2014
|
-
}
|
|
2015
|
-
return out;
|
|
2016
|
-
}
|
|
2017
|
-
|
|
2018
2241
|
// src/core/model-fallback.ts
|
|
2019
2242
|
async function sendWithModelFallback(provider, args) {
|
|
2020
2243
|
const chain = [provider.model, ...provider.fallbackModels ?? []];
|
|
@@ -3081,82 +3304,6 @@ function selectForDifficulty(args) {
|
|
|
3081
3304
|
};
|
|
3082
3305
|
}
|
|
3083
3306
|
|
|
3084
|
-
// src/core/reasoning-upgrade.ts
|
|
3085
|
-
var UPGRADE_MODEL = "claude-fable-5";
|
|
3086
|
-
var UPGRADE_LABEL = "Fable 5";
|
|
3087
|
-
function isUpgradeRequested(args) {
|
|
3088
|
-
if (args["upgrade"] === true) return true;
|
|
3089
|
-
const reasoning = args["reasoning"];
|
|
3090
|
-
if (typeof reasoning === "string" && reasoning.trim().toLowerCase() === "max") {
|
|
3091
|
-
return true;
|
|
3092
|
-
}
|
|
3093
|
-
const model = args["model"];
|
|
3094
|
-
if (typeof model === "string") {
|
|
3095
|
-
const m = model.trim().toLowerCase();
|
|
3096
|
-
if (m === "fable5" || m === "fable-5" || m === "fable" || m === UPGRADE_MODEL) {
|
|
3097
|
-
return true;
|
|
3098
|
-
}
|
|
3099
|
-
}
|
|
3100
|
-
return false;
|
|
3101
|
-
}
|
|
3102
|
-
var HEAVY_TERMS = [
|
|
3103
|
-
/\bprov(e|ing|en)\b|\bproof\b|\btheorem\b|\bderiv(e|ation)\b/i,
|
|
3104
|
-
/\barchitect(ure|ing)?\b|\bdesign\s+(a|the|an)\b|\bhigh[-\s]?level\s+design\b/i,
|
|
3105
|
-
/\btrade[-\s]?offs?\b|\bpros?\s+and\s+cons?\b|\bweigh\b/i,
|
|
3106
|
-
/\boptimi[sz]e\b|\bcomplexity\b|\bO\(|\balgorithm(ic)?\b/i,
|
|
3107
|
-
/\brace\s+condition\b|\bconcurren(t|cy)\b|\bdeadlock\b|\bdistributed\b|\bconsensus\b/i,
|
|
3108
|
-
/\broot[-\s]?cause\b|\bdebug(ging)?\b|\bwhy\s+(does|is|would|might)\b/i,
|
|
3109
|
-
/\bsecurity\b|\bthreat\s+model\b|\bexploit\b|\bvulnerabilit(y|ies)\b/i,
|
|
3110
|
-
/\bmigrat(e|ion)\b|\brefactor\b|\bre[-\s]?architect\b/i,
|
|
3111
|
-
/\binvariant\b|\bcorrectness\b|\bedge\s+cases?\b|\bformal(ly)?\b/i,
|
|
3112
|
-
/\bstrateg(y|ic|ies)\b|\bplan\s+(the|a|an|out)\b|\broadmap\b/i,
|
|
3113
|
-
/\breason\s+(through|about)\b|\bstep[-\s]?by[-\s]?step\b|\bthink\s+deeply\b/i,
|
|
3114
|
-
/\bnp[-\s]?(hard|complete)\b|\bgraph\b|\bstate\s+machine\b|\bconstraint\b/i
|
|
3115
|
-
];
|
|
3116
|
-
var DIFFICULTY_TERMS = /\b(hard|tricky|subtle|complex|complicated|non[-\s]?trivial|thorny|gnarly|difficult|deep)\b/i;
|
|
3117
|
-
function assessReasoning(text) {
|
|
3118
|
-
const s = typeof text === "string" ? text : "";
|
|
3119
|
-
const signals = [];
|
|
3120
|
-
let score = 0;
|
|
3121
|
-
let termHits = 0;
|
|
3122
|
-
for (const re of HEAVY_TERMS) {
|
|
3123
|
-
if (re.test(s)) termHits += 1;
|
|
3124
|
-
}
|
|
3125
|
-
if (termHits > 0) {
|
|
3126
|
-
const add = Math.min(termHits, 4);
|
|
3127
|
-
score += add;
|
|
3128
|
-
signals.push(`${termHits} reasoning cue${termHits === 1 ? "" : "s"}`);
|
|
3129
|
-
}
|
|
3130
|
-
if (DIFFICULTY_TERMS.test(s)) {
|
|
3131
|
-
score += 1;
|
|
3132
|
-
signals.push("explicit difficulty marker");
|
|
3133
|
-
}
|
|
3134
|
-
const words = s.split(/\s+/).filter(Boolean).length;
|
|
3135
|
-
if (words >= 120) {
|
|
3136
|
-
score += 2;
|
|
3137
|
-
signals.push("long, detailed prompt");
|
|
3138
|
-
} else if (words >= 50) {
|
|
3139
|
-
score += 1;
|
|
3140
|
-
signals.push("substantial prompt");
|
|
3141
|
-
}
|
|
3142
|
-
const constraints = (s.match(/\b(must|should|need to|ensure|require[ds]?|constraint)\b/gi) ?? []).length + (s.match(/(^|\n)\s*(?:[-*]|\d+[.)])\s+/g) ?? []).length;
|
|
3143
|
-
if (constraints >= 3) {
|
|
3144
|
-
score += 1;
|
|
3145
|
-
signals.push(`${constraints} constraints/steps`);
|
|
3146
|
-
}
|
|
3147
|
-
const heavy = score >= 3;
|
|
3148
|
-
const reason = heavy ? `Task looks reasoning-heavy (${signals.join(", ") || "score " + score}).` : `Task looks routine (score ${score}).`;
|
|
3149
|
-
return { heavy, score, reason, signals };
|
|
3150
|
-
}
|
|
3151
|
-
function buildSuggestedUpgrade(toolName, assessment) {
|
|
3152
|
-
return {
|
|
3153
|
-
model: UPGRADE_MODEL,
|
|
3154
|
-
label: UPGRADE_LABEL,
|
|
3155
|
-
reason: assessment.reason,
|
|
3156
|
-
how: `re-run \`${toolName}\` with reasoning:"max" (or upgrade:true) to route the lead reasoning seat to ${UPGRADE_LABEL}, and \u2014 when an OpenAI key is configured \u2014 add an OpenAI second-opinion pass that ${UPGRADE_LABEL} weighs before finalizing (the result names which model ran). Other panel seats stay on their normal models.`
|
|
3157
|
-
};
|
|
3158
|
-
}
|
|
3159
|
-
|
|
3160
3307
|
// src/tools/audit.ts
|
|
3161
3308
|
var AUDIT_OBVIOUS_FAILURE_HIGH = 0.3;
|
|
3162
3309
|
var AUDIT_OBVIOUS_FAILURE_MED = 0.2;
|
|
@@ -3454,9 +3601,14 @@ ${rubricText}`;
|
|
|
3454
3601
|
);
|
|
3455
3602
|
}
|
|
3456
3603
|
const upgradeRequested = isUpgradeRequested(args);
|
|
3457
|
-
const
|
|
3458
|
-
const
|
|
3459
|
-
const
|
|
3604
|
+
const seat = synthesisSeat({ moderator: auditor, pinned: false, superRequested: false, upgradeRequested });
|
|
3605
|
+
const upgraded = seat.upgraded;
|
|
3606
|
+
const auditorForCall = seat.provider;
|
|
3607
|
+
const coProvider = pickCoReasoner(
|
|
3608
|
+
opts.providers,
|
|
3609
|
+
upgradeRequested,
|
|
3610
|
+
auditorForCall.name === "openai" ? auditorForCall.model : void 0
|
|
3611
|
+
);
|
|
3460
3612
|
const coReason = await coReasonThenInject({
|
|
3461
3613
|
provider: coProvider,
|
|
3462
3614
|
messages: msgs,
|
|
@@ -3539,15 +3691,16 @@ ${rubricText}`;
|
|
|
3539
3691
|
if (upgraded) {
|
|
3540
3692
|
result["reasoning_upgrade"] = {
|
|
3541
3693
|
applied: true,
|
|
3542
|
-
|
|
3543
|
-
|
|
3694
|
+
provider: auditorForCall.name,
|
|
3695
|
+
model: auditorForCall.model,
|
|
3696
|
+
label: seat.label ?? auditorForCall.model,
|
|
3544
3697
|
seat: "auditor",
|
|
3545
3698
|
...coReasoned ? { co_reasoner: { model: coProvider.model, label: coReasonLabel(coProvider.model) } } : {}
|
|
3546
3699
|
};
|
|
3547
3700
|
} else if (upgradeRequested) {
|
|
3548
3701
|
result["reasoning_upgrade"] = {
|
|
3549
3702
|
applied: false,
|
|
3550
|
-
reason:
|
|
3703
|
+
reason: seat.skipReason ?? "the auditor couldn't be upgraded."
|
|
3551
3704
|
};
|
|
3552
3705
|
} else {
|
|
3553
3706
|
const assessment = assessReasoning(
|
|
@@ -3630,7 +3783,7 @@ function pickAuditor(providers, exclude, explicit, moderatorName, allowlist, che
|
|
|
3630
3783
|
}
|
|
3631
3784
|
}
|
|
3632
3785
|
}
|
|
3633
|
-
const mod = providers
|
|
3786
|
+
const mod = resolveModerator(providers, moderatorName).provider;
|
|
3634
3787
|
if (mod !== void 0 && !exclude.has(mod.name) && (allowlist === null || allowlist.includes(mod.name))) {
|
|
3635
3788
|
return { auditor: mod, reason: null };
|
|
3636
3789
|
}
|
|
@@ -3949,9 +4102,7 @@ function pickPanelJudge(providers, moderatorName, pricing) {
|
|
|
3949
4102
|
return entry.model && entry.model !== base.model ? retargetProvider(base, entry.model) : base;
|
|
3950
4103
|
}
|
|
3951
4104
|
}
|
|
3952
|
-
|
|
3953
|
-
if (mod !== void 0) return mod;
|
|
3954
|
-
return null;
|
|
4105
|
+
return resolveModerator(providers, moderatorName).provider ?? null;
|
|
3955
4106
|
}
|
|
3956
4107
|
var AGREEMENT_CHECK_SCHEMA = {
|
|
3957
4108
|
type: "object",
|
|
@@ -4268,83 +4419,6 @@ async function pickAutoPanel(storage, purpose, n, providers, allowlist) {
|
|
|
4268
4419
|
return { providers: ranked.slice(0, Math.max(1, n)), coldStart: true };
|
|
4269
4420
|
}
|
|
4270
4421
|
|
|
4271
|
-
// src/core/super-mode.ts
|
|
4272
|
-
import { AsyncLocalStorage } from "async_hooks";
|
|
4273
|
-
var SUPER_MODELS = {
|
|
4274
|
-
// Fable 5.1 verified present on the account; 5 as the fallback for accounts
|
|
4275
|
-
// that haven't been granted 5.1 yet.
|
|
4276
|
-
anthropic: ["claude-fable-5-1", UPGRADE_MODEL],
|
|
4277
|
-
// Astra is live (verified against the account's model list 2026-09-23).
|
|
4278
|
-
// The fallback is named explicitly rather than reusing CO_REASON_MODEL:
|
|
4279
|
-
// that constant means "OpenAI's top reasoning model" for the max-reasoning
|
|
4280
|
-
// co-reasoner, which is a different question from "what should super fall
|
|
4281
|
-
// back to". Sharing the symbol silently coupled two unrelated decisions.
|
|
4282
|
-
openai: ["gpt-6-astra", "gpt-6-sol"],
|
|
4283
|
-
// Explicitly left as-is per product decision. Note grok-4-latest is not in
|
|
4284
|
-
// xAI's published model list, but it resolves in practice — real panel calls
|
|
4285
|
-
// on it succeeded as recently as 2026-08-30 — so it is an unlisted alias
|
|
4286
|
-
// rather than a dead id.
|
|
4287
|
-
xai: [DEFAULT_MODELS["xai"]],
|
|
4288
|
-
// 3.8 Flash is now BOTH the everyday default and the super pick for Gemini,
|
|
4289
|
-
// so this can no longer borrow DEFAULT_MODELS as its fallback — that would
|
|
4290
|
-
// repeat the same model and retry one that just failed. Named explicitly.
|
|
4291
|
-
gemini: ["gemini-3.8-flash", "gemini-3.1-pro-preview"],
|
|
4292
|
-
kimi: [DEFAULT_MODELS["kimi"]],
|
|
4293
|
-
qwen: [DEFAULT_MODELS["qwen"]]
|
|
4294
|
-
};
|
|
4295
|
-
var SUPER_ENV_VARS = {
|
|
4296
|
-
anthropic: "ANTHROPIC_SUPER_MODEL",
|
|
4297
|
-
openai: "OPENAI_SUPER_MODEL",
|
|
4298
|
-
xai: "XAI_SUPER_MODEL",
|
|
4299
|
-
gemini: "GEMINI_SUPER_MODEL",
|
|
4300
|
-
kimi: "KIMI_SUPER_MODEL",
|
|
4301
|
-
qwen: "QWEN_SUPER_MODEL",
|
|
4302
|
-
mistral: "MISTRAL_SUPER_MODEL",
|
|
4303
|
-
groq: "GROQ_SUPER_MODEL",
|
|
4304
|
-
deepseek: "DEEPSEEK_SUPER_MODEL"
|
|
4305
|
-
};
|
|
4306
|
-
function parseChain(v) {
|
|
4307
|
-
if (!v) return [];
|
|
4308
|
-
const out = [];
|
|
4309
|
-
for (const raw of v.split(",")) {
|
|
4310
|
-
const m = raw.trim();
|
|
4311
|
-
if (m && !out.includes(m)) out.push(m);
|
|
4312
|
-
}
|
|
4313
|
-
return out;
|
|
4314
|
-
}
|
|
4315
|
-
var superEnvStore = new AsyncLocalStorage();
|
|
4316
|
-
function withSuperEnv(env, fn) {
|
|
4317
|
-
return superEnvStore.run(env, fn);
|
|
4318
|
-
}
|
|
4319
|
-
var currentEnv = () => superEnvStore.getStore() ?? process.env;
|
|
4320
|
-
function superChainFor(provider, env = currentEnv()) {
|
|
4321
|
-
const varName = SUPER_ENV_VARS[provider];
|
|
4322
|
-
const user = varName ? parseChain(env[varName]) : [];
|
|
4323
|
-
if (user.length > 0) {
|
|
4324
|
-
const fallbacks = varName ? parseChain(env[`${varName}_FALLBACKS`]) : [];
|
|
4325
|
-
return [...user, ...fallbacks.filter((m) => !user.includes(m))];
|
|
4326
|
-
}
|
|
4327
|
-
return SUPER_MODELS[provider] ?? [];
|
|
4328
|
-
}
|
|
4329
|
-
function superPrimary(provider, env = currentEnv()) {
|
|
4330
|
-
return superChainFor(provider, env)[0];
|
|
4331
|
-
}
|
|
4332
|
-
var SUPER_PROVIDER_NAMES = Object.keys(SUPER_MODELS);
|
|
4333
|
-
function isSuperRequested(args) {
|
|
4334
|
-
return args["super"] === true;
|
|
4335
|
-
}
|
|
4336
|
-
function retargetForSuper(p, env = currentEnv()) {
|
|
4337
|
-
const chain = superChainFor(p.name, env);
|
|
4338
|
-
if (chain.length === 0) return p;
|
|
4339
|
-
const [primary, ...fallbacks] = chain;
|
|
4340
|
-
return retargetProvider(p, primary, fallbacks);
|
|
4341
|
-
}
|
|
4342
|
-
var SUPER_BUDGET_MULTIPLIER = 3;
|
|
4343
|
-
var SUPER_BUDGET_CEILING = 16e3;
|
|
4344
|
-
function superBudget(base) {
|
|
4345
|
-
return Math.min(base * SUPER_BUDGET_MULTIPLIER, SUPER_BUDGET_CEILING);
|
|
4346
|
-
}
|
|
4347
|
-
|
|
4348
4422
|
// src/core/session-memory.ts
|
|
4349
4423
|
var SESSION_MEMORY_DEFAULT_LIMIT = 50;
|
|
4350
4424
|
var SESSION_MEMORY_INJECT_BUDGET_CHARS = 4e3;
|
|
@@ -6725,8 +6799,9 @@ async function runOrchestrate(args, opts) {
|
|
|
6725
6799
|
blocked
|
|
6726
6800
|
};
|
|
6727
6801
|
}
|
|
6728
|
-
const
|
|
6729
|
-
const moderator =
|
|
6802
|
+
const resolvedModerator = resolveModerator(opts.providers, args["moderator"], opts.moderator);
|
|
6803
|
+
const moderator = resolvedModerator.provider ?? selected[0];
|
|
6804
|
+
const moderatorChosen = resolvedModerator.provider !== void 0 && (resolvedModerator.pinned || parseModeratorSpec(args["moderator"]) !== null);
|
|
6730
6805
|
const failFast = boolArg2(args["fail_fast"], false);
|
|
6731
6806
|
const planOnly = boolArg2(args["plan_only"], false);
|
|
6732
6807
|
const cheapMode = boolArg2(args["cheap_mode"], opts.ctx?.cheap_mode ?? false);
|
|
@@ -7210,11 +7285,17 @@ ${recombineSys}` : recombineSys },
|
|
|
7210
7285
|
let synthProvider = moderator;
|
|
7211
7286
|
let synthModel = null;
|
|
7212
7287
|
const upgradeRequested = isUpgradeRequested(args);
|
|
7213
|
-
const
|
|
7288
|
+
const seat = synthesisSeat({
|
|
7289
|
+
moderator,
|
|
7290
|
+
pinned: resolvedModerator.provider !== void 0 && resolvedModerator.pinned,
|
|
7291
|
+
superRequested: false,
|
|
7292
|
+
upgradeRequested
|
|
7293
|
+
});
|
|
7294
|
+
const upgraded = seat.upgraded;
|
|
7214
7295
|
if (upgraded) {
|
|
7215
|
-
synthProvider =
|
|
7216
|
-
synthModel =
|
|
7217
|
-
} else if (cheapMode && opts.pricing) {
|
|
7296
|
+
synthProvider = seat.provider;
|
|
7297
|
+
synthModel = `${seat.provider.name}/${seat.provider.model}`;
|
|
7298
|
+
} else if (cheapMode && opts.pricing && !moderatorChosen) {
|
|
7218
7299
|
const pick = selectForDifficulty({
|
|
7219
7300
|
pricing: opts.pricing,
|
|
7220
7301
|
tier: "med",
|
|
@@ -7240,7 +7321,11 @@ ${recombineSys}` : recombineSys },
|
|
|
7240
7321
|
provider: synthProvider.name
|
|
7241
7322
|
} }
|
|
7242
7323
|
);
|
|
7243
|
-
const coProvider = pickCoReasoner(
|
|
7324
|
+
const coProvider = pickCoReasoner(
|
|
7325
|
+
opts.providers,
|
|
7326
|
+
upgradeRequested,
|
|
7327
|
+
synthProvider.name === "openai" ? synthProvider.model : void 0
|
|
7328
|
+
);
|
|
7244
7329
|
const coReason = await coReasonThenInject({
|
|
7245
7330
|
provider: coProvider,
|
|
7246
7331
|
messages: recMsgs,
|
|
@@ -7290,7 +7375,8 @@ ${recombineSys}` : recombineSys },
|
|
|
7290
7375
|
missing,
|
|
7291
7376
|
partial,
|
|
7292
7377
|
fail_fast: failFast,
|
|
7293
|
-
cheap_mode: cheapMode
|
|
7378
|
+
cheap_mode: cheapMode,
|
|
7379
|
+
moderator: { provider: moderator.name, model: moderator.model }
|
|
7294
7380
|
};
|
|
7295
7381
|
if (personaMeta.used !== null) result["persona"] = personaMeta;
|
|
7296
7382
|
if (synthModel) result["synth_model"] = synthModel;
|
|
@@ -7298,15 +7384,16 @@ ${recombineSys}` : recombineSys },
|
|
|
7298
7384
|
if (upgraded) {
|
|
7299
7385
|
result["reasoning_upgrade"] = {
|
|
7300
7386
|
applied: true,
|
|
7301
|
-
|
|
7302
|
-
|
|
7387
|
+
provider: seat.provider.name,
|
|
7388
|
+
model: seat.provider.model,
|
|
7389
|
+
label: seat.label ?? seat.provider.model,
|
|
7303
7390
|
seat: "recombine/synthesis",
|
|
7304
7391
|
...coReasoned ? { co_reasoner: { model: coProvider.model, label: coReasonLabel(coProvider.model) } } : {}
|
|
7305
7392
|
};
|
|
7306
7393
|
} else if (upgradeRequested) {
|
|
7307
7394
|
result["reasoning_upgrade"] = {
|
|
7308
7395
|
applied: false,
|
|
7309
|
-
reason:
|
|
7396
|
+
reason: seat.skipReason ?? "the moderator couldn't be upgraded."
|
|
7310
7397
|
};
|
|
7311
7398
|
} else if (goal) {
|
|
7312
7399
|
const assessment = assessReasoning(goal);
|
|
@@ -8488,13 +8575,24 @@ async function runCoordinate(args, opts) {
|
|
|
8488
8575
|
};
|
|
8489
8576
|
}
|
|
8490
8577
|
const proposerName = typeof args["proposer"] === "string" && args["proposer"] ? args["proposer"] : selected[0].name;
|
|
8491
|
-
const
|
|
8578
|
+
const resolvedSynth = resolveModerator(
|
|
8579
|
+
opts.providers,
|
|
8580
|
+
args["synthesizer"],
|
|
8581
|
+
args["moderator"],
|
|
8582
|
+
opts.moderator
|
|
8583
|
+
);
|
|
8492
8584
|
const proposer = opts.providers[proposerName.toLowerCase()] ?? selected[0];
|
|
8493
|
-
const synth =
|
|
8585
|
+
const synth = resolvedSynth.provider ?? proposer;
|
|
8494
8586
|
const proposerForCall = superRequested ? retargetForSuper(proposer) : proposer;
|
|
8495
8587
|
const upgradeRequested = isUpgradeRequested(args) || superRequested;
|
|
8496
|
-
const
|
|
8497
|
-
|
|
8588
|
+
const seat = synthesisSeat({
|
|
8589
|
+
moderator: synth,
|
|
8590
|
+
pinned: resolvedSynth.provider !== void 0 && resolvedSynth.pinned,
|
|
8591
|
+
superRequested,
|
|
8592
|
+
upgradeRequested
|
|
8593
|
+
});
|
|
8594
|
+
const upgraded = seat.upgraded;
|
|
8595
|
+
const synthForCall = seat.provider;
|
|
8498
8596
|
let critics = [];
|
|
8499
8597
|
if (Array.isArray(args["critics"])) {
|
|
8500
8598
|
for (const n of args["critics"]) {
|
|
@@ -8645,7 +8743,11 @@ CRITIQUES:
|
|
|
8645
8743
|
${critiqueBlock}`
|
|
8646
8744
|
}
|
|
8647
8745
|
];
|
|
8648
|
-
const coProvider = pickCoReasoner(
|
|
8746
|
+
const coProvider = pickCoReasoner(
|
|
8747
|
+
opts.providers,
|
|
8748
|
+
upgradeRequested,
|
|
8749
|
+
synthForCall.name === "openai" ? synthForCall.model : void 0
|
|
8750
|
+
);
|
|
8649
8751
|
const coReason = await coReasonThenInject({
|
|
8650
8752
|
provider: coProvider,
|
|
8651
8753
|
messages: synthMessages,
|
|
@@ -8690,7 +8792,8 @@ ${critiqueBlock}`
|
|
|
8690
8792
|
critique_answers: scannedCritiques,
|
|
8691
8793
|
critique_structured: critiqueStructured,
|
|
8692
8794
|
synthesis_answer: synthAns,
|
|
8693
|
-
synthesis_structured: synthObj
|
|
8795
|
+
synthesis_structured: synthObj,
|
|
8796
|
+
moderator: { provider: synthForCall.name, model: synthForCall.model }
|
|
8694
8797
|
};
|
|
8695
8798
|
if (synthErrs.length > 0) result["synthesis_errors"] = synthErrs;
|
|
8696
8799
|
if (canaryLeaks.length > 0) result["canary_leaks"] = canaryLeaks;
|
|
@@ -8708,15 +8811,16 @@ ${critiqueBlock}`
|
|
|
8708
8811
|
result["reasoning_upgrade"] = {
|
|
8709
8812
|
applied: true,
|
|
8710
8813
|
// The model that actually ran the seat, not the one we'd have picked.
|
|
8711
|
-
|
|
8712
|
-
|
|
8814
|
+
provider: synthForCall.name,
|
|
8815
|
+
model: synthForCall.model,
|
|
8816
|
+
label: seat.label ?? synthForCall.model,
|
|
8713
8817
|
seat: "synthesizer",
|
|
8714
8818
|
...coReasonAns ? { co_reasoner: { model: coProvider.model, label: coReasonLabel(coProvider.model) } } : {}
|
|
8715
8819
|
};
|
|
8716
8820
|
} else if (upgradeRequested) {
|
|
8717
8821
|
result["reasoning_upgrade"] = {
|
|
8718
8822
|
applied: false,
|
|
8719
|
-
reason:
|
|
8823
|
+
reason: seat.skipReason ?? "the synthesizer couldn't be upgraded."
|
|
8720
8824
|
};
|
|
8721
8825
|
} else {
|
|
8722
8826
|
const assessment = assessReasoning(topic);
|
|
@@ -9322,10 +9426,12 @@ async function runDebate(args, opts) {
|
|
|
9322
9426
|
const earlyStopThreshold = Number.isFinite(earlyStopThresholdRaw) ? earlyStopThresholdRaw : 0.7;
|
|
9323
9427
|
let earlyStoppedRound = null;
|
|
9324
9428
|
let agreementBlock = null;
|
|
9325
|
-
const
|
|
9326
|
-
const
|
|
9429
|
+
const resolvedModerator = resolveModerator(opts.providers, args["moderator"], opts.moderator);
|
|
9430
|
+
const moderatorName = resolvedModerator.spec.provider;
|
|
9431
|
+
const moderator = resolvedModerator.provider ?? selected[0];
|
|
9327
9432
|
const upgradeRequested = isUpgradeRequested(args) || superRequested;
|
|
9328
|
-
const
|
|
9433
|
+
const seat = moderator ? synthesisSeat({ moderator, pinned: resolvedModerator.pinned, superRequested, upgradeRequested }) : null;
|
|
9434
|
+
const upgraded = seat?.upgraded ?? false;
|
|
9329
9435
|
for (let rnd = 1; rnd <= maxRounds; rnd++) {
|
|
9330
9436
|
const roundMessages = [
|
|
9331
9437
|
{
|
|
@@ -9410,8 +9516,10 @@ ${prior.body}` });
|
|
|
9410
9516
|
let personaMeta = null;
|
|
9411
9517
|
let coReasoned = false;
|
|
9412
9518
|
let coReasonerModel = null;
|
|
9519
|
+
let moderatorUsed = null;
|
|
9413
9520
|
if (moderator) {
|
|
9414
|
-
const synthProvider =
|
|
9521
|
+
const synthProvider = seat?.provider ?? moderator;
|
|
9522
|
+
moderatorUsed = { provider: synthProvider.name, model: synthProvider.model };
|
|
9415
9523
|
const condensed = buildModeratorTranscript(transcript);
|
|
9416
9524
|
const persona = buildPersonaInjection({
|
|
9417
9525
|
toolName: "debate",
|
|
@@ -9437,7 +9545,7 @@ TRANSCRIPT:
|
|
|
9437
9545
|
${condensed}`
|
|
9438
9546
|
}
|
|
9439
9547
|
];
|
|
9440
|
-
const openAiSeat = selected.find((p) => p.name === "openai")?.model;
|
|
9548
|
+
const openAiSeat = synthProvider.name === "openai" ? synthProvider.model : selected.find((p) => p.name === "openai")?.model;
|
|
9441
9549
|
const coProvider = pickCoReasoner(opts.providers, upgradeRequested, openAiSeat);
|
|
9442
9550
|
const coReason = await coReasonThenInject({
|
|
9443
9551
|
provider: coProvider,
|
|
@@ -9497,20 +9605,22 @@ ${condensed}`
|
|
|
9497
9605
|
transcript,
|
|
9498
9606
|
synthesis
|
|
9499
9607
|
};
|
|
9608
|
+
if (moderatorUsed) result["moderator"] = moderatorUsed;
|
|
9500
9609
|
if (personaMeta && personaMeta.used !== null) result["persona"] = personaMeta;
|
|
9501
9610
|
if (compactionMeta) result["round_compaction"] = compactionMeta;
|
|
9502
9611
|
if (upgraded) {
|
|
9503
9612
|
result["reasoning_upgrade"] = {
|
|
9504
9613
|
applied: true,
|
|
9505
|
-
|
|
9506
|
-
|
|
9614
|
+
provider: seat.provider.name,
|
|
9615
|
+
model: seat.provider.model,
|
|
9616
|
+
label: seat.label ?? seat.provider.model,
|
|
9507
9617
|
seat: "moderator synthesis",
|
|
9508
9618
|
...coReasoned && coReasonerModel ? { co_reasoner: { model: coReasonerModel, label: coReasonLabel(coReasonerModel) } } : {}
|
|
9509
9619
|
};
|
|
9510
9620
|
} else if (upgradeRequested) {
|
|
9511
9621
|
result["reasoning_upgrade"] = {
|
|
9512
9622
|
applied: false,
|
|
9513
|
-
reason:
|
|
9623
|
+
reason: seat?.skipReason ?? "no moderator was available for the upgrade."
|
|
9514
9624
|
};
|
|
9515
9625
|
} else {
|
|
9516
9626
|
const assessment = assessReasoning(topic);
|
|
@@ -10139,12 +10249,25 @@ function runListProviders(args, opts) {
|
|
|
10139
10249
|
}
|
|
10140
10250
|
const result = {
|
|
10141
10251
|
providers,
|
|
10142
|
-
moderator_default: opts.moderatorDefault ??
|
|
10252
|
+
moderator_default: opts.moderatorDefault ?? DEFAULT_MODERATOR,
|
|
10253
|
+
// Who will actually moderate right now: the configured spec if that
|
|
10254
|
+
// provider has a key, else the first available (what the tools fall to).
|
|
10255
|
+
moderator: describeModerator(opts.providers ?? {}, opts.moderatorDefault),
|
|
10143
10256
|
usage_hint: USAGE_HINT
|
|
10144
10257
|
};
|
|
10145
10258
|
if (superRequested) result["super_mode"] = true;
|
|
10146
10259
|
return result;
|
|
10147
10260
|
}
|
|
10261
|
+
function describeModerator(providers, spec) {
|
|
10262
|
+
const r = resolveModerator(providers, spec);
|
|
10263
|
+
const p = r.provider ?? Object.values(providers)[0];
|
|
10264
|
+
return {
|
|
10265
|
+
spec: spec ?? DEFAULT_MODERATOR,
|
|
10266
|
+
provider: p?.name ?? null,
|
|
10267
|
+
model: p?.model ?? null,
|
|
10268
|
+
available: r.provider !== void 0
|
|
10269
|
+
};
|
|
10270
|
+
}
|
|
10148
10271
|
|
|
10149
10272
|
// src/tools/models.ts
|
|
10150
10273
|
var KNOWN_PROVIDERS7 = [
|
|
@@ -11694,7 +11817,7 @@ var CHECK_INTERVAL_SECONDS = 3 * 24 * 60 * 60;
|
|
|
11694
11817
|
var DEFAULT_PACKAGE = "crosscheck-cli";
|
|
11695
11818
|
var FETCH_TIMEOUT_MS = 3e3;
|
|
11696
11819
|
function engineVersion() {
|
|
11697
|
-
return true ? "0.2.
|
|
11820
|
+
return true ? "0.2.31" : "0.0.0-dev";
|
|
11698
11821
|
}
|
|
11699
11822
|
function defaultUpdateCachePath() {
|
|
11700
11823
|
const base = process.env["CROSSCHECK_DATA_DIR"] || path9.join(os.homedir() || os.tmpdir(), ".crosscheck");
|
|
@@ -12139,7 +12262,7 @@ var HELP_CATALOG = [
|
|
|
12139
12262
|
primaryArg: "topic",
|
|
12140
12263
|
summary: "Bounded multi-round debate between models, ending in a synthesized recommendation.",
|
|
12141
12264
|
example: "xc debate should we adopt a monorepo?",
|
|
12142
|
-
detail: `The panel argues across a few rounds \u2014 each model sees the others' prior turns, concedes or pushes back \u2014 then a moderator synthesizes a single grounded recommendation.
|
|
12265
|
+
detail: `The panel argues across a few rounds \u2014 each model sees the others' prior turns, concedes or pushes back \u2014 then a moderator synthesizes a single grounded recommendation. Any model can moderate \u2014 pass moderator:"openai" or an exact model (moderator:"openai:gpt-6-sol"), or set a default with \`crosscheck moderator set\`. reasoning:"max" bumps the moderator's synthesis to its provider's flagship (Fable 5 for Anthropic). Great for contentious or trade-off-heavy calls.`
|
|
12143
12266
|
},
|
|
12144
12267
|
{
|
|
12145
12268
|
name: "coordinate",
|
|
@@ -12382,6 +12505,10 @@ function renderHelpCommand(entry) {
|
|
|
12382
12505
|
}
|
|
12383
12506
|
|
|
12384
12507
|
// src/tools/index.ts
|
|
12508
|
+
var MODERATOR_PARAM = {
|
|
12509
|
+
type: "string",
|
|
12510
|
+
description: 'Who moderates (synthesises) this run: a provider ("openai") or an exact model ("openai:gpt-6-sol"). Any configured provider works. Defaults to the configured moderator (CROSSCHECK_MODERATOR / config `moderator`).'
|
|
12511
|
+
};
|
|
12385
12512
|
function defineTool(opts) {
|
|
12386
12513
|
return {
|
|
12387
12514
|
name: opts.name,
|
|
@@ -12616,7 +12743,7 @@ function createTool(o, toolName, cheapDefault) {
|
|
|
12616
12743
|
instruction: { type: "string" },
|
|
12617
12744
|
documents: { type: "array", items: { type: "string" } },
|
|
12618
12745
|
providers: { type: "array", items: { type: "string" } },
|
|
12619
|
-
moderator:
|
|
12746
|
+
moderator: MODERATOR_PARAM,
|
|
12620
12747
|
constraints: { type: "string" },
|
|
12621
12748
|
target_path: { type: "string" },
|
|
12622
12749
|
session_id: { type: "string" },
|
|
@@ -12657,7 +12784,7 @@ function orchestrateTool(providers, allowlist, moderator, storage, pricing, brea
|
|
|
12657
12784
|
dag: { type: "object", additionalProperties: true },
|
|
12658
12785
|
context: { type: "string" },
|
|
12659
12786
|
providers: { type: "array", items: { type: "string" } },
|
|
12660
|
-
moderator:
|
|
12787
|
+
moderator: MODERATOR_PARAM,
|
|
12661
12788
|
fail_fast: { type: "boolean" },
|
|
12662
12789
|
plan_only: { type: "boolean" },
|
|
12663
12790
|
cheap_mode: { type: "boolean" },
|
|
@@ -13036,7 +13163,7 @@ function planTool(providers, allowlist, storage, breakers, transcriptsDir, repoR
|
|
|
13036
13163
|
constraints: { type: "string" },
|
|
13037
13164
|
context: { type: "string" },
|
|
13038
13165
|
providers: { type: "array", items: { type: "string" } },
|
|
13039
|
-
moderator:
|
|
13166
|
+
moderator: MODERATOR_PARAM,
|
|
13040
13167
|
session_id: { type: "string" },
|
|
13041
13168
|
structured: { type: "boolean" },
|
|
13042
13169
|
mode: { type: "string", enum: ["fast", "thorough"] },
|
|
@@ -13098,7 +13225,7 @@ function coordinateTool(providers, allowlist, innerCallers, storage, breakers, t
|
|
|
13098
13225
|
providers: { type: "array", items: { type: "string" } },
|
|
13099
13226
|
proposer: { type: "string" },
|
|
13100
13227
|
synthesizer: { type: "string" },
|
|
13101
|
-
moderator:
|
|
13228
|
+
moderator: MODERATOR_PARAM,
|
|
13102
13229
|
critics: { type: "array", items: { type: "string" } },
|
|
13103
13230
|
session_id: { type: "string" },
|
|
13104
13231
|
untrusted_input: { type: "boolean" },
|
|
@@ -13131,7 +13258,7 @@ function debateTool(providers, allowlist, innerCallers, storage, pricing, breake
|
|
|
13131
13258
|
context: { type: "string" },
|
|
13132
13259
|
max_rounds: { type: "integer", minimum: 1 },
|
|
13133
13260
|
providers: { type: "array", items: { type: "string" } },
|
|
13134
|
-
moderator:
|
|
13261
|
+
moderator: MODERATOR_PARAM,
|
|
13135
13262
|
session_id: { type: "string" },
|
|
13136
13263
|
reasoning: { type: "string", enum: ["default", "max"], description: '"max" bumps the moderator-synthesis seat to Fable 5 (premium thinking model); the debaters stay on their normal models. Omit for the Opus 4.8 default.' },
|
|
13137
13264
|
structured: { type: "boolean" },
|
|
@@ -13676,8 +13803,8 @@ function createEmbeddedEngine(opts) {
|
|
|
13676
13803
|
const built = Object.fromEntries(
|
|
13677
13804
|
Object.entries(buildProviders({ env, pricing })).map(([name, p]) => [name, withActivity(p)])
|
|
13678
13805
|
);
|
|
13679
|
-
const moderator = opts.moderator ??
|
|
13680
|
-
const tools = registerCoreTools({ providers: built, pricing });
|
|
13806
|
+
const moderator = opts.moderator ?? DEFAULT_MODERATOR;
|
|
13807
|
+
const tools = registerCoreTools({ providers: built, pricing, moderatorDefault: moderator });
|
|
13681
13808
|
const providerIds = Object.keys(built).map(vaultId).sort();
|
|
13682
13809
|
const models = {};
|
|
13683
13810
|
for (const [name, p] of Object.entries(built)) models[vaultId(name)] = p.model;
|
|
@@ -13708,7 +13835,8 @@ function createEmbeddedEngine(opts) {
|
|
|
13708
13835
|
nextCallId,
|
|
13709
13836
|
skipped: /* @__PURE__ */ new Set(),
|
|
13710
13837
|
inflight: /* @__PURE__ */ new Map(),
|
|
13711
|
-
|
|
13838
|
+
// The provider half of a `provider:model` spec, as the vault spells it.
|
|
13839
|
+
moderator: vaultId(moderatorProviderName(moderator)),
|
|
13712
13840
|
...runOpts.callTimeoutMs && runOpts.callTimeoutMs > 0 ? { callTimeoutMs: runOpts.callTimeoutMs } : {},
|
|
13713
13841
|
...runOpts.images?.length ? { images: runOpts.images.filter((i) => IMAGE_MEDIA_TYPES.includes(i.mediaType) && typeof i.data === "string" && i.data.length > 0).slice(0, MAX_RUN_IMAGES) } : {}
|
|
13714
13842
|
};
|