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/node-stdio.js
CHANGED
|
@@ -1269,6 +1269,11 @@ function reasoningSharesOutputBudget(provider) {
|
|
|
1269
1269
|
|
|
1270
1270
|
// src/providers/types.ts
|
|
1271
1271
|
init_esm_shims();
|
|
1272
|
+
var IMAGE_MEDIA_TYPES = ["image/png", "image/jpeg", "image/webp", "image/gif"];
|
|
1273
|
+
function imagesOf(m) {
|
|
1274
|
+
if (m.role !== "user" || !Array.isArray(m.images)) return [];
|
|
1275
|
+
return m.images.filter((i) => Boolean(i) && typeof i.data === "string" && i.data.length > 0 && IMAGE_MEDIA_TYPES.includes(i.mediaType));
|
|
1276
|
+
}
|
|
1272
1277
|
var ProviderError = class extends Error {
|
|
1273
1278
|
name = "ProviderError";
|
|
1274
1279
|
kind;
|
|
@@ -1668,7 +1673,12 @@ function buildAnthropicRequest(opts) {
|
|
|
1668
1673
|
}
|
|
1669
1674
|
continue;
|
|
1670
1675
|
}
|
|
1671
|
-
|
|
1676
|
+
const text = typeof m.content === "string" ? m.content : "";
|
|
1677
|
+
const images = imagesOf(m);
|
|
1678
|
+
convo.push(images.length ? { role: m.role, content: [
|
|
1679
|
+
...images.map((i) => ({ type: "image", source: { type: "base64", media_type: i.mediaType, data: i.data } })),
|
|
1680
|
+
{ type: "text", text }
|
|
1681
|
+
] } : { role: m.role, content: text });
|
|
1672
1682
|
}
|
|
1673
1683
|
const body = {
|
|
1674
1684
|
model: opts.model,
|
|
@@ -1909,7 +1919,10 @@ function buildGeminiRequest(opts) {
|
|
|
1909
1919
|
const role = m.role === "user" ? "user" : "model";
|
|
1910
1920
|
contents.push({
|
|
1911
1921
|
role,
|
|
1912
|
-
parts: [
|
|
1922
|
+
parts: [
|
|
1923
|
+
...imagesOf(m).map((i) => ({ inline_data: { mime_type: i.mediaType, data: i.data } })),
|
|
1924
|
+
{ text: typeof m.content === "string" ? m.content : "" }
|
|
1925
|
+
]
|
|
1913
1926
|
});
|
|
1914
1927
|
}
|
|
1915
1928
|
const body = {
|
|
@@ -2078,10 +2091,11 @@ function supportsNativeJsonSchema(provider, model) {
|
|
|
2078
2091
|
return true;
|
|
2079
2092
|
}
|
|
2080
2093
|
function buildOpenAICompatibleRequest(opts) {
|
|
2081
|
-
const msgs = opts.messages.map((m) =>
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2094
|
+
const msgs = opts.messages.map((m) => {
|
|
2095
|
+
const text = typeof m.content === "string" ? m.content : "";
|
|
2096
|
+
const images = imagesOf(m);
|
|
2097
|
+
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 };
|
|
2098
|
+
});
|
|
2085
2099
|
const body = {
|
|
2086
2100
|
model: opts.model,
|
|
2087
2101
|
messages: msgs
|
|
@@ -2457,6 +2471,7 @@ Routing rules:
|
|
|
2457
2471
|
2. If the next token does NOT match a tool name (or there is no next token), default to \`mcp__crosscheck__${DEFAULT_TOOL}\` and pass the entire message tail (everything after \`xc\`/\`XC\`) as \`question\`.
|
|
2458
2472
|
3. Preserve the user's wording verbatim in the argument \u2014 do not paraphrase, summarize, or "clean up" the prompt before forwarding.
|
|
2459
2473
|
4. If the user message is exactly \`xc\` or \`XC\` with no tail, ask them what they want crosscheck to do; do not invent a question.
|
|
2474
|
+
5. If the user names a moderator ("let Gemini moderate", "moderator gpt", "moderated by openai:gpt-6-sol"), ALSO pass it as \`moderator\` \u2014 a provider or \`provider:model\` \u2014 on tools that accept one (debate, plan, coordinate, orchestrate, create). Any provider can moderate. Still forward the wording verbatim.
|
|
2460
2475
|
|
|
2461
2476
|
Routable tool names: ${ROUTABLE_TOOLS.join(", ")}.
|
|
2462
2477
|
|
|
@@ -2494,7 +2509,7 @@ import { z } from "zod";
|
|
|
2494
2509
|
// src/server-meta.ts
|
|
2495
2510
|
init_esm_shims();
|
|
2496
2511
|
var SERVER_NAME = "crosscheck-agent";
|
|
2497
|
-
var SERVER_VERSION = true ? "0.2.
|
|
2512
|
+
var SERVER_VERSION = true ? "0.2.31" : "0.0.0-dev";
|
|
2498
2513
|
|
|
2499
2514
|
// src/tools/audit.ts
|
|
2500
2515
|
init_esm_shims();
|
|
@@ -4128,6 +4143,231 @@ function numberOrNull(v) {
|
|
|
4128
4143
|
// src/tools/audit.ts
|
|
4129
4144
|
import { performance as performance2 } from "perf_hooks";
|
|
4130
4145
|
|
|
4146
|
+
// src/core/moderator.ts
|
|
4147
|
+
init_esm_shims();
|
|
4148
|
+
|
|
4149
|
+
// src/core/super-mode.ts
|
|
4150
|
+
init_esm_shims();
|
|
4151
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
4152
|
+
|
|
4153
|
+
// src/core/reasoning-upgrade.ts
|
|
4154
|
+
init_esm_shims();
|
|
4155
|
+
var UPGRADE_MODEL = "claude-fable-5";
|
|
4156
|
+
var UPGRADE_LABEL = "Fable 5";
|
|
4157
|
+
function isUpgradeRequested(args) {
|
|
4158
|
+
if (args["upgrade"] === true) return true;
|
|
4159
|
+
const reasoning = args["reasoning"];
|
|
4160
|
+
if (typeof reasoning === "string" && reasoning.trim().toLowerCase() === "max") {
|
|
4161
|
+
return true;
|
|
4162
|
+
}
|
|
4163
|
+
const model = args["model"];
|
|
4164
|
+
if (typeof model === "string") {
|
|
4165
|
+
const m = model.trim().toLowerCase();
|
|
4166
|
+
if (m === "fable5" || m === "fable-5" || m === "fable" || m === UPGRADE_MODEL) {
|
|
4167
|
+
return true;
|
|
4168
|
+
}
|
|
4169
|
+
}
|
|
4170
|
+
return false;
|
|
4171
|
+
}
|
|
4172
|
+
var HEAVY_TERMS = [
|
|
4173
|
+
/\bprov(e|ing|en)\b|\bproof\b|\btheorem\b|\bderiv(e|ation)\b/i,
|
|
4174
|
+
/\barchitect(ure|ing)?\b|\bdesign\s+(a|the|an)\b|\bhigh[-\s]?level\s+design\b/i,
|
|
4175
|
+
/\btrade[-\s]?offs?\b|\bpros?\s+and\s+cons?\b|\bweigh\b/i,
|
|
4176
|
+
/\boptimi[sz]e\b|\bcomplexity\b|\bO\(|\balgorithm(ic)?\b/i,
|
|
4177
|
+
/\brace\s+condition\b|\bconcurren(t|cy)\b|\bdeadlock\b|\bdistributed\b|\bconsensus\b/i,
|
|
4178
|
+
/\broot[-\s]?cause\b|\bdebug(ging)?\b|\bwhy\s+(does|is|would|might)\b/i,
|
|
4179
|
+
/\bsecurity\b|\bthreat\s+model\b|\bexploit\b|\bvulnerabilit(y|ies)\b/i,
|
|
4180
|
+
/\bmigrat(e|ion)\b|\brefactor\b|\bre[-\s]?architect\b/i,
|
|
4181
|
+
/\binvariant\b|\bcorrectness\b|\bedge\s+cases?\b|\bformal(ly)?\b/i,
|
|
4182
|
+
/\bstrateg(y|ic|ies)\b|\bplan\s+(the|a|an|out)\b|\broadmap\b/i,
|
|
4183
|
+
/\breason\s+(through|about)\b|\bstep[-\s]?by[-\s]?step\b|\bthink\s+deeply\b/i,
|
|
4184
|
+
/\bnp[-\s]?(hard|complete)\b|\bgraph\b|\bstate\s+machine\b|\bconstraint\b/i
|
|
4185
|
+
];
|
|
4186
|
+
var DIFFICULTY_TERMS = /\b(hard|tricky|subtle|complex|complicated|non[-\s]?trivial|thorny|gnarly|difficult|deep)\b/i;
|
|
4187
|
+
function assessReasoning(text) {
|
|
4188
|
+
const s = typeof text === "string" ? text : "";
|
|
4189
|
+
const signals = [];
|
|
4190
|
+
let score = 0;
|
|
4191
|
+
let termHits = 0;
|
|
4192
|
+
for (const re of HEAVY_TERMS) {
|
|
4193
|
+
if (re.test(s)) termHits += 1;
|
|
4194
|
+
}
|
|
4195
|
+
if (termHits > 0) {
|
|
4196
|
+
const add = Math.min(termHits, 4);
|
|
4197
|
+
score += add;
|
|
4198
|
+
signals.push(`${termHits} reasoning cue${termHits === 1 ? "" : "s"}`);
|
|
4199
|
+
}
|
|
4200
|
+
if (DIFFICULTY_TERMS.test(s)) {
|
|
4201
|
+
score += 1;
|
|
4202
|
+
signals.push("explicit difficulty marker");
|
|
4203
|
+
}
|
|
4204
|
+
const words = s.split(/\s+/).filter(Boolean).length;
|
|
4205
|
+
if (words >= 120) {
|
|
4206
|
+
score += 2;
|
|
4207
|
+
signals.push("long, detailed prompt");
|
|
4208
|
+
} else if (words >= 50) {
|
|
4209
|
+
score += 1;
|
|
4210
|
+
signals.push("substantial prompt");
|
|
4211
|
+
}
|
|
4212
|
+
const constraints = (s.match(/\b(must|should|need to|ensure|require[ds]?|constraint)\b/gi) ?? []).length + (s.match(/(^|\n)\s*(?:[-*]|\d+[.)])\s+/g) ?? []).length;
|
|
4213
|
+
if (constraints >= 3) {
|
|
4214
|
+
score += 1;
|
|
4215
|
+
signals.push(`${constraints} constraints/steps`);
|
|
4216
|
+
}
|
|
4217
|
+
const heavy = score >= 3;
|
|
4218
|
+
const reason = heavy ? `Task looks reasoning-heavy (${signals.join(", ") || "score " + score}).` : `Task looks routine (score ${score}).`;
|
|
4219
|
+
return { heavy, score, reason, signals };
|
|
4220
|
+
}
|
|
4221
|
+
function buildSuggestedUpgrade(toolName, assessment) {
|
|
4222
|
+
return {
|
|
4223
|
+
model: UPGRADE_MODEL,
|
|
4224
|
+
label: UPGRADE_LABEL,
|
|
4225
|
+
reason: assessment.reason,
|
|
4226
|
+
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.`
|
|
4227
|
+
};
|
|
4228
|
+
}
|
|
4229
|
+
|
|
4230
|
+
// src/core/super-mode.ts
|
|
4231
|
+
var SUPER_MODELS = {
|
|
4232
|
+
// Fable 5.1 verified present on the account; 5 as the fallback for accounts
|
|
4233
|
+
// that haven't been granted 5.1 yet.
|
|
4234
|
+
anthropic: ["claude-fable-5-1", UPGRADE_MODEL],
|
|
4235
|
+
// Astra is live (verified against the account's model list 2026-09-23).
|
|
4236
|
+
// The fallback is named explicitly rather than reusing CO_REASON_MODEL:
|
|
4237
|
+
// that constant means "OpenAI's top reasoning model" for the max-reasoning
|
|
4238
|
+
// co-reasoner, which is a different question from "what should super fall
|
|
4239
|
+
// back to". Sharing the symbol silently coupled two unrelated decisions.
|
|
4240
|
+
openai: ["gpt-6-astra", "gpt-6-sol"],
|
|
4241
|
+
// Explicitly left as-is per product decision. Note grok-4-latest is not in
|
|
4242
|
+
// xAI's published model list, but it resolves in practice — real panel calls
|
|
4243
|
+
// on it succeeded as recently as 2026-08-30 — so it is an unlisted alias
|
|
4244
|
+
// rather than a dead id.
|
|
4245
|
+
xai: [DEFAULT_MODELS["xai"]],
|
|
4246
|
+
// 3.8 Flash is now BOTH the everyday default and the super pick for Gemini,
|
|
4247
|
+
// so this can no longer borrow DEFAULT_MODELS as its fallback — that would
|
|
4248
|
+
// repeat the same model and retry one that just failed. Named explicitly.
|
|
4249
|
+
gemini: ["gemini-3.8-flash", "gemini-3.1-pro-preview"],
|
|
4250
|
+
kimi: [DEFAULT_MODELS["kimi"]],
|
|
4251
|
+
qwen: [DEFAULT_MODELS["qwen"]]
|
|
4252
|
+
};
|
|
4253
|
+
var SUPER_ENV_VARS = {
|
|
4254
|
+
anthropic: "ANTHROPIC_SUPER_MODEL",
|
|
4255
|
+
openai: "OPENAI_SUPER_MODEL",
|
|
4256
|
+
xai: "XAI_SUPER_MODEL",
|
|
4257
|
+
gemini: "GEMINI_SUPER_MODEL",
|
|
4258
|
+
kimi: "KIMI_SUPER_MODEL",
|
|
4259
|
+
qwen: "QWEN_SUPER_MODEL",
|
|
4260
|
+
mistral: "MISTRAL_SUPER_MODEL",
|
|
4261
|
+
groq: "GROQ_SUPER_MODEL",
|
|
4262
|
+
deepseek: "DEEPSEEK_SUPER_MODEL"
|
|
4263
|
+
};
|
|
4264
|
+
function parseChain(v) {
|
|
4265
|
+
if (!v) return [];
|
|
4266
|
+
const out = [];
|
|
4267
|
+
for (const raw of v.split(",")) {
|
|
4268
|
+
const m = raw.trim();
|
|
4269
|
+
if (m && !out.includes(m)) out.push(m);
|
|
4270
|
+
}
|
|
4271
|
+
return out;
|
|
4272
|
+
}
|
|
4273
|
+
var superEnvStore = new AsyncLocalStorage();
|
|
4274
|
+
var currentEnv = () => superEnvStore.getStore() ?? process.env;
|
|
4275
|
+
function superChainFor(provider, env = currentEnv()) {
|
|
4276
|
+
const varName = SUPER_ENV_VARS[provider];
|
|
4277
|
+
const user = varName ? parseChain(env[varName]) : [];
|
|
4278
|
+
if (user.length > 0) {
|
|
4279
|
+
const fallbacks = varName ? parseChain(env[`${varName}_FALLBACKS`]) : [];
|
|
4280
|
+
return [...user, ...fallbacks.filter((m) => !user.includes(m))];
|
|
4281
|
+
}
|
|
4282
|
+
return SUPER_MODELS[provider] ?? [];
|
|
4283
|
+
}
|
|
4284
|
+
function superPrimary(provider, env = currentEnv()) {
|
|
4285
|
+
return superChainFor(provider, env)[0];
|
|
4286
|
+
}
|
|
4287
|
+
var SUPER_PROVIDER_NAMES = Object.keys(SUPER_MODELS);
|
|
4288
|
+
function isSuperRequested(args) {
|
|
4289
|
+
return args["super"] === true;
|
|
4290
|
+
}
|
|
4291
|
+
function retargetForSuper(p, env = currentEnv()) {
|
|
4292
|
+
const chain = superChainFor(p.name, env);
|
|
4293
|
+
if (chain.length === 0) return p;
|
|
4294
|
+
const [primary, ...fallbacks] = chain;
|
|
4295
|
+
return retargetProvider(p, primary, fallbacks);
|
|
4296
|
+
}
|
|
4297
|
+
var SUPER_BUDGET_MULTIPLIER = 3;
|
|
4298
|
+
var SUPER_BUDGET_CEILING = 16e3;
|
|
4299
|
+
function superBudget(base) {
|
|
4300
|
+
return Math.min(base * SUPER_BUDGET_MULTIPLIER, SUPER_BUDGET_CEILING);
|
|
4301
|
+
}
|
|
4302
|
+
|
|
4303
|
+
// src/core/moderator.ts
|
|
4304
|
+
var DEFAULT_MODERATOR = "anthropic";
|
|
4305
|
+
var PROVIDER_ALIASES = {
|
|
4306
|
+
grok: "xai",
|
|
4307
|
+
claude: "anthropic",
|
|
4308
|
+
google: "gemini",
|
|
4309
|
+
chatgpt: "openai",
|
|
4310
|
+
gpt: "openai",
|
|
4311
|
+
moonshot: "kimi"
|
|
4312
|
+
};
|
|
4313
|
+
function parseModeratorSpec(raw) {
|
|
4314
|
+
if (typeof raw !== "string") return null;
|
|
4315
|
+
const s = raw.trim();
|
|
4316
|
+
if (!s) return null;
|
|
4317
|
+
const i = s.indexOf(":");
|
|
4318
|
+
const providerPart = (i < 0 ? s : s.slice(0, i)).trim().toLowerCase();
|
|
4319
|
+
const modelPart = i < 0 ? "" : s.slice(i + 1).trim();
|
|
4320
|
+
if (!providerPart) return null;
|
|
4321
|
+
return {
|
|
4322
|
+
provider: PROVIDER_ALIASES[providerPart] ?? providerPart,
|
|
4323
|
+
model: modelPart || null
|
|
4324
|
+
};
|
|
4325
|
+
}
|
|
4326
|
+
function formatModeratorSpec(spec) {
|
|
4327
|
+
return spec.model ? `${spec.provider}:${spec.model}` : spec.provider;
|
|
4328
|
+
}
|
|
4329
|
+
function pickModeratorSpec(...candidates) {
|
|
4330
|
+
for (const c of candidates) {
|
|
4331
|
+
const s = parseModeratorSpec(c);
|
|
4332
|
+
if (s) return s;
|
|
4333
|
+
}
|
|
4334
|
+
return { provider: DEFAULT_MODERATOR, model: null };
|
|
4335
|
+
}
|
|
4336
|
+
function resolveModerator(providers, ...candidates) {
|
|
4337
|
+
const spec = pickModeratorSpec(...candidates);
|
|
4338
|
+
const base = providers[spec.provider];
|
|
4339
|
+
if (!base) return { provider: void 0, spec, pinned: false };
|
|
4340
|
+
if (!spec.model) return { provider: base, spec, pinned: false };
|
|
4341
|
+
return { provider: retargetProvider(base, spec.model), spec, pinned: true };
|
|
4342
|
+
}
|
|
4343
|
+
function synthesisSeat(o) {
|
|
4344
|
+
const { moderator, pinned, superRequested, upgradeRequested } = o;
|
|
4345
|
+
const wantsMore = superRequested || upgradeRequested;
|
|
4346
|
+
if (!wantsMore) return { provider: moderator, upgraded: false, label: null, skipReason: null };
|
|
4347
|
+
if (pinned) {
|
|
4348
|
+
return {
|
|
4349
|
+
provider: moderator,
|
|
4350
|
+
upgraded: false,
|
|
4351
|
+
label: null,
|
|
4352
|
+
skipReason: `the moderator is pinned to ${moderator.name}:${moderator.model}; a pinned model is used as-is.`
|
|
4353
|
+
};
|
|
4354
|
+
}
|
|
4355
|
+
if (moderator.name === "anthropic" && !superRequested) {
|
|
4356
|
+
return { provider: retargetProvider(moderator, UPGRADE_MODEL), upgraded: true, label: UPGRADE_LABEL, skipReason: null };
|
|
4357
|
+
}
|
|
4358
|
+
if (superChainFor(moderator.name).length === 0) {
|
|
4359
|
+
return {
|
|
4360
|
+
provider: moderator,
|
|
4361
|
+
upgraded: false,
|
|
4362
|
+
label: null,
|
|
4363
|
+
skipReason: `no flagship model is known for ${moderator.name}; the moderator ran at ${moderator.model}.`
|
|
4364
|
+
};
|
|
4365
|
+
}
|
|
4366
|
+
const seat = retargetForSuper(moderator);
|
|
4367
|
+
const label = moderator.name === "anthropic" ? UPGRADE_LABEL : seat.model;
|
|
4368
|
+
return { provider: seat, upgraded: true, label, skipReason: null };
|
|
4369
|
+
}
|
|
4370
|
+
|
|
4131
4371
|
// src/core/co-reason.ts
|
|
4132
4372
|
init_esm_shims();
|
|
4133
4373
|
var CO_REASON_MODEL = "gpt-6-sol";
|
|
@@ -4306,83 +4546,6 @@ function selectForDifficulty(args) {
|
|
|
4306
4546
|
};
|
|
4307
4547
|
}
|
|
4308
4548
|
|
|
4309
|
-
// src/core/reasoning-upgrade.ts
|
|
4310
|
-
init_esm_shims();
|
|
4311
|
-
var UPGRADE_MODEL = "claude-fable-5";
|
|
4312
|
-
var UPGRADE_LABEL = "Fable 5";
|
|
4313
|
-
function isUpgradeRequested(args) {
|
|
4314
|
-
if (args["upgrade"] === true) return true;
|
|
4315
|
-
const reasoning = args["reasoning"];
|
|
4316
|
-
if (typeof reasoning === "string" && reasoning.trim().toLowerCase() === "max") {
|
|
4317
|
-
return true;
|
|
4318
|
-
}
|
|
4319
|
-
const model = args["model"];
|
|
4320
|
-
if (typeof model === "string") {
|
|
4321
|
-
const m = model.trim().toLowerCase();
|
|
4322
|
-
if (m === "fable5" || m === "fable-5" || m === "fable" || m === UPGRADE_MODEL) {
|
|
4323
|
-
return true;
|
|
4324
|
-
}
|
|
4325
|
-
}
|
|
4326
|
-
return false;
|
|
4327
|
-
}
|
|
4328
|
-
var HEAVY_TERMS = [
|
|
4329
|
-
/\bprov(e|ing|en)\b|\bproof\b|\btheorem\b|\bderiv(e|ation)\b/i,
|
|
4330
|
-
/\barchitect(ure|ing)?\b|\bdesign\s+(a|the|an)\b|\bhigh[-\s]?level\s+design\b/i,
|
|
4331
|
-
/\btrade[-\s]?offs?\b|\bpros?\s+and\s+cons?\b|\bweigh\b/i,
|
|
4332
|
-
/\boptimi[sz]e\b|\bcomplexity\b|\bO\(|\balgorithm(ic)?\b/i,
|
|
4333
|
-
/\brace\s+condition\b|\bconcurren(t|cy)\b|\bdeadlock\b|\bdistributed\b|\bconsensus\b/i,
|
|
4334
|
-
/\broot[-\s]?cause\b|\bdebug(ging)?\b|\bwhy\s+(does|is|would|might)\b/i,
|
|
4335
|
-
/\bsecurity\b|\bthreat\s+model\b|\bexploit\b|\bvulnerabilit(y|ies)\b/i,
|
|
4336
|
-
/\bmigrat(e|ion)\b|\brefactor\b|\bre[-\s]?architect\b/i,
|
|
4337
|
-
/\binvariant\b|\bcorrectness\b|\bedge\s+cases?\b|\bformal(ly)?\b/i,
|
|
4338
|
-
/\bstrateg(y|ic|ies)\b|\bplan\s+(the|a|an|out)\b|\broadmap\b/i,
|
|
4339
|
-
/\breason\s+(through|about)\b|\bstep[-\s]?by[-\s]?step\b|\bthink\s+deeply\b/i,
|
|
4340
|
-
/\bnp[-\s]?(hard|complete)\b|\bgraph\b|\bstate\s+machine\b|\bconstraint\b/i
|
|
4341
|
-
];
|
|
4342
|
-
var DIFFICULTY_TERMS = /\b(hard|tricky|subtle|complex|complicated|non[-\s]?trivial|thorny|gnarly|difficult|deep)\b/i;
|
|
4343
|
-
function assessReasoning(text) {
|
|
4344
|
-
const s = typeof text === "string" ? text : "";
|
|
4345
|
-
const signals = [];
|
|
4346
|
-
let score = 0;
|
|
4347
|
-
let termHits = 0;
|
|
4348
|
-
for (const re of HEAVY_TERMS) {
|
|
4349
|
-
if (re.test(s)) termHits += 1;
|
|
4350
|
-
}
|
|
4351
|
-
if (termHits > 0) {
|
|
4352
|
-
const add = Math.min(termHits, 4);
|
|
4353
|
-
score += add;
|
|
4354
|
-
signals.push(`${termHits} reasoning cue${termHits === 1 ? "" : "s"}`);
|
|
4355
|
-
}
|
|
4356
|
-
if (DIFFICULTY_TERMS.test(s)) {
|
|
4357
|
-
score += 1;
|
|
4358
|
-
signals.push("explicit difficulty marker");
|
|
4359
|
-
}
|
|
4360
|
-
const words = s.split(/\s+/).filter(Boolean).length;
|
|
4361
|
-
if (words >= 120) {
|
|
4362
|
-
score += 2;
|
|
4363
|
-
signals.push("long, detailed prompt");
|
|
4364
|
-
} else if (words >= 50) {
|
|
4365
|
-
score += 1;
|
|
4366
|
-
signals.push("substantial prompt");
|
|
4367
|
-
}
|
|
4368
|
-
const constraints = (s.match(/\b(must|should|need to|ensure|require[ds]?|constraint)\b/gi) ?? []).length + (s.match(/(^|\n)\s*(?:[-*]|\d+[.)])\s+/g) ?? []).length;
|
|
4369
|
-
if (constraints >= 3) {
|
|
4370
|
-
score += 1;
|
|
4371
|
-
signals.push(`${constraints} constraints/steps`);
|
|
4372
|
-
}
|
|
4373
|
-
const heavy = score >= 3;
|
|
4374
|
-
const reason = heavy ? `Task looks reasoning-heavy (${signals.join(", ") || "score " + score}).` : `Task looks routine (score ${score}).`;
|
|
4375
|
-
return { heavy, score, reason, signals };
|
|
4376
|
-
}
|
|
4377
|
-
function buildSuggestedUpgrade(toolName, assessment) {
|
|
4378
|
-
return {
|
|
4379
|
-
model: UPGRADE_MODEL,
|
|
4380
|
-
label: UPGRADE_LABEL,
|
|
4381
|
-
reason: assessment.reason,
|
|
4382
|
-
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.`
|
|
4383
|
-
};
|
|
4384
|
-
}
|
|
4385
|
-
|
|
4386
4549
|
// src/tools/audit.ts
|
|
4387
4550
|
var AUDIT_OBVIOUS_FAILURE_HIGH = 0.3;
|
|
4388
4551
|
var AUDIT_OBVIOUS_FAILURE_MED = 0.2;
|
|
@@ -4680,9 +4843,14 @@ ${rubricText}`;
|
|
|
4680
4843
|
);
|
|
4681
4844
|
}
|
|
4682
4845
|
const upgradeRequested = isUpgradeRequested(args);
|
|
4683
|
-
const
|
|
4684
|
-
const
|
|
4685
|
-
const
|
|
4846
|
+
const seat = synthesisSeat({ moderator: auditor, pinned: false, superRequested: false, upgradeRequested });
|
|
4847
|
+
const upgraded = seat.upgraded;
|
|
4848
|
+
const auditorForCall = seat.provider;
|
|
4849
|
+
const coProvider = pickCoReasoner(
|
|
4850
|
+
opts.providers,
|
|
4851
|
+
upgradeRequested,
|
|
4852
|
+
auditorForCall.name === "openai" ? auditorForCall.model : void 0
|
|
4853
|
+
);
|
|
4686
4854
|
const coReason = await coReasonThenInject({
|
|
4687
4855
|
provider: coProvider,
|
|
4688
4856
|
messages: msgs,
|
|
@@ -4765,15 +4933,16 @@ ${rubricText}`;
|
|
|
4765
4933
|
if (upgraded) {
|
|
4766
4934
|
result["reasoning_upgrade"] = {
|
|
4767
4935
|
applied: true,
|
|
4768
|
-
|
|
4769
|
-
|
|
4936
|
+
provider: auditorForCall.name,
|
|
4937
|
+
model: auditorForCall.model,
|
|
4938
|
+
label: seat.label ?? auditorForCall.model,
|
|
4770
4939
|
seat: "auditor",
|
|
4771
4940
|
...coReasoned ? { co_reasoner: { model: coProvider.model, label: coReasonLabel(coProvider.model) } } : {}
|
|
4772
4941
|
};
|
|
4773
4942
|
} else if (upgradeRequested) {
|
|
4774
4943
|
result["reasoning_upgrade"] = {
|
|
4775
4944
|
applied: false,
|
|
4776
|
-
reason:
|
|
4945
|
+
reason: seat.skipReason ?? "the auditor couldn't be upgraded."
|
|
4777
4946
|
};
|
|
4778
4947
|
} else {
|
|
4779
4948
|
const assessment = assessReasoning(
|
|
@@ -4856,7 +5025,7 @@ function pickAuditor(providers, exclude, explicit, moderatorName, allowlist, che
|
|
|
4856
5025
|
}
|
|
4857
5026
|
}
|
|
4858
5027
|
}
|
|
4859
|
-
const mod = providers
|
|
5028
|
+
const mod = resolveModerator(providers, moderatorName).provider;
|
|
4860
5029
|
if (mod !== void 0 && !exclude.has(mod.name) && (allowlist === null || allowlist.includes(mod.name))) {
|
|
4861
5030
|
return { auditor: mod, reason: null };
|
|
4862
5031
|
}
|
|
@@ -5181,9 +5350,7 @@ function pickPanelJudge(providers, moderatorName, pricing) {
|
|
|
5181
5350
|
return entry.model && entry.model !== base.model ? retargetProvider(base, entry.model) : base;
|
|
5182
5351
|
}
|
|
5183
5352
|
}
|
|
5184
|
-
|
|
5185
|
-
if (mod !== void 0) return mod;
|
|
5186
|
-
return null;
|
|
5353
|
+
return resolveModerator(providers, moderatorName).provider ?? null;
|
|
5187
5354
|
}
|
|
5188
5355
|
var AGREEMENT_CHECK_SCHEMA = {
|
|
5189
5356
|
type: "object",
|
|
@@ -5501,78 +5668,6 @@ async function pickAutoPanel(storage, purpose, n, providers, allowlist) {
|
|
|
5501
5668
|
return { providers: ranked.slice(0, Math.max(1, n)), coldStart: true };
|
|
5502
5669
|
}
|
|
5503
5670
|
|
|
5504
|
-
// src/core/super-mode.ts
|
|
5505
|
-
init_esm_shims();
|
|
5506
|
-
var SUPER_MODELS = {
|
|
5507
|
-
// Fable 5.1 verified present on the account; 5 as the fallback for accounts
|
|
5508
|
-
// that haven't been granted 5.1 yet.
|
|
5509
|
-
anthropic: ["claude-fable-5-1", UPGRADE_MODEL],
|
|
5510
|
-
// Astra is live (verified against the account's model list 2026-09-23).
|
|
5511
|
-
// The fallback is named explicitly rather than reusing CO_REASON_MODEL:
|
|
5512
|
-
// that constant means "OpenAI's top reasoning model" for the max-reasoning
|
|
5513
|
-
// co-reasoner, which is a different question from "what should super fall
|
|
5514
|
-
// back to". Sharing the symbol silently coupled two unrelated decisions.
|
|
5515
|
-
openai: ["gpt-6-astra", "gpt-6-sol"],
|
|
5516
|
-
// Explicitly left as-is per product decision. Note grok-4-latest is not in
|
|
5517
|
-
// xAI's published model list, but it resolves in practice — real panel calls
|
|
5518
|
-
// on it succeeded as recently as 2026-08-30 — so it is an unlisted alias
|
|
5519
|
-
// rather than a dead id.
|
|
5520
|
-
xai: [DEFAULT_MODELS["xai"]],
|
|
5521
|
-
// 3.8 Flash is now BOTH the everyday default and the super pick for Gemini,
|
|
5522
|
-
// so this can no longer borrow DEFAULT_MODELS as its fallback — that would
|
|
5523
|
-
// repeat the same model and retry one that just failed. Named explicitly.
|
|
5524
|
-
gemini: ["gemini-3.8-flash", "gemini-3.1-pro-preview"],
|
|
5525
|
-
kimi: [DEFAULT_MODELS["kimi"]],
|
|
5526
|
-
qwen: [DEFAULT_MODELS["qwen"]]
|
|
5527
|
-
};
|
|
5528
|
-
var SUPER_ENV_VARS = {
|
|
5529
|
-
anthropic: "ANTHROPIC_SUPER_MODEL",
|
|
5530
|
-
openai: "OPENAI_SUPER_MODEL",
|
|
5531
|
-
xai: "XAI_SUPER_MODEL",
|
|
5532
|
-
gemini: "GEMINI_SUPER_MODEL",
|
|
5533
|
-
kimi: "KIMI_SUPER_MODEL",
|
|
5534
|
-
qwen: "QWEN_SUPER_MODEL",
|
|
5535
|
-
mistral: "MISTRAL_SUPER_MODEL",
|
|
5536
|
-
groq: "GROQ_SUPER_MODEL",
|
|
5537
|
-
deepseek: "DEEPSEEK_SUPER_MODEL"
|
|
5538
|
-
};
|
|
5539
|
-
function parseChain(v) {
|
|
5540
|
-
if (!v) return [];
|
|
5541
|
-
const out = [];
|
|
5542
|
-
for (const raw of v.split(",")) {
|
|
5543
|
-
const m = raw.trim();
|
|
5544
|
-
if (m && !out.includes(m)) out.push(m);
|
|
5545
|
-
}
|
|
5546
|
-
return out;
|
|
5547
|
-
}
|
|
5548
|
-
function superChainFor(provider, env = process.env) {
|
|
5549
|
-
const varName = SUPER_ENV_VARS[provider];
|
|
5550
|
-
const user = varName ? parseChain(env[varName]) : [];
|
|
5551
|
-
if (user.length > 0) {
|
|
5552
|
-
const fallbacks = varName ? parseChain(env[`${varName}_FALLBACKS`]) : [];
|
|
5553
|
-
return [...user, ...fallbacks.filter((m) => !user.includes(m))];
|
|
5554
|
-
}
|
|
5555
|
-
return SUPER_MODELS[provider] ?? [];
|
|
5556
|
-
}
|
|
5557
|
-
function superPrimary(provider, env = process.env) {
|
|
5558
|
-
return superChainFor(provider, env)[0];
|
|
5559
|
-
}
|
|
5560
|
-
var SUPER_PROVIDER_NAMES = Object.keys(SUPER_MODELS);
|
|
5561
|
-
function isSuperRequested(args) {
|
|
5562
|
-
return args["super"] === true;
|
|
5563
|
-
}
|
|
5564
|
-
function retargetForSuper(p, env = process.env) {
|
|
5565
|
-
const chain = superChainFor(p.name, env);
|
|
5566
|
-
if (chain.length === 0) return p;
|
|
5567
|
-
const [primary, ...fallbacks] = chain;
|
|
5568
|
-
return retargetProvider(p, primary, fallbacks);
|
|
5569
|
-
}
|
|
5570
|
-
var SUPER_BUDGET_MULTIPLIER = 3;
|
|
5571
|
-
var SUPER_BUDGET_CEILING = 16e3;
|
|
5572
|
-
function superBudget(base) {
|
|
5573
|
-
return Math.min(base * SUPER_BUDGET_MULTIPLIER, SUPER_BUDGET_CEILING);
|
|
5574
|
-
}
|
|
5575
|
-
|
|
5576
5671
|
// src/core/session-memory.ts
|
|
5577
5672
|
init_esm_shims();
|
|
5578
5673
|
var SESSION_MEMORY_DEFAULT_LIMIT = 50;
|
|
@@ -7649,9 +7744,9 @@ import { performance as performance7 } from "perf_hooks";
|
|
|
7649
7744
|
|
|
7650
7745
|
// src/core/progress.ts
|
|
7651
7746
|
init_esm_shims();
|
|
7652
|
-
import { AsyncLocalStorage } from "async_hooks";
|
|
7747
|
+
import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
|
|
7653
7748
|
import { performance as performance6 } from "perf_hooks";
|
|
7654
|
-
var progressStorage = new
|
|
7749
|
+
var progressStorage = new AsyncLocalStorage2();
|
|
7655
7750
|
async function withProgress(token, sendNotification, fn) {
|
|
7656
7751
|
if (token === void 0 || token === null) {
|
|
7657
7752
|
return fn();
|
|
@@ -7965,8 +8060,9 @@ async function runOrchestrate(args, opts) {
|
|
|
7965
8060
|
blocked
|
|
7966
8061
|
};
|
|
7967
8062
|
}
|
|
7968
|
-
const
|
|
7969
|
-
const moderator =
|
|
8063
|
+
const resolvedModerator = resolveModerator(opts.providers, args["moderator"], opts.moderator);
|
|
8064
|
+
const moderator = resolvedModerator.provider ?? selected[0];
|
|
8065
|
+
const moderatorChosen = resolvedModerator.provider !== void 0 && (resolvedModerator.pinned || parseModeratorSpec(args["moderator"]) !== null);
|
|
7970
8066
|
const failFast = boolArg2(args["fail_fast"], false);
|
|
7971
8067
|
const planOnly = boolArg2(args["plan_only"], false);
|
|
7972
8068
|
const cheapMode = boolArg2(args["cheap_mode"], opts.ctx?.cheap_mode ?? false);
|
|
@@ -8450,11 +8546,17 @@ ${recombineSys}` : recombineSys },
|
|
|
8450
8546
|
let synthProvider = moderator;
|
|
8451
8547
|
let synthModel = null;
|
|
8452
8548
|
const upgradeRequested = isUpgradeRequested(args);
|
|
8453
|
-
const
|
|
8549
|
+
const seat = synthesisSeat({
|
|
8550
|
+
moderator,
|
|
8551
|
+
pinned: resolvedModerator.provider !== void 0 && resolvedModerator.pinned,
|
|
8552
|
+
superRequested: false,
|
|
8553
|
+
upgradeRequested
|
|
8554
|
+
});
|
|
8555
|
+
const upgraded = seat.upgraded;
|
|
8454
8556
|
if (upgraded) {
|
|
8455
|
-
synthProvider =
|
|
8456
|
-
synthModel =
|
|
8457
|
-
} else if (cheapMode && opts.pricing) {
|
|
8557
|
+
synthProvider = seat.provider;
|
|
8558
|
+
synthModel = `${seat.provider.name}/${seat.provider.model}`;
|
|
8559
|
+
} else if (cheapMode && opts.pricing && !moderatorChosen) {
|
|
8458
8560
|
const pick = selectForDifficulty({
|
|
8459
8561
|
pricing: opts.pricing,
|
|
8460
8562
|
tier: "med",
|
|
@@ -8480,7 +8582,11 @@ ${recombineSys}` : recombineSys },
|
|
|
8480
8582
|
provider: synthProvider.name
|
|
8481
8583
|
} }
|
|
8482
8584
|
);
|
|
8483
|
-
const coProvider = pickCoReasoner(
|
|
8585
|
+
const coProvider = pickCoReasoner(
|
|
8586
|
+
opts.providers,
|
|
8587
|
+
upgradeRequested,
|
|
8588
|
+
synthProvider.name === "openai" ? synthProvider.model : void 0
|
|
8589
|
+
);
|
|
8484
8590
|
const coReason = await coReasonThenInject({
|
|
8485
8591
|
provider: coProvider,
|
|
8486
8592
|
messages: recMsgs,
|
|
@@ -8530,7 +8636,8 @@ ${recombineSys}` : recombineSys },
|
|
|
8530
8636
|
missing,
|
|
8531
8637
|
partial,
|
|
8532
8638
|
fail_fast: failFast,
|
|
8533
|
-
cheap_mode: cheapMode
|
|
8639
|
+
cheap_mode: cheapMode,
|
|
8640
|
+
moderator: { provider: moderator.name, model: moderator.model }
|
|
8534
8641
|
};
|
|
8535
8642
|
if (personaMeta.used !== null) result["persona"] = personaMeta;
|
|
8536
8643
|
if (synthModel) result["synth_model"] = synthModel;
|
|
@@ -8538,15 +8645,16 @@ ${recombineSys}` : recombineSys },
|
|
|
8538
8645
|
if (upgraded) {
|
|
8539
8646
|
result["reasoning_upgrade"] = {
|
|
8540
8647
|
applied: true,
|
|
8541
|
-
|
|
8542
|
-
|
|
8648
|
+
provider: seat.provider.name,
|
|
8649
|
+
model: seat.provider.model,
|
|
8650
|
+
label: seat.label ?? seat.provider.model,
|
|
8543
8651
|
seat: "recombine/synthesis",
|
|
8544
8652
|
...coReasoned ? { co_reasoner: { model: coProvider.model, label: coReasonLabel(coProvider.model) } } : {}
|
|
8545
8653
|
};
|
|
8546
8654
|
} else if (upgradeRequested) {
|
|
8547
8655
|
result["reasoning_upgrade"] = {
|
|
8548
8656
|
applied: false,
|
|
8549
|
-
reason:
|
|
8657
|
+
reason: seat.skipReason ?? "the moderator couldn't be upgraded."
|
|
8550
8658
|
};
|
|
8551
8659
|
} else if (goal) {
|
|
8552
8660
|
const assessment = assessReasoning(goal);
|
|
@@ -9731,13 +9839,24 @@ async function runCoordinate(args, opts) {
|
|
|
9731
9839
|
};
|
|
9732
9840
|
}
|
|
9733
9841
|
const proposerName = typeof args["proposer"] === "string" && args["proposer"] ? args["proposer"] : selected[0].name;
|
|
9734
|
-
const
|
|
9842
|
+
const resolvedSynth = resolveModerator(
|
|
9843
|
+
opts.providers,
|
|
9844
|
+
args["synthesizer"],
|
|
9845
|
+
args["moderator"],
|
|
9846
|
+
opts.moderator
|
|
9847
|
+
);
|
|
9735
9848
|
const proposer = opts.providers[proposerName.toLowerCase()] ?? selected[0];
|
|
9736
|
-
const synth =
|
|
9849
|
+
const synth = resolvedSynth.provider ?? proposer;
|
|
9737
9850
|
const proposerForCall = superRequested ? retargetForSuper(proposer) : proposer;
|
|
9738
9851
|
const upgradeRequested = isUpgradeRequested(args) || superRequested;
|
|
9739
|
-
const
|
|
9740
|
-
|
|
9852
|
+
const seat = synthesisSeat({
|
|
9853
|
+
moderator: synth,
|
|
9854
|
+
pinned: resolvedSynth.provider !== void 0 && resolvedSynth.pinned,
|
|
9855
|
+
superRequested,
|
|
9856
|
+
upgradeRequested
|
|
9857
|
+
});
|
|
9858
|
+
const upgraded = seat.upgraded;
|
|
9859
|
+
const synthForCall = seat.provider;
|
|
9741
9860
|
let critics = [];
|
|
9742
9861
|
if (Array.isArray(args["critics"])) {
|
|
9743
9862
|
for (const n of args["critics"]) {
|
|
@@ -9888,7 +10007,11 @@ CRITIQUES:
|
|
|
9888
10007
|
${critiqueBlock}`
|
|
9889
10008
|
}
|
|
9890
10009
|
];
|
|
9891
|
-
const coProvider = pickCoReasoner(
|
|
10010
|
+
const coProvider = pickCoReasoner(
|
|
10011
|
+
opts.providers,
|
|
10012
|
+
upgradeRequested,
|
|
10013
|
+
synthForCall.name === "openai" ? synthForCall.model : void 0
|
|
10014
|
+
);
|
|
9892
10015
|
const coReason = await coReasonThenInject({
|
|
9893
10016
|
provider: coProvider,
|
|
9894
10017
|
messages: synthMessages,
|
|
@@ -9933,7 +10056,8 @@ ${critiqueBlock}`
|
|
|
9933
10056
|
critique_answers: scannedCritiques,
|
|
9934
10057
|
critique_structured: critiqueStructured,
|
|
9935
10058
|
synthesis_answer: synthAns,
|
|
9936
|
-
synthesis_structured: synthObj
|
|
10059
|
+
synthesis_structured: synthObj,
|
|
10060
|
+
moderator: { provider: synthForCall.name, model: synthForCall.model }
|
|
9937
10061
|
};
|
|
9938
10062
|
if (synthErrs.length > 0) result["synthesis_errors"] = synthErrs;
|
|
9939
10063
|
if (canaryLeaks.length > 0) result["canary_leaks"] = canaryLeaks;
|
|
@@ -9951,15 +10075,16 @@ ${critiqueBlock}`
|
|
|
9951
10075
|
result["reasoning_upgrade"] = {
|
|
9952
10076
|
applied: true,
|
|
9953
10077
|
// The model that actually ran the seat, not the one we'd have picked.
|
|
9954
|
-
|
|
9955
|
-
|
|
10078
|
+
provider: synthForCall.name,
|
|
10079
|
+
model: synthForCall.model,
|
|
10080
|
+
label: seat.label ?? synthForCall.model,
|
|
9956
10081
|
seat: "synthesizer",
|
|
9957
10082
|
...coReasonAns ? { co_reasoner: { model: coProvider.model, label: coReasonLabel(coProvider.model) } } : {}
|
|
9958
10083
|
};
|
|
9959
10084
|
} else if (upgradeRequested) {
|
|
9960
10085
|
result["reasoning_upgrade"] = {
|
|
9961
10086
|
applied: false,
|
|
9962
|
-
reason:
|
|
10087
|
+
reason: seat.skipReason ?? "the synthesizer couldn't be upgraded."
|
|
9963
10088
|
};
|
|
9964
10089
|
} else {
|
|
9965
10090
|
const assessment = assessReasoning(topic);
|
|
@@ -10570,10 +10695,12 @@ async function runDebate(args, opts) {
|
|
|
10570
10695
|
const earlyStopThreshold = Number.isFinite(earlyStopThresholdRaw) ? earlyStopThresholdRaw : 0.7;
|
|
10571
10696
|
let earlyStoppedRound = null;
|
|
10572
10697
|
let agreementBlock = null;
|
|
10573
|
-
const
|
|
10574
|
-
const
|
|
10698
|
+
const resolvedModerator = resolveModerator(opts.providers, args["moderator"], opts.moderator);
|
|
10699
|
+
const moderatorName = resolvedModerator.spec.provider;
|
|
10700
|
+
const moderator = resolvedModerator.provider ?? selected[0];
|
|
10575
10701
|
const upgradeRequested = isUpgradeRequested(args) || superRequested;
|
|
10576
|
-
const
|
|
10702
|
+
const seat = moderator ? synthesisSeat({ moderator, pinned: resolvedModerator.pinned, superRequested, upgradeRequested }) : null;
|
|
10703
|
+
const upgraded = seat?.upgraded ?? false;
|
|
10577
10704
|
for (let rnd = 1; rnd <= maxRounds; rnd++) {
|
|
10578
10705
|
const roundMessages = [
|
|
10579
10706
|
{
|
|
@@ -10658,8 +10785,10 @@ ${prior.body}` });
|
|
|
10658
10785
|
let personaMeta = null;
|
|
10659
10786
|
let coReasoned = false;
|
|
10660
10787
|
let coReasonerModel = null;
|
|
10788
|
+
let moderatorUsed = null;
|
|
10661
10789
|
if (moderator) {
|
|
10662
|
-
const synthProvider =
|
|
10790
|
+
const synthProvider = seat?.provider ?? moderator;
|
|
10791
|
+
moderatorUsed = { provider: synthProvider.name, model: synthProvider.model };
|
|
10663
10792
|
const condensed = buildModeratorTranscript(transcript);
|
|
10664
10793
|
const persona = buildPersonaInjection({
|
|
10665
10794
|
toolName: "debate",
|
|
@@ -10685,7 +10814,7 @@ TRANSCRIPT:
|
|
|
10685
10814
|
${condensed}`
|
|
10686
10815
|
}
|
|
10687
10816
|
];
|
|
10688
|
-
const openAiSeat = selected.find((p) => p.name === "openai")?.model;
|
|
10817
|
+
const openAiSeat = synthProvider.name === "openai" ? synthProvider.model : selected.find((p) => p.name === "openai")?.model;
|
|
10689
10818
|
const coProvider = pickCoReasoner(opts.providers, upgradeRequested, openAiSeat);
|
|
10690
10819
|
const coReason = await coReasonThenInject({
|
|
10691
10820
|
provider: coProvider,
|
|
@@ -10745,20 +10874,22 @@ ${condensed}`
|
|
|
10745
10874
|
transcript,
|
|
10746
10875
|
synthesis
|
|
10747
10876
|
};
|
|
10877
|
+
if (moderatorUsed) result["moderator"] = moderatorUsed;
|
|
10748
10878
|
if (personaMeta && personaMeta.used !== null) result["persona"] = personaMeta;
|
|
10749
10879
|
if (compactionMeta) result["round_compaction"] = compactionMeta;
|
|
10750
10880
|
if (upgraded) {
|
|
10751
10881
|
result["reasoning_upgrade"] = {
|
|
10752
10882
|
applied: true,
|
|
10753
|
-
|
|
10754
|
-
|
|
10883
|
+
provider: seat.provider.name,
|
|
10884
|
+
model: seat.provider.model,
|
|
10885
|
+
label: seat.label ?? seat.provider.model,
|
|
10755
10886
|
seat: "moderator synthesis",
|
|
10756
10887
|
...coReasoned && coReasonerModel ? { co_reasoner: { model: coReasonerModel, label: coReasonLabel(coReasonerModel) } } : {}
|
|
10757
10888
|
};
|
|
10758
10889
|
} else if (upgradeRequested) {
|
|
10759
10890
|
result["reasoning_upgrade"] = {
|
|
10760
10891
|
applied: false,
|
|
10761
|
-
reason:
|
|
10892
|
+
reason: seat?.skipReason ?? "no moderator was available for the upgrade."
|
|
10762
10893
|
};
|
|
10763
10894
|
} else {
|
|
10764
10895
|
const assessment = assessReasoning(topic);
|
|
@@ -11390,12 +11521,25 @@ function runListProviders(args, opts) {
|
|
|
11390
11521
|
}
|
|
11391
11522
|
const result = {
|
|
11392
11523
|
providers,
|
|
11393
|
-
moderator_default: opts.moderatorDefault ??
|
|
11524
|
+
moderator_default: opts.moderatorDefault ?? DEFAULT_MODERATOR,
|
|
11525
|
+
// Who will actually moderate right now: the configured spec if that
|
|
11526
|
+
// provider has a key, else the first available (what the tools fall to).
|
|
11527
|
+
moderator: describeModerator(opts.providers ?? {}, opts.moderatorDefault),
|
|
11394
11528
|
usage_hint: USAGE_HINT
|
|
11395
11529
|
};
|
|
11396
11530
|
if (superRequested) result["super_mode"] = true;
|
|
11397
11531
|
return result;
|
|
11398
11532
|
}
|
|
11533
|
+
function describeModerator(providers, spec) {
|
|
11534
|
+
const r = resolveModerator(providers, spec);
|
|
11535
|
+
const p = r.provider ?? Object.values(providers)[0];
|
|
11536
|
+
return {
|
|
11537
|
+
spec: spec ?? DEFAULT_MODERATOR,
|
|
11538
|
+
provider: p?.name ?? null,
|
|
11539
|
+
model: p?.model ?? null,
|
|
11540
|
+
available: r.provider !== void 0
|
|
11541
|
+
};
|
|
11542
|
+
}
|
|
11399
11543
|
|
|
11400
11544
|
// src/tools/models.ts
|
|
11401
11545
|
init_esm_shims();
|
|
@@ -12956,7 +13100,7 @@ var CHECK_INTERVAL_SECONDS = 3 * 24 * 60 * 60;
|
|
|
12956
13100
|
var DEFAULT_PACKAGE = "crosscheck-cli";
|
|
12957
13101
|
var FETCH_TIMEOUT_MS = 3e3;
|
|
12958
13102
|
function engineVersion() {
|
|
12959
|
-
return true ? "0.2.
|
|
13103
|
+
return true ? "0.2.31" : "0.0.0-dev";
|
|
12960
13104
|
}
|
|
12961
13105
|
function defaultUpdateCachePath() {
|
|
12962
13106
|
const base = process.env["CROSSCHECK_DATA_DIR"] || path10.join(os.homedir() || os.tmpdir(), ".crosscheck");
|
|
@@ -13403,7 +13547,7 @@ var HELP_CATALOG = [
|
|
|
13403
13547
|
primaryArg: "topic",
|
|
13404
13548
|
summary: "Bounded multi-round debate between models, ending in a synthesized recommendation.",
|
|
13405
13549
|
example: "xc debate should we adopt a monorepo?",
|
|
13406
|
-
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.
|
|
13550
|
+
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.`
|
|
13407
13551
|
},
|
|
13408
13552
|
{
|
|
13409
13553
|
name: "coordinate",
|
|
@@ -13646,6 +13790,10 @@ function renderHelpCommand(entry) {
|
|
|
13646
13790
|
}
|
|
13647
13791
|
|
|
13648
13792
|
// src/tools/index.ts
|
|
13793
|
+
var MODERATOR_PARAM = {
|
|
13794
|
+
type: "string",
|
|
13795
|
+
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`).'
|
|
13796
|
+
};
|
|
13649
13797
|
function defineTool(opts) {
|
|
13650
13798
|
return {
|
|
13651
13799
|
name: opts.name,
|
|
@@ -13880,7 +14028,7 @@ function createTool(o, toolName, cheapDefault) {
|
|
|
13880
14028
|
instruction: { type: "string" },
|
|
13881
14029
|
documents: { type: "array", items: { type: "string" } },
|
|
13882
14030
|
providers: { type: "array", items: { type: "string" } },
|
|
13883
|
-
moderator:
|
|
14031
|
+
moderator: MODERATOR_PARAM,
|
|
13884
14032
|
constraints: { type: "string" },
|
|
13885
14033
|
target_path: { type: "string" },
|
|
13886
14034
|
session_id: { type: "string" },
|
|
@@ -13921,7 +14069,7 @@ function orchestrateTool(providers, allowlist, moderator, storage, pricing, brea
|
|
|
13921
14069
|
dag: { type: "object", additionalProperties: true },
|
|
13922
14070
|
context: { type: "string" },
|
|
13923
14071
|
providers: { type: "array", items: { type: "string" } },
|
|
13924
|
-
moderator:
|
|
14072
|
+
moderator: MODERATOR_PARAM,
|
|
13925
14073
|
fail_fast: { type: "boolean" },
|
|
13926
14074
|
plan_only: { type: "boolean" },
|
|
13927
14075
|
cheap_mode: { type: "boolean" },
|
|
@@ -14300,7 +14448,7 @@ function planTool(providers, allowlist, storage, breakers, transcriptsDir, repoR
|
|
|
14300
14448
|
constraints: { type: "string" },
|
|
14301
14449
|
context: { type: "string" },
|
|
14302
14450
|
providers: { type: "array", items: { type: "string" } },
|
|
14303
|
-
moderator:
|
|
14451
|
+
moderator: MODERATOR_PARAM,
|
|
14304
14452
|
session_id: { type: "string" },
|
|
14305
14453
|
structured: { type: "boolean" },
|
|
14306
14454
|
mode: { type: "string", enum: ["fast", "thorough"] },
|
|
@@ -14362,7 +14510,7 @@ function coordinateTool(providers, allowlist, innerCallers, storage, breakers, t
|
|
|
14362
14510
|
providers: { type: "array", items: { type: "string" } },
|
|
14363
14511
|
proposer: { type: "string" },
|
|
14364
14512
|
synthesizer: { type: "string" },
|
|
14365
|
-
moderator:
|
|
14513
|
+
moderator: MODERATOR_PARAM,
|
|
14366
14514
|
critics: { type: "array", items: { type: "string" } },
|
|
14367
14515
|
session_id: { type: "string" },
|
|
14368
14516
|
untrusted_input: { type: "boolean" },
|
|
@@ -14395,7 +14543,7 @@ function debateTool(providers, allowlist, innerCallers, storage, pricing, breake
|
|
|
14395
14543
|
context: { type: "string" },
|
|
14396
14544
|
max_rounds: { type: "integer", minimum: 1 },
|
|
14397
14545
|
providers: { type: "array", items: { type: "string" } },
|
|
14398
|
-
moderator:
|
|
14546
|
+
moderator: MODERATOR_PARAM,
|
|
14399
14547
|
session_id: { type: "string" },
|
|
14400
14548
|
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.' },
|
|
14401
14549
|
structured: { type: "boolean" },
|
|
@@ -15398,8 +15546,8 @@ function mapConfig(raw, sourcePath) {
|
|
|
15398
15546
|
if (pa === null) result.providerAllowlist = null;
|
|
15399
15547
|
else if (strArr(pa) !== void 0) result.providerAllowlist = strArr(pa);
|
|
15400
15548
|
}
|
|
15401
|
-
const moderator =
|
|
15402
|
-
if (moderator) result.moderatorDefault = moderator
|
|
15549
|
+
const moderator = parseModeratorSpec(raw["moderator"]);
|
|
15550
|
+
if (moderator) result.moderatorDefault = formatModeratorSpec(moderator);
|
|
15403
15551
|
const bench = asObj(raw["bench"]);
|
|
15404
15552
|
const goldens = bench ? str(bench["goldens_dir"]) : void 0;
|
|
15405
15553
|
if (goldens) result.benchGoldensDir = goldens;
|
|
@@ -15603,7 +15751,9 @@ async function main() {
|
|
|
15603
15751
|
if (configFile?.providerAllowlist !== void 0) {
|
|
15604
15752
|
serverOpts.providerAllowlist = configFile.providerAllowlist;
|
|
15605
15753
|
}
|
|
15606
|
-
|
|
15754
|
+
const envModerator = parseModeratorSpec(process.env["CROSSCHECK_MODERATOR"]);
|
|
15755
|
+
const moderatorDefault = envModerator ? formatModeratorSpec(envModerator) : configFile?.moderatorDefault;
|
|
15756
|
+
if (moderatorDefault) serverOpts.moderatorDefault = moderatorDefault;
|
|
15607
15757
|
if (configFile?.benchGoldensDir) serverOpts.benchGoldensDir = configFile.benchGoldensDir;
|
|
15608
15758
|
if (configFile?.eventsPath) serverOpts.eventsPath = configFile.eventsPath;
|
|
15609
15759
|
await connectAndServe(transport, serverOpts);
|