crosscheck-mcp 0.2.29 → 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 +1129 -987
- 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 +1129 -987
- package/dist/browser-ext.js.map +1 -1
- package/dist/embed.cjs +434 -243
- package/dist/embed.cjs.map +1 -1
- package/dist/embed.d.cts +44 -3
- package/dist/embed.d.ts +44 -3
- package/dist/embed.js +428 -242
- package/dist/embed.js.map +1 -1
- package/dist/node-stdio.cjs +360 -210
- package/dist/node-stdio.cjs.map +1 -1
- package/dist/node-stdio.d.cts +1 -1
- package/dist/node-stdio.d.ts +1 -1
- package/dist/node-stdio.js +357 -207
- package/dist/node-stdio.js.map +1 -1
- package/dist/{types-BcprisDl.d.cts → types-HA3W47O4.d.cts} +13 -2
- package/dist/{types-BcprisDl.d.ts → types-HA3W47O4.d.ts} +13 -2
- package/package.json +3 -2
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";
|
|
@@ -179,6 +203,11 @@ function reasoningSharesOutputBudget(provider) {
|
|
|
179
203
|
}
|
|
180
204
|
|
|
181
205
|
// src/providers/types.ts
|
|
206
|
+
var IMAGE_MEDIA_TYPES = ["image/png", "image/jpeg", "image/webp", "image/gif"];
|
|
207
|
+
function imagesOf(m) {
|
|
208
|
+
if (m.role !== "user" || !Array.isArray(m.images)) return [];
|
|
209
|
+
return m.images.filter((i) => Boolean(i) && typeof i.data === "string" && i.data.length > 0 && IMAGE_MEDIA_TYPES.includes(i.mediaType));
|
|
210
|
+
}
|
|
182
211
|
var ProviderError = class extends Error {
|
|
183
212
|
name = "ProviderError";
|
|
184
213
|
kind;
|
|
@@ -567,7 +596,12 @@ function buildAnthropicRequest(opts) {
|
|
|
567
596
|
}
|
|
568
597
|
continue;
|
|
569
598
|
}
|
|
570
|
-
|
|
599
|
+
const text = typeof m.content === "string" ? m.content : "";
|
|
600
|
+
const images = imagesOf(m);
|
|
601
|
+
convo.push(images.length ? { role: m.role, content: [
|
|
602
|
+
...images.map((i) => ({ type: "image", source: { type: "base64", media_type: i.mediaType, data: i.data } })),
|
|
603
|
+
{ type: "text", text }
|
|
604
|
+
] } : { role: m.role, content: text });
|
|
571
605
|
}
|
|
572
606
|
const body = {
|
|
573
607
|
model: opts.model,
|
|
@@ -807,7 +841,10 @@ function buildGeminiRequest(opts) {
|
|
|
807
841
|
const role = m.role === "user" ? "user" : "model";
|
|
808
842
|
contents.push({
|
|
809
843
|
role,
|
|
810
|
-
parts: [
|
|
844
|
+
parts: [
|
|
845
|
+
...imagesOf(m).map((i) => ({ inline_data: { mime_type: i.mediaType, data: i.data } })),
|
|
846
|
+
{ text: typeof m.content === "string" ? m.content : "" }
|
|
847
|
+
]
|
|
811
848
|
});
|
|
812
849
|
}
|
|
813
850
|
const body = {
|
|
@@ -975,10 +1012,11 @@ function supportsNativeJsonSchema(provider, model) {
|
|
|
975
1012
|
return true;
|
|
976
1013
|
}
|
|
977
1014
|
function buildOpenAICompatibleRequest(opts) {
|
|
978
|
-
const msgs = opts.messages.map((m) =>
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
1015
|
+
const msgs = opts.messages.map((m) => {
|
|
1016
|
+
const text = typeof m.content === "string" ? m.content : "";
|
|
1017
|
+
const images = imagesOf(m);
|
|
1018
|
+
return images.length ? { role: m.role, content: [{ type: "text", text }, ...images.map((i) => ({ type: "image_url", image_url: { url: `data:${i.mediaType};base64,${i.data}` } }))] } : { role: m.role, content: text };
|
|
1019
|
+
});
|
|
982
1020
|
const body = {
|
|
983
1021
|
model: opts.model,
|
|
984
1022
|
messages: msgs
|
|
@@ -1286,12 +1324,238 @@ function makeGeminiProvider(model, apiKey, opts, fallbackModels = []) {
|
|
|
1286
1324
|
};
|
|
1287
1325
|
}
|
|
1288
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
|
+
|
|
1289
1553
|
// src/tools/index.ts
|
|
1290
1554
|
import { z } from "zod";
|
|
1291
1555
|
|
|
1292
1556
|
// src/server-meta.ts
|
|
1293
1557
|
var SERVER_NAME = "crosscheck-agent";
|
|
1294
|
-
var SERVER_VERSION = true ? "0.2.
|
|
1558
|
+
var SERVER_VERSION = true ? "0.2.31" : "0.0.0-dev";
|
|
1295
1559
|
|
|
1296
1560
|
// src/tools/audit.ts
|
|
1297
1561
|
import { readdirSync, readFileSync as readFileSync3, statSync } from "fs";
|
|
@@ -1974,33 +2238,6 @@ function operatorCeiling(purpose, provider) {
|
|
|
1974
2238
|
return null;
|
|
1975
2239
|
}
|
|
1976
2240
|
|
|
1977
|
-
// src/core/retarget.ts
|
|
1978
|
-
function retargetProvider(p, newModel, fallbackModels) {
|
|
1979
|
-
const chain = fallbackModels && fallbackModels.length > 0 ? fallbackModels : void 0;
|
|
1980
|
-
if (p.model === newModel && chain === void 0) return p;
|
|
1981
|
-
return {
|
|
1982
|
-
name: p.name,
|
|
1983
|
-
model: newModel,
|
|
1984
|
-
...chain ? { fallbackModels: chain } : {},
|
|
1985
|
-
send: (args) => p.send({ ...args, modelOverride: newModel })
|
|
1986
|
-
};
|
|
1987
|
-
}
|
|
1988
|
-
async function loadProviderWeights(storage, names) {
|
|
1989
|
-
const out = {};
|
|
1990
|
-
for (const raw of names) {
|
|
1991
|
-
const name = raw.toLowerCase();
|
|
1992
|
-
if (name in out) continue;
|
|
1993
|
-
const row = await storage.getProviderStats(name);
|
|
1994
|
-
if (!row) {
|
|
1995
|
-
out[name] = 0.5;
|
|
1996
|
-
continue;
|
|
1997
|
-
}
|
|
1998
|
-
const total = row.wins + row.losses + row.abstains;
|
|
1999
|
-
out[name] = total <= 0 ? 0.5 : (row.wins + 0.5 * row.abstains) / total;
|
|
2000
|
-
}
|
|
2001
|
-
return out;
|
|
2002
|
-
}
|
|
2003
|
-
|
|
2004
2241
|
// src/core/model-fallback.ts
|
|
2005
2242
|
async function sendWithModelFallback(provider, args) {
|
|
2006
2243
|
const chain = [provider.model, ...provider.fallbackModels ?? []];
|
|
@@ -3067,82 +3304,6 @@ function selectForDifficulty(args) {
|
|
|
3067
3304
|
};
|
|
3068
3305
|
}
|
|
3069
3306
|
|
|
3070
|
-
// src/core/reasoning-upgrade.ts
|
|
3071
|
-
var UPGRADE_MODEL = "claude-fable-5";
|
|
3072
|
-
var UPGRADE_LABEL = "Fable 5";
|
|
3073
|
-
function isUpgradeRequested(args) {
|
|
3074
|
-
if (args["upgrade"] === true) return true;
|
|
3075
|
-
const reasoning = args["reasoning"];
|
|
3076
|
-
if (typeof reasoning === "string" && reasoning.trim().toLowerCase() === "max") {
|
|
3077
|
-
return true;
|
|
3078
|
-
}
|
|
3079
|
-
const model = args["model"];
|
|
3080
|
-
if (typeof model === "string") {
|
|
3081
|
-
const m = model.trim().toLowerCase();
|
|
3082
|
-
if (m === "fable5" || m === "fable-5" || m === "fable" || m === UPGRADE_MODEL) {
|
|
3083
|
-
return true;
|
|
3084
|
-
}
|
|
3085
|
-
}
|
|
3086
|
-
return false;
|
|
3087
|
-
}
|
|
3088
|
-
var HEAVY_TERMS = [
|
|
3089
|
-
/\bprov(e|ing|en)\b|\bproof\b|\btheorem\b|\bderiv(e|ation)\b/i,
|
|
3090
|
-
/\barchitect(ure|ing)?\b|\bdesign\s+(a|the|an)\b|\bhigh[-\s]?level\s+design\b/i,
|
|
3091
|
-
/\btrade[-\s]?offs?\b|\bpros?\s+and\s+cons?\b|\bweigh\b/i,
|
|
3092
|
-
/\boptimi[sz]e\b|\bcomplexity\b|\bO\(|\balgorithm(ic)?\b/i,
|
|
3093
|
-
/\brace\s+condition\b|\bconcurren(t|cy)\b|\bdeadlock\b|\bdistributed\b|\bconsensus\b/i,
|
|
3094
|
-
/\broot[-\s]?cause\b|\bdebug(ging)?\b|\bwhy\s+(does|is|would|might)\b/i,
|
|
3095
|
-
/\bsecurity\b|\bthreat\s+model\b|\bexploit\b|\bvulnerabilit(y|ies)\b/i,
|
|
3096
|
-
/\bmigrat(e|ion)\b|\brefactor\b|\bre[-\s]?architect\b/i,
|
|
3097
|
-
/\binvariant\b|\bcorrectness\b|\bedge\s+cases?\b|\bformal(ly)?\b/i,
|
|
3098
|
-
/\bstrateg(y|ic|ies)\b|\bplan\s+(the|a|an|out)\b|\broadmap\b/i,
|
|
3099
|
-
/\breason\s+(through|about)\b|\bstep[-\s]?by[-\s]?step\b|\bthink\s+deeply\b/i,
|
|
3100
|
-
/\bnp[-\s]?(hard|complete)\b|\bgraph\b|\bstate\s+machine\b|\bconstraint\b/i
|
|
3101
|
-
];
|
|
3102
|
-
var DIFFICULTY_TERMS = /\b(hard|tricky|subtle|complex|complicated|non[-\s]?trivial|thorny|gnarly|difficult|deep)\b/i;
|
|
3103
|
-
function assessReasoning(text) {
|
|
3104
|
-
const s = typeof text === "string" ? text : "";
|
|
3105
|
-
const signals = [];
|
|
3106
|
-
let score = 0;
|
|
3107
|
-
let termHits = 0;
|
|
3108
|
-
for (const re of HEAVY_TERMS) {
|
|
3109
|
-
if (re.test(s)) termHits += 1;
|
|
3110
|
-
}
|
|
3111
|
-
if (termHits > 0) {
|
|
3112
|
-
const add = Math.min(termHits, 4);
|
|
3113
|
-
score += add;
|
|
3114
|
-
signals.push(`${termHits} reasoning cue${termHits === 1 ? "" : "s"}`);
|
|
3115
|
-
}
|
|
3116
|
-
if (DIFFICULTY_TERMS.test(s)) {
|
|
3117
|
-
score += 1;
|
|
3118
|
-
signals.push("explicit difficulty marker");
|
|
3119
|
-
}
|
|
3120
|
-
const words = s.split(/\s+/).filter(Boolean).length;
|
|
3121
|
-
if (words >= 120) {
|
|
3122
|
-
score += 2;
|
|
3123
|
-
signals.push("long, detailed prompt");
|
|
3124
|
-
} else if (words >= 50) {
|
|
3125
|
-
score += 1;
|
|
3126
|
-
signals.push("substantial prompt");
|
|
3127
|
-
}
|
|
3128
|
-
const constraints = (s.match(/\b(must|should|need to|ensure|require[ds]?|constraint)\b/gi) ?? []).length + (s.match(/(^|\n)\s*(?:[-*]|\d+[.)])\s+/g) ?? []).length;
|
|
3129
|
-
if (constraints >= 3) {
|
|
3130
|
-
score += 1;
|
|
3131
|
-
signals.push(`${constraints} constraints/steps`);
|
|
3132
|
-
}
|
|
3133
|
-
const heavy = score >= 3;
|
|
3134
|
-
const reason = heavy ? `Task looks reasoning-heavy (${signals.join(", ") || "score " + score}).` : `Task looks routine (score ${score}).`;
|
|
3135
|
-
return { heavy, score, reason, signals };
|
|
3136
|
-
}
|
|
3137
|
-
function buildSuggestedUpgrade(toolName, assessment) {
|
|
3138
|
-
return {
|
|
3139
|
-
model: UPGRADE_MODEL,
|
|
3140
|
-
label: UPGRADE_LABEL,
|
|
3141
|
-
reason: assessment.reason,
|
|
3142
|
-
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.`
|
|
3143
|
-
};
|
|
3144
|
-
}
|
|
3145
|
-
|
|
3146
3307
|
// src/tools/audit.ts
|
|
3147
3308
|
var AUDIT_OBVIOUS_FAILURE_HIGH = 0.3;
|
|
3148
3309
|
var AUDIT_OBVIOUS_FAILURE_MED = 0.2;
|
|
@@ -3440,9 +3601,14 @@ ${rubricText}`;
|
|
|
3440
3601
|
);
|
|
3441
3602
|
}
|
|
3442
3603
|
const upgradeRequested = isUpgradeRequested(args);
|
|
3443
|
-
const
|
|
3444
|
-
const
|
|
3445
|
-
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
|
+
);
|
|
3446
3612
|
const coReason = await coReasonThenInject({
|
|
3447
3613
|
provider: coProvider,
|
|
3448
3614
|
messages: msgs,
|
|
@@ -3525,15 +3691,16 @@ ${rubricText}`;
|
|
|
3525
3691
|
if (upgraded) {
|
|
3526
3692
|
result["reasoning_upgrade"] = {
|
|
3527
3693
|
applied: true,
|
|
3528
|
-
|
|
3529
|
-
|
|
3694
|
+
provider: auditorForCall.name,
|
|
3695
|
+
model: auditorForCall.model,
|
|
3696
|
+
label: seat.label ?? auditorForCall.model,
|
|
3530
3697
|
seat: "auditor",
|
|
3531
3698
|
...coReasoned ? { co_reasoner: { model: coProvider.model, label: coReasonLabel(coProvider.model) } } : {}
|
|
3532
3699
|
};
|
|
3533
3700
|
} else if (upgradeRequested) {
|
|
3534
3701
|
result["reasoning_upgrade"] = {
|
|
3535
3702
|
applied: false,
|
|
3536
|
-
reason:
|
|
3703
|
+
reason: seat.skipReason ?? "the auditor couldn't be upgraded."
|
|
3537
3704
|
};
|
|
3538
3705
|
} else {
|
|
3539
3706
|
const assessment = assessReasoning(
|
|
@@ -3616,7 +3783,7 @@ function pickAuditor(providers, exclude, explicit, moderatorName, allowlist, che
|
|
|
3616
3783
|
}
|
|
3617
3784
|
}
|
|
3618
3785
|
}
|
|
3619
|
-
const mod = providers
|
|
3786
|
+
const mod = resolveModerator(providers, moderatorName).provider;
|
|
3620
3787
|
if (mod !== void 0 && !exclude.has(mod.name) && (allowlist === null || allowlist.includes(mod.name))) {
|
|
3621
3788
|
return { auditor: mod, reason: null };
|
|
3622
3789
|
}
|
|
@@ -3935,9 +4102,7 @@ function pickPanelJudge(providers, moderatorName, pricing) {
|
|
|
3935
4102
|
return entry.model && entry.model !== base.model ? retargetProvider(base, entry.model) : base;
|
|
3936
4103
|
}
|
|
3937
4104
|
}
|
|
3938
|
-
|
|
3939
|
-
if (mod !== void 0) return mod;
|
|
3940
|
-
return null;
|
|
4105
|
+
return resolveModerator(providers, moderatorName).provider ?? null;
|
|
3941
4106
|
}
|
|
3942
4107
|
var AGREEMENT_CHECK_SCHEMA = {
|
|
3943
4108
|
type: "object",
|
|
@@ -4254,77 +4419,6 @@ async function pickAutoPanel(storage, purpose, n, providers, allowlist) {
|
|
|
4254
4419
|
return { providers: ranked.slice(0, Math.max(1, n)), coldStart: true };
|
|
4255
4420
|
}
|
|
4256
4421
|
|
|
4257
|
-
// src/core/super-mode.ts
|
|
4258
|
-
var SUPER_MODELS = {
|
|
4259
|
-
// Fable 5.1 verified present on the account; 5 as the fallback for accounts
|
|
4260
|
-
// that haven't been granted 5.1 yet.
|
|
4261
|
-
anthropic: ["claude-fable-5-1", UPGRADE_MODEL],
|
|
4262
|
-
// Astra is live (verified against the account's model list 2026-09-23).
|
|
4263
|
-
// The fallback is named explicitly rather than reusing CO_REASON_MODEL:
|
|
4264
|
-
// that constant means "OpenAI's top reasoning model" for the max-reasoning
|
|
4265
|
-
// co-reasoner, which is a different question from "what should super fall
|
|
4266
|
-
// back to". Sharing the symbol silently coupled two unrelated decisions.
|
|
4267
|
-
openai: ["gpt-6-astra", "gpt-6-sol"],
|
|
4268
|
-
// Explicitly left as-is per product decision. Note grok-4-latest is not in
|
|
4269
|
-
// xAI's published model list, but it resolves in practice — real panel calls
|
|
4270
|
-
// on it succeeded as recently as 2026-08-30 — so it is an unlisted alias
|
|
4271
|
-
// rather than a dead id.
|
|
4272
|
-
xai: [DEFAULT_MODELS["xai"]],
|
|
4273
|
-
// 3.8 Flash is now BOTH the everyday default and the super pick for Gemini,
|
|
4274
|
-
// so this can no longer borrow DEFAULT_MODELS as its fallback — that would
|
|
4275
|
-
// repeat the same model and retry one that just failed. Named explicitly.
|
|
4276
|
-
gemini: ["gemini-3.8-flash", "gemini-3.1-pro-preview"],
|
|
4277
|
-
kimi: [DEFAULT_MODELS["kimi"]],
|
|
4278
|
-
qwen: [DEFAULT_MODELS["qwen"]]
|
|
4279
|
-
};
|
|
4280
|
-
var SUPER_ENV_VARS = {
|
|
4281
|
-
anthropic: "ANTHROPIC_SUPER_MODEL",
|
|
4282
|
-
openai: "OPENAI_SUPER_MODEL",
|
|
4283
|
-
xai: "XAI_SUPER_MODEL",
|
|
4284
|
-
gemini: "GEMINI_SUPER_MODEL",
|
|
4285
|
-
kimi: "KIMI_SUPER_MODEL",
|
|
4286
|
-
qwen: "QWEN_SUPER_MODEL",
|
|
4287
|
-
mistral: "MISTRAL_SUPER_MODEL",
|
|
4288
|
-
groq: "GROQ_SUPER_MODEL",
|
|
4289
|
-
deepseek: "DEEPSEEK_SUPER_MODEL"
|
|
4290
|
-
};
|
|
4291
|
-
function parseChain(v) {
|
|
4292
|
-
if (!v) return [];
|
|
4293
|
-
const out = [];
|
|
4294
|
-
for (const raw of v.split(",")) {
|
|
4295
|
-
const m = raw.trim();
|
|
4296
|
-
if (m && !out.includes(m)) out.push(m);
|
|
4297
|
-
}
|
|
4298
|
-
return out;
|
|
4299
|
-
}
|
|
4300
|
-
function superChainFor(provider, env = process.env) {
|
|
4301
|
-
const varName = SUPER_ENV_VARS[provider];
|
|
4302
|
-
const user = varName ? parseChain(env[varName]) : [];
|
|
4303
|
-
if (user.length > 0) {
|
|
4304
|
-
const fallbacks = varName ? parseChain(env[`${varName}_FALLBACKS`]) : [];
|
|
4305
|
-
return [...user, ...fallbacks.filter((m) => !user.includes(m))];
|
|
4306
|
-
}
|
|
4307
|
-
return SUPER_MODELS[provider] ?? [];
|
|
4308
|
-
}
|
|
4309
|
-
function superPrimary(provider, env = process.env) {
|
|
4310
|
-
return superChainFor(provider, env)[0];
|
|
4311
|
-
}
|
|
4312
|
-
var SUPER_PROVIDER_NAMES = Object.keys(SUPER_MODELS);
|
|
4313
|
-
function isSuperRequested(args) {
|
|
4314
|
-
return args["super"] === true;
|
|
4315
|
-
}
|
|
4316
|
-
function retargetForSuper(p, env = process.env) {
|
|
4317
|
-
const chain = superChainFor(p.name, env);
|
|
4318
|
-
if (chain.length === 0) return p;
|
|
4319
|
-
const [primary, ...fallbacks] = chain;
|
|
4320
|
-
return retargetProvider(p, primary, fallbacks);
|
|
4321
|
-
}
|
|
4322
|
-
var SUPER_BUDGET_MULTIPLIER = 3;
|
|
4323
|
-
var SUPER_BUDGET_CEILING = 16e3;
|
|
4324
|
-
function superBudget(base) {
|
|
4325
|
-
return Math.min(base * SUPER_BUDGET_MULTIPLIER, SUPER_BUDGET_CEILING);
|
|
4326
|
-
}
|
|
4327
|
-
|
|
4328
4422
|
// src/core/session-memory.ts
|
|
4329
4423
|
var SESSION_MEMORY_DEFAULT_LIMIT = 50;
|
|
4330
4424
|
var SESSION_MEMORY_INJECT_BUDGET_CHARS = 4e3;
|
|
@@ -6391,9 +6485,9 @@ import path6 from "path";
|
|
|
6391
6485
|
import { performance as performance7 } from "perf_hooks";
|
|
6392
6486
|
|
|
6393
6487
|
// src/core/progress.ts
|
|
6394
|
-
import { AsyncLocalStorage } from "async_hooks";
|
|
6488
|
+
import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
|
|
6395
6489
|
import { performance as performance6 } from "perf_hooks";
|
|
6396
|
-
var progressStorage = new
|
|
6490
|
+
var progressStorage = new AsyncLocalStorage2();
|
|
6397
6491
|
async function withProgress(token, sendNotification, fn) {
|
|
6398
6492
|
if (token === void 0 || token === null) {
|
|
6399
6493
|
return fn();
|
|
@@ -6705,8 +6799,9 @@ async function runOrchestrate(args, opts) {
|
|
|
6705
6799
|
blocked
|
|
6706
6800
|
};
|
|
6707
6801
|
}
|
|
6708
|
-
const
|
|
6709
|
-
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);
|
|
6710
6805
|
const failFast = boolArg2(args["fail_fast"], false);
|
|
6711
6806
|
const planOnly = boolArg2(args["plan_only"], false);
|
|
6712
6807
|
const cheapMode = boolArg2(args["cheap_mode"], opts.ctx?.cheap_mode ?? false);
|
|
@@ -7190,11 +7285,17 @@ ${recombineSys}` : recombineSys },
|
|
|
7190
7285
|
let synthProvider = moderator;
|
|
7191
7286
|
let synthModel = null;
|
|
7192
7287
|
const upgradeRequested = isUpgradeRequested(args);
|
|
7193
|
-
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;
|
|
7194
7295
|
if (upgraded) {
|
|
7195
|
-
synthProvider =
|
|
7196
|
-
synthModel =
|
|
7197
|
-
} else if (cheapMode && opts.pricing) {
|
|
7296
|
+
synthProvider = seat.provider;
|
|
7297
|
+
synthModel = `${seat.provider.name}/${seat.provider.model}`;
|
|
7298
|
+
} else if (cheapMode && opts.pricing && !moderatorChosen) {
|
|
7198
7299
|
const pick = selectForDifficulty({
|
|
7199
7300
|
pricing: opts.pricing,
|
|
7200
7301
|
tier: "med",
|
|
@@ -7220,7 +7321,11 @@ ${recombineSys}` : recombineSys },
|
|
|
7220
7321
|
provider: synthProvider.name
|
|
7221
7322
|
} }
|
|
7222
7323
|
);
|
|
7223
|
-
const coProvider = pickCoReasoner(
|
|
7324
|
+
const coProvider = pickCoReasoner(
|
|
7325
|
+
opts.providers,
|
|
7326
|
+
upgradeRequested,
|
|
7327
|
+
synthProvider.name === "openai" ? synthProvider.model : void 0
|
|
7328
|
+
);
|
|
7224
7329
|
const coReason = await coReasonThenInject({
|
|
7225
7330
|
provider: coProvider,
|
|
7226
7331
|
messages: recMsgs,
|
|
@@ -7270,7 +7375,8 @@ ${recombineSys}` : recombineSys },
|
|
|
7270
7375
|
missing,
|
|
7271
7376
|
partial,
|
|
7272
7377
|
fail_fast: failFast,
|
|
7273
|
-
cheap_mode: cheapMode
|
|
7378
|
+
cheap_mode: cheapMode,
|
|
7379
|
+
moderator: { provider: moderator.name, model: moderator.model }
|
|
7274
7380
|
};
|
|
7275
7381
|
if (personaMeta.used !== null) result["persona"] = personaMeta;
|
|
7276
7382
|
if (synthModel) result["synth_model"] = synthModel;
|
|
@@ -7278,15 +7384,16 @@ ${recombineSys}` : recombineSys },
|
|
|
7278
7384
|
if (upgraded) {
|
|
7279
7385
|
result["reasoning_upgrade"] = {
|
|
7280
7386
|
applied: true,
|
|
7281
|
-
|
|
7282
|
-
|
|
7387
|
+
provider: seat.provider.name,
|
|
7388
|
+
model: seat.provider.model,
|
|
7389
|
+
label: seat.label ?? seat.provider.model,
|
|
7283
7390
|
seat: "recombine/synthesis",
|
|
7284
7391
|
...coReasoned ? { co_reasoner: { model: coProvider.model, label: coReasonLabel(coProvider.model) } } : {}
|
|
7285
7392
|
};
|
|
7286
7393
|
} else if (upgradeRequested) {
|
|
7287
7394
|
result["reasoning_upgrade"] = {
|
|
7288
7395
|
applied: false,
|
|
7289
|
-
reason:
|
|
7396
|
+
reason: seat.skipReason ?? "the moderator couldn't be upgraded."
|
|
7290
7397
|
};
|
|
7291
7398
|
} else if (goal) {
|
|
7292
7399
|
const assessment = assessReasoning(goal);
|
|
@@ -8468,13 +8575,24 @@ async function runCoordinate(args, opts) {
|
|
|
8468
8575
|
};
|
|
8469
8576
|
}
|
|
8470
8577
|
const proposerName = typeof args["proposer"] === "string" && args["proposer"] ? args["proposer"] : selected[0].name;
|
|
8471
|
-
const
|
|
8578
|
+
const resolvedSynth = resolveModerator(
|
|
8579
|
+
opts.providers,
|
|
8580
|
+
args["synthesizer"],
|
|
8581
|
+
args["moderator"],
|
|
8582
|
+
opts.moderator
|
|
8583
|
+
);
|
|
8472
8584
|
const proposer = opts.providers[proposerName.toLowerCase()] ?? selected[0];
|
|
8473
|
-
const synth =
|
|
8585
|
+
const synth = resolvedSynth.provider ?? proposer;
|
|
8474
8586
|
const proposerForCall = superRequested ? retargetForSuper(proposer) : proposer;
|
|
8475
8587
|
const upgradeRequested = isUpgradeRequested(args) || superRequested;
|
|
8476
|
-
const
|
|
8477
|
-
|
|
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;
|
|
8478
8596
|
let critics = [];
|
|
8479
8597
|
if (Array.isArray(args["critics"])) {
|
|
8480
8598
|
for (const n of args["critics"]) {
|
|
@@ -8625,7 +8743,11 @@ CRITIQUES:
|
|
|
8625
8743
|
${critiqueBlock}`
|
|
8626
8744
|
}
|
|
8627
8745
|
];
|
|
8628
|
-
const coProvider = pickCoReasoner(
|
|
8746
|
+
const coProvider = pickCoReasoner(
|
|
8747
|
+
opts.providers,
|
|
8748
|
+
upgradeRequested,
|
|
8749
|
+
synthForCall.name === "openai" ? synthForCall.model : void 0
|
|
8750
|
+
);
|
|
8629
8751
|
const coReason = await coReasonThenInject({
|
|
8630
8752
|
provider: coProvider,
|
|
8631
8753
|
messages: synthMessages,
|
|
@@ -8670,7 +8792,8 @@ ${critiqueBlock}`
|
|
|
8670
8792
|
critique_answers: scannedCritiques,
|
|
8671
8793
|
critique_structured: critiqueStructured,
|
|
8672
8794
|
synthesis_answer: synthAns,
|
|
8673
|
-
synthesis_structured: synthObj
|
|
8795
|
+
synthesis_structured: synthObj,
|
|
8796
|
+
moderator: { provider: synthForCall.name, model: synthForCall.model }
|
|
8674
8797
|
};
|
|
8675
8798
|
if (synthErrs.length > 0) result["synthesis_errors"] = synthErrs;
|
|
8676
8799
|
if (canaryLeaks.length > 0) result["canary_leaks"] = canaryLeaks;
|
|
@@ -8688,15 +8811,16 @@ ${critiqueBlock}`
|
|
|
8688
8811
|
result["reasoning_upgrade"] = {
|
|
8689
8812
|
applied: true,
|
|
8690
8813
|
// The model that actually ran the seat, not the one we'd have picked.
|
|
8691
|
-
|
|
8692
|
-
|
|
8814
|
+
provider: synthForCall.name,
|
|
8815
|
+
model: synthForCall.model,
|
|
8816
|
+
label: seat.label ?? synthForCall.model,
|
|
8693
8817
|
seat: "synthesizer",
|
|
8694
8818
|
...coReasonAns ? { co_reasoner: { model: coProvider.model, label: coReasonLabel(coProvider.model) } } : {}
|
|
8695
8819
|
};
|
|
8696
8820
|
} else if (upgradeRequested) {
|
|
8697
8821
|
result["reasoning_upgrade"] = {
|
|
8698
8822
|
applied: false,
|
|
8699
|
-
reason:
|
|
8823
|
+
reason: seat.skipReason ?? "the synthesizer couldn't be upgraded."
|
|
8700
8824
|
};
|
|
8701
8825
|
} else {
|
|
8702
8826
|
const assessment = assessReasoning(topic);
|
|
@@ -9302,10 +9426,12 @@ async function runDebate(args, opts) {
|
|
|
9302
9426
|
const earlyStopThreshold = Number.isFinite(earlyStopThresholdRaw) ? earlyStopThresholdRaw : 0.7;
|
|
9303
9427
|
let earlyStoppedRound = null;
|
|
9304
9428
|
let agreementBlock = null;
|
|
9305
|
-
const
|
|
9306
|
-
const
|
|
9429
|
+
const resolvedModerator = resolveModerator(opts.providers, args["moderator"], opts.moderator);
|
|
9430
|
+
const moderatorName = resolvedModerator.spec.provider;
|
|
9431
|
+
const moderator = resolvedModerator.provider ?? selected[0];
|
|
9307
9432
|
const upgradeRequested = isUpgradeRequested(args) || superRequested;
|
|
9308
|
-
const
|
|
9433
|
+
const seat = moderator ? synthesisSeat({ moderator, pinned: resolvedModerator.pinned, superRequested, upgradeRequested }) : null;
|
|
9434
|
+
const upgraded = seat?.upgraded ?? false;
|
|
9309
9435
|
for (let rnd = 1; rnd <= maxRounds; rnd++) {
|
|
9310
9436
|
const roundMessages = [
|
|
9311
9437
|
{
|
|
@@ -9390,8 +9516,10 @@ ${prior.body}` });
|
|
|
9390
9516
|
let personaMeta = null;
|
|
9391
9517
|
let coReasoned = false;
|
|
9392
9518
|
let coReasonerModel = null;
|
|
9519
|
+
let moderatorUsed = null;
|
|
9393
9520
|
if (moderator) {
|
|
9394
|
-
const synthProvider =
|
|
9521
|
+
const synthProvider = seat?.provider ?? moderator;
|
|
9522
|
+
moderatorUsed = { provider: synthProvider.name, model: synthProvider.model };
|
|
9395
9523
|
const condensed = buildModeratorTranscript(transcript);
|
|
9396
9524
|
const persona = buildPersonaInjection({
|
|
9397
9525
|
toolName: "debate",
|
|
@@ -9417,7 +9545,7 @@ TRANSCRIPT:
|
|
|
9417
9545
|
${condensed}`
|
|
9418
9546
|
}
|
|
9419
9547
|
];
|
|
9420
|
-
const openAiSeat = selected.find((p) => p.name === "openai")?.model;
|
|
9548
|
+
const openAiSeat = synthProvider.name === "openai" ? synthProvider.model : selected.find((p) => p.name === "openai")?.model;
|
|
9421
9549
|
const coProvider = pickCoReasoner(opts.providers, upgradeRequested, openAiSeat);
|
|
9422
9550
|
const coReason = await coReasonThenInject({
|
|
9423
9551
|
provider: coProvider,
|
|
@@ -9477,20 +9605,22 @@ ${condensed}`
|
|
|
9477
9605
|
transcript,
|
|
9478
9606
|
synthesis
|
|
9479
9607
|
};
|
|
9608
|
+
if (moderatorUsed) result["moderator"] = moderatorUsed;
|
|
9480
9609
|
if (personaMeta && personaMeta.used !== null) result["persona"] = personaMeta;
|
|
9481
9610
|
if (compactionMeta) result["round_compaction"] = compactionMeta;
|
|
9482
9611
|
if (upgraded) {
|
|
9483
9612
|
result["reasoning_upgrade"] = {
|
|
9484
9613
|
applied: true,
|
|
9485
|
-
|
|
9486
|
-
|
|
9614
|
+
provider: seat.provider.name,
|
|
9615
|
+
model: seat.provider.model,
|
|
9616
|
+
label: seat.label ?? seat.provider.model,
|
|
9487
9617
|
seat: "moderator synthesis",
|
|
9488
9618
|
...coReasoned && coReasonerModel ? { co_reasoner: { model: coReasonerModel, label: coReasonLabel(coReasonerModel) } } : {}
|
|
9489
9619
|
};
|
|
9490
9620
|
} else if (upgradeRequested) {
|
|
9491
9621
|
result["reasoning_upgrade"] = {
|
|
9492
9622
|
applied: false,
|
|
9493
|
-
reason:
|
|
9623
|
+
reason: seat?.skipReason ?? "no moderator was available for the upgrade."
|
|
9494
9624
|
};
|
|
9495
9625
|
} else {
|
|
9496
9626
|
const assessment = assessReasoning(topic);
|
|
@@ -10119,12 +10249,25 @@ function runListProviders(args, opts) {
|
|
|
10119
10249
|
}
|
|
10120
10250
|
const result = {
|
|
10121
10251
|
providers,
|
|
10122
|
-
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),
|
|
10123
10256
|
usage_hint: USAGE_HINT
|
|
10124
10257
|
};
|
|
10125
10258
|
if (superRequested) result["super_mode"] = true;
|
|
10126
10259
|
return result;
|
|
10127
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
|
+
}
|
|
10128
10271
|
|
|
10129
10272
|
// src/tools/models.ts
|
|
10130
10273
|
var KNOWN_PROVIDERS7 = [
|
|
@@ -11674,7 +11817,7 @@ var CHECK_INTERVAL_SECONDS = 3 * 24 * 60 * 60;
|
|
|
11674
11817
|
var DEFAULT_PACKAGE = "crosscheck-cli";
|
|
11675
11818
|
var FETCH_TIMEOUT_MS = 3e3;
|
|
11676
11819
|
function engineVersion() {
|
|
11677
|
-
return true ? "0.2.
|
|
11820
|
+
return true ? "0.2.31" : "0.0.0-dev";
|
|
11678
11821
|
}
|
|
11679
11822
|
function defaultUpdateCachePath() {
|
|
11680
11823
|
const base = process.env["CROSSCHECK_DATA_DIR"] || path9.join(os.homedir() || os.tmpdir(), ".crosscheck");
|
|
@@ -12119,7 +12262,7 @@ var HELP_CATALOG = [
|
|
|
12119
12262
|
primaryArg: "topic",
|
|
12120
12263
|
summary: "Bounded multi-round debate between models, ending in a synthesized recommendation.",
|
|
12121
12264
|
example: "xc debate should we adopt a monorepo?",
|
|
12122
|
-
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.`
|
|
12123
12266
|
},
|
|
12124
12267
|
{
|
|
12125
12268
|
name: "coordinate",
|
|
@@ -12362,6 +12505,10 @@ function renderHelpCommand(entry) {
|
|
|
12362
12505
|
}
|
|
12363
12506
|
|
|
12364
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
|
+
};
|
|
12365
12512
|
function defineTool(opts) {
|
|
12366
12513
|
return {
|
|
12367
12514
|
name: opts.name,
|
|
@@ -12596,7 +12743,7 @@ function createTool(o, toolName, cheapDefault) {
|
|
|
12596
12743
|
instruction: { type: "string" },
|
|
12597
12744
|
documents: { type: "array", items: { type: "string" } },
|
|
12598
12745
|
providers: { type: "array", items: { type: "string" } },
|
|
12599
|
-
moderator:
|
|
12746
|
+
moderator: MODERATOR_PARAM,
|
|
12600
12747
|
constraints: { type: "string" },
|
|
12601
12748
|
target_path: { type: "string" },
|
|
12602
12749
|
session_id: { type: "string" },
|
|
@@ -12637,7 +12784,7 @@ function orchestrateTool(providers, allowlist, moderator, storage, pricing, brea
|
|
|
12637
12784
|
dag: { type: "object", additionalProperties: true },
|
|
12638
12785
|
context: { type: "string" },
|
|
12639
12786
|
providers: { type: "array", items: { type: "string" } },
|
|
12640
|
-
moderator:
|
|
12787
|
+
moderator: MODERATOR_PARAM,
|
|
12641
12788
|
fail_fast: { type: "boolean" },
|
|
12642
12789
|
plan_only: { type: "boolean" },
|
|
12643
12790
|
cheap_mode: { type: "boolean" },
|
|
@@ -13016,7 +13163,7 @@ function planTool(providers, allowlist, storage, breakers, transcriptsDir, repoR
|
|
|
13016
13163
|
constraints: { type: "string" },
|
|
13017
13164
|
context: { type: "string" },
|
|
13018
13165
|
providers: { type: "array", items: { type: "string" } },
|
|
13019
|
-
moderator:
|
|
13166
|
+
moderator: MODERATOR_PARAM,
|
|
13020
13167
|
session_id: { type: "string" },
|
|
13021
13168
|
structured: { type: "boolean" },
|
|
13022
13169
|
mode: { type: "string", enum: ["fast", "thorough"] },
|
|
@@ -13078,7 +13225,7 @@ function coordinateTool(providers, allowlist, innerCallers, storage, breakers, t
|
|
|
13078
13225
|
providers: { type: "array", items: { type: "string" } },
|
|
13079
13226
|
proposer: { type: "string" },
|
|
13080
13227
|
synthesizer: { type: "string" },
|
|
13081
|
-
moderator:
|
|
13228
|
+
moderator: MODERATOR_PARAM,
|
|
13082
13229
|
critics: { type: "array", items: { type: "string" } },
|
|
13083
13230
|
session_id: { type: "string" },
|
|
13084
13231
|
untrusted_input: { type: "boolean" },
|
|
@@ -13111,7 +13258,7 @@ function debateTool(providers, allowlist, innerCallers, storage, pricing, breake
|
|
|
13111
13258
|
context: { type: "string" },
|
|
13112
13259
|
max_rounds: { type: "integer", minimum: 1 },
|
|
13113
13260
|
providers: { type: "array", items: { type: "string" } },
|
|
13114
|
-
moderator:
|
|
13261
|
+
moderator: MODERATOR_PARAM,
|
|
13115
13262
|
session_id: { type: "string" },
|
|
13116
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.' },
|
|
13117
13264
|
structured: { type: "boolean" },
|
|
@@ -13467,7 +13614,33 @@ function vaultId(engineName) {
|
|
|
13467
13614
|
}
|
|
13468
13615
|
var ACTIVITY_TEXT_CAP = 8e3;
|
|
13469
13616
|
var ASKED_CAP = 280;
|
|
13470
|
-
var
|
|
13617
|
+
var VISION_PROVIDERS = ["anthropic", "openai", "gemini", "grok"];
|
|
13618
|
+
var NO_IMAGE_PURPOSES = /* @__PURE__ */ new Set(["early_stop", "extract", "canary", "classify"]);
|
|
13619
|
+
var MAX_RUN_IMAGES = 8;
|
|
13620
|
+
function withRunImages(args, provider, images) {
|
|
13621
|
+
if (!images?.length || NO_IMAGE_PURPOSES.has(args.purpose ?? "")) return args;
|
|
13622
|
+
const msgs = [...args.messages];
|
|
13623
|
+
let idx = -1;
|
|
13624
|
+
for (let i = msgs.length - 1; i >= 0; i--) if (msgs[i]?.role === "user") {
|
|
13625
|
+
idx = i;
|
|
13626
|
+
break;
|
|
13627
|
+
}
|
|
13628
|
+
if (idx < 0) return args;
|
|
13629
|
+
const m = msgs[idx];
|
|
13630
|
+
if (VISION_PROVIDERS.includes(provider)) {
|
|
13631
|
+
msgs[idx] = { ...m, images: [...m.images ?? [], ...images] };
|
|
13632
|
+
} else {
|
|
13633
|
+
const n = images.length;
|
|
13634
|
+
msgs[idx] = {
|
|
13635
|
+
...m,
|
|
13636
|
+
content: `${m.content}
|
|
13637
|
+
|
|
13638
|
+
[The user also attached ${n} image${n === 1 ? "" : "s"} that this model can't see. Don't guess at ${n === 1 ? "its" : "their"} contents \u2014 work from the text, and say so if the answer depends on ${n === 1 ? "it" : "them"}.]`
|
|
13639
|
+
};
|
|
13640
|
+
}
|
|
13641
|
+
return { ...args, messages: msgs };
|
|
13642
|
+
}
|
|
13643
|
+
var runContext = new AsyncLocalStorage3();
|
|
13471
13644
|
var SYNTHESIS_PURPOSES = /* @__PURE__ */ new Set(["synth", "moderator", "recombine", "judge", "unify"]);
|
|
13472
13645
|
function exemptFromSkip(ctx, provider, purpose) {
|
|
13473
13646
|
return provider === ctx.moderator && SYNTHESIS_PURPOSES.has(purpose);
|
|
@@ -13522,7 +13695,7 @@ function withActivity(p) {
|
|
|
13522
13695
|
if (!stopped && controller.signal.reason === "skip") stopped = "user";
|
|
13523
13696
|
}, { once: true });
|
|
13524
13697
|
try {
|
|
13525
|
-
const res = await send({ ...args, signal: controller.signal });
|
|
13698
|
+
const res = await send({ ...withRunImages(args, provider, ctx.images), signal: controller.signal });
|
|
13526
13699
|
const text = typeof res.text === "string" ? res.text : "";
|
|
13527
13700
|
ctx.emit({
|
|
13528
13701
|
type: "call.done",
|
|
@@ -13617,6 +13790,12 @@ function createEmbeddedEngine(opts) {
|
|
|
13617
13790
|
const varName = MODEL_ENV[provider.trim().toLowerCase()];
|
|
13618
13791
|
if (varName && model) env[varName] = model;
|
|
13619
13792
|
}
|
|
13793
|
+
const superEnv = {};
|
|
13794
|
+
for (const [provider, model] of Object.entries(opts.superModels ?? {})) {
|
|
13795
|
+
const p = provider.trim().toLowerCase();
|
|
13796
|
+
const varName = SUPER_ENV_VARS[p === "grok" ? "xai" : p];
|
|
13797
|
+
if (varName && model) superEnv[varName] = model;
|
|
13798
|
+
}
|
|
13620
13799
|
const pricingPath = [opts.pricingPath, bundledPricingPath()].find(
|
|
13621
13800
|
(p) => Boolean(p) && existsSync11(p)
|
|
13622
13801
|
);
|
|
@@ -13624,8 +13803,8 @@ function createEmbeddedEngine(opts) {
|
|
|
13624
13803
|
const built = Object.fromEntries(
|
|
13625
13804
|
Object.entries(buildProviders({ env, pricing })).map(([name, p]) => [name, withActivity(p)])
|
|
13626
13805
|
);
|
|
13627
|
-
const moderator = opts.moderator ??
|
|
13628
|
-
const tools = registerCoreTools({ providers: built, pricing });
|
|
13806
|
+
const moderator = opts.moderator ?? DEFAULT_MODERATOR;
|
|
13807
|
+
const tools = registerCoreTools({ providers: built, pricing, moderatorDefault: moderator });
|
|
13629
13808
|
const providerIds = Object.keys(built).map(vaultId).sort();
|
|
13630
13809
|
const models = {};
|
|
13631
13810
|
for (const [name, p] of Object.entries(built)) models[vaultId(name)] = p.model;
|
|
@@ -13656,14 +13835,16 @@ function createEmbeddedEngine(opts) {
|
|
|
13656
13835
|
nextCallId,
|
|
13657
13836
|
skipped: /* @__PURE__ */ new Set(),
|
|
13658
13837
|
inflight: /* @__PURE__ */ new Map(),
|
|
13659
|
-
|
|
13660
|
-
|
|
13838
|
+
// The provider half of a `provider:model` spec, as the vault spells it.
|
|
13839
|
+
moderator: vaultId(moderatorProviderName(moderator)),
|
|
13840
|
+
...runOpts.callTimeoutMs && runOpts.callTimeoutMs > 0 ? { callTimeoutMs: runOpts.callTimeoutMs } : {},
|
|
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) } : {}
|
|
13661
13842
|
};
|
|
13662
13843
|
liveRuns.set(runId, ctx);
|
|
13663
13844
|
try {
|
|
13664
13845
|
return await runContext.run(ctx, () => withProgress(runId, (n) => {
|
|
13665
13846
|
if (n.params.message) emit({ type: "progress", runId, at: Date.now(), message: n.params.message });
|
|
13666
|
-
}, () => runInner(name, args, runId, started, emit)));
|
|
13847
|
+
}, () => withSuperEnv(superEnv, () => runInner(name, args, runId, started, emit))));
|
|
13667
13848
|
} finally {
|
|
13668
13849
|
liveRuns.delete(runId);
|
|
13669
13850
|
}
|
|
@@ -13821,12 +14002,17 @@ export {
|
|
|
13821
14002
|
DEFAULT_EXCLUDED_PROVIDERS,
|
|
13822
14003
|
DEFAULT_FALLBACKS,
|
|
13823
14004
|
DEFAULT_MODELS,
|
|
14005
|
+
IMAGE_MEDIA_TYPES,
|
|
14006
|
+
MAX_RUN_IMAGES,
|
|
14007
|
+
SUPER_MODELS,
|
|
14008
|
+
VISION_PROVIDERS,
|
|
13824
14009
|
KEY_ENV as __KEY_ENV,
|
|
13825
14010
|
MODEL_ENV as __MODEL_ENV,
|
|
13826
14011
|
__test_internals,
|
|
13827
14012
|
createEmbeddedEngine,
|
|
13828
14013
|
isAlive,
|
|
13829
14014
|
listProcesses,
|
|
13830
|
-
processRegistryPath
|
|
14015
|
+
processRegistryPath,
|
|
14016
|
+
withRunImages
|
|
13831
14017
|
};
|
|
13832
14018
|
//# sourceMappingURL=embed.js.map
|