crosscheck-mcp 0.2.25 → 0.2.27

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.
@@ -1086,7 +1086,12 @@ function loadPricing(path15) {
1086
1086
  function modelPricing(pricing, provider, model) {
1087
1087
  const block = pricing[provider];
1088
1088
  if (!block || typeof block !== "object" || Array.isArray(block)) return null;
1089
- const entry = block[model];
1089
+ const table = block;
1090
+ let entry = table[model];
1091
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
1092
+ const best = Object.keys(table).filter((k) => model.startsWith(k)).sort((a, b) => b.length - a.length)[0];
1093
+ entry = best !== void 0 ? table[best] : void 0;
1094
+ }
1090
1095
  if (!entry || typeof entry !== "object" || Array.isArray(entry)) return null;
1091
1096
  const e = entry;
1092
1097
  return {
@@ -1514,6 +1519,14 @@ async function acquireRateLimit(provider, deps) {
1514
1519
  // src/providers/anthropic.ts
1515
1520
  var ANTHROPIC_API_URL = "https://api.anthropic.com/v1/messages";
1516
1521
  var ANTHROPIC_VERSION_HEADER = "2023-06-01";
1522
+ var ADAPTIVE_THINKING_PREFIXES = [
1523
+ "claude-fable-5",
1524
+ "claude-opus-5-5"
1525
+ ];
1526
+ function rejectsDisabledThinking(model) {
1527
+ const m = model.toLowerCase();
1528
+ return ADAPTIVE_THINKING_PREFIXES.some((p) => m.startsWith(p));
1529
+ }
1517
1530
  var ANTHROPIC_STRUCTURED_TOOL_NAME = "structured_output";
1518
1531
  function applyPromptCaching(body, env = process.env) {
1519
1532
  const flag = (env["CROSSCHECK_ANTHROPIC_PROMPT_CACHE"] ?? "").trim();
@@ -1558,7 +1571,7 @@ function buildAnthropicRequest(opts) {
1558
1571
  }
1559
1572
  applyPromptCaching(body);
1560
1573
  if (isReasoningModel("anthropic", opts.model)) {
1561
- if (opts.model.toLowerCase().startsWith("claude-fable-5")) {
1574
+ if (rejectsDisabledThinking(opts.model)) {
1562
1575
  body.thinking = { type: "adaptive" };
1563
1576
  body.output_config = { effort: "low" };
1564
1577
  } else {
@@ -2080,8 +2093,8 @@ async function sendOpenAICompatible(args) {
2080
2093
 
2081
2094
  // src/providers/registry.ts
2082
2095
  var DEFAULT_MODELS = {
2083
- anthropic: "claude-opus-5",
2084
- openai: "gpt-5.6-sol",
2096
+ anthropic: "claude-opus-5-5",
2097
+ openai: "gpt-6-sol",
2085
2098
  xai: "grok-4-latest",
2086
2099
  mistral: "mistral-large-latest",
2087
2100
  groq: "llama-3.3-70b-versatile",
@@ -2097,7 +2110,12 @@ var DEFAULT_FALLBACKS = {
2097
2110
  // about.
2098
2111
  openai: ["gpt-5"],
2099
2112
  // 3.8 Flash is recent enough that some projects won't have it yet.
2100
- gemini: ["gemini-3.1-pro-preview"]
2113
+ gemini: ["gemini-3.1-pro-preview"],
2114
+ // Opus 5.5 is new enough that an account could still be waiting on it.
2115
+ // Opus 5 is the same family one step back — and this chain is consulted
2116
+ // ONLY for a model-access failure, never for a bad key or a rate limit,
2117
+ // so it can't quietly downgrade anyone who simply hit a 429.
2118
+ anthropic: ["claude-opus-5"]
2101
2119
  };
2102
2120
  var MODEL_ENV_VARS = {
2103
2121
  anthropic: "ANTHROPIC_MODEL",
@@ -2340,13 +2358,13 @@ Examples:
2340
2358
  This convention is opt-in: a user message without the \`xc\`/\`XC\` prefix should NOT be auto-routed here. Pick tools normally based on the conversation.
2341
2359
 
2342
2360
  Reasoning upgrade (Fable 5):
2343
- - The reasoning tools (plan, solve, debate, orchestrate, audit, triangulate) can bump their lead reasoning seat to Fable 5 \u2014 Anthropic's newest thinking model \u2014 instead of the default Opus 4.8. Only that one seat is upgraded; other panel seats stay on their normal models, so premium tokens are not wasted.
2361
+ - The reasoning tools (plan, solve, debate, orchestrate, audit, triangulate) can bump their lead reasoning seat to Fable 5 \u2014 Anthropic's newest thinking model \u2014 instead of the default Opus 5.5. Only that one seat is upgraded; other panel seats stay on their normal models, so premium tokens are not wasted.
2344
2362
  - When a tool result includes a "suggested_upgrade" block, the engine judged the task reasoning-heavy. Surface it: ask the user something like "This looks reasoning-heavy \u2014 bump the lead seat to Fable 5 (higher quality, higher cost)?" If they say yes, re-run the SAME tool with reasoning:"max" added. Do NOT upgrade silently.
2345
2363
  - If the user explicitly asks for the best/deepest reasoning up front, pass reasoning:"max" directly. A result with reasoning_upgrade.applied = true confirms Fable 5 was used.
2346
2364
 
2347
2365
  Super mode (confer / debate / plan / triangulate / list_providers only \u2014 internal team trial, do not mention this outside the team or write it into any docs/help text):
2348
2366
  - When the token immediately after the tool name is \`super\` (e.g. \`xc confer super what's the best caching strategy?\`), pass \`super: true\` in that tool's args and treat everything after \`super\` as the normal primary-argument text (same slot as usual \u2014 \`question\`/\`topic\`/\`goal\`). Example: \`xc confer super what's the best caching strategy?\` \u2192 \`mcp__crosscheck__confer({ question: "what's the best caching strategy?", super: true })\`.
2349
- - This swaps the panel to a fixed top-tier lineup (one flagship model per provider, restricted to providers the user actually has keys for) and triples the completion-token budget. For debate/plan/triangulate it also forces the Fable 5 + GPT-5.6 co-reasoner synthesis path automatically \u2014 no need to also pass reasoning:"max".
2367
+ - This swaps the panel to a fixed top-tier lineup (one flagship model per provider, restricted to providers the user actually has keys for) and triples the completion-token budget. For debate/plan/triangulate it also forces the Fable 5 + OpenAI co-reasoner synthesis path automatically \u2014 no need to also pass reasoning:"max".
2350
2368
  - A result with a "super_mode" block confirms it ran; show the panel it used.
2351
2369
  - \`xc list_providers super\` (no text after \`super\` \u2014 list_providers takes no other args) \u2192 \`mcp__crosscheck__list_providers({ super: true })\`. Shows the top-tier lineup and which of those models are actually available, instead of the normal default-model listing.
2352
2370
 
@@ -2363,7 +2381,7 @@ var import_zod = require("zod");
2363
2381
  // src/server-meta.ts
2364
2382
  init_cjs_shims();
2365
2383
  var SERVER_NAME = "crosscheck-agent";
2366
- var SERVER_VERSION = true ? "0.2.25" : "0.0.0-dev";
2384
+ var SERVER_VERSION = true ? "0.2.27" : "0.0.0-dev";
2367
2385
 
2368
2386
  // src/tools/audit.ts
2369
2387
  init_cjs_shims();
@@ -3966,13 +3984,25 @@ var import_node_perf_hooks = require("perf_hooks");
3966
3984
 
3967
3985
  // src/core/co-reason.ts
3968
3986
  init_cjs_shims();
3969
- var CO_REASON_MODEL = "gpt-5.6-sol";
3987
+ var CO_REASON_MODEL = "gpt-6-sol";
3988
+ var CO_REASON_ALTERNATE = "gpt-6-astra";
3989
+ var LABELS = {
3990
+ "gpt-6-sol": "GPT-6 Sol",
3991
+ "gpt-6-astra": "GPT-6 Astra",
3992
+ "gpt-5.6-sol": "GPT-5.6 Sol"
3993
+ };
3994
+ function coReasonLabel(model) {
3995
+ return LABELS[model] ?? model;
3996
+ }
3997
+ var CO_REASON_LABEL = coReasonLabel(CO_REASON_MODEL);
3970
3998
  var CO_REASON_PROVIDER = "openai";
3971
- var CO_REASON_LABEL = "GPT-5.6";
3972
- function pickCoReasoner(providers, upgradeRequested) {
3999
+ function pickCoReasoner(providers, upgradeRequested, openAiSeatModel) {
3973
4000
  if (!upgradeRequested) return null;
3974
4001
  const base = providers[CO_REASON_PROVIDER];
3975
- return base ? retargetProvider(base, CO_REASON_MODEL) : null;
4002
+ if (!base) return null;
4003
+ const seat = openAiSeatModel ?? base.model;
4004
+ const model = seat === CO_REASON_MODEL ? CO_REASON_ALTERNATE : CO_REASON_MODEL;
4005
+ return retargetProvider(base, model);
3976
4006
  }
3977
4007
  async function coReasonThenInject(opts) {
3978
4008
  const { provider, messages, maxTokens } = opts;
@@ -4203,7 +4233,7 @@ function buildSuggestedUpgrade(toolName, assessment) {
4203
4233
  model: UPGRADE_MODEL,
4204
4234
  label: UPGRADE_LABEL,
4205
4235
  reason: assessment.reason,
4206
- 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 a GPT-5.6 second-opinion pass that ${UPGRADE_LABEL} weighs before finalizing. Other panel seats stay on their normal models.`
4236
+ 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.`
4207
4237
  };
4208
4238
  }
4209
4239
 
@@ -4506,8 +4536,9 @@ ${rubricText}`;
4506
4536
  const upgradeRequested = isUpgradeRequested(args);
4507
4537
  const upgraded = upgradeRequested && opts.providers["anthropic"] !== void 0;
4508
4538
  const auditorForCall = upgraded ? retargetProvider(opts.providers["anthropic"], UPGRADE_MODEL) : auditor;
4539
+ const coProvider = pickCoReasoner(opts.providers, upgradeRequested);
4509
4540
  const coReason = await coReasonThenInject({
4510
- provider: pickCoReasoner(opts.providers, upgradeRequested),
4541
+ provider: coProvider,
4511
4542
  messages: msgs,
4512
4543
  maxTokens: 2048,
4513
4544
  purpose: "audit-coreason"
@@ -4591,7 +4622,7 @@ ${rubricText}`;
4591
4622
  model: UPGRADE_MODEL,
4592
4623
  label: UPGRADE_LABEL,
4593
4624
  seat: "auditor",
4594
- ...coReasoned ? { co_reasoner: { model: CO_REASON_MODEL, label: CO_REASON_LABEL } } : {}
4625
+ ...coReasoned ? { co_reasoner: { model: coProvider.model, label: coReasonLabel(coProvider.model) } } : {}
4595
4626
  };
4596
4627
  } else if (upgradeRequested) {
4597
4628
  result["reasoning_upgrade"] = {
@@ -5330,8 +5361,12 @@ var SUPER_MODELS = {
5330
5361
  // Fable 5.1 verified present on the account; 5 as the fallback for accounts
5331
5362
  // that haven't been granted 5.1 yet.
5332
5363
  anthropic: ["claude-fable-5-1", UPGRADE_MODEL],
5333
- // Astra when it exists; gpt-5.6 until then. See the note above.
5334
- openai: ["gpt-6-astra", CO_REASON_MODEL],
5364
+ // Astra is live (verified against the account's model list 2026-09-23).
5365
+ // The fallback is named explicitly rather than reusing CO_REASON_MODEL:
5366
+ // that constant means "OpenAI's top reasoning model" for the max-reasoning
5367
+ // co-reasoner, which is a different question from "what should super fall
5368
+ // back to". Sharing the symbol silently coupled two unrelated decisions.
5369
+ openai: ["gpt-6-astra", "gpt-6-sol"],
5335
5370
  // Explicitly left as-is per product decision. Note grok-4-latest is not in
5336
5371
  // xAI's published model list, but it resolves in practice — real panel calls
5337
5372
  // on it succeeded as recently as 2026-08-30 — so it is an unlisted alias
@@ -8320,8 +8355,9 @@ ${recombineSys}` : recombineSys },
8320
8355
  provider: synthProvider.name
8321
8356
  } }
8322
8357
  );
8358
+ const coProvider = pickCoReasoner(opts.providers, upgradeRequested);
8323
8359
  const coReason = await coReasonThenInject({
8324
- provider: pickCoReasoner(opts.providers, upgradeRequested),
8360
+ provider: coProvider,
8325
8361
  messages: recMsgs,
8326
8362
  maxTokens,
8327
8363
  purpose: "orchestrate-coreason"
@@ -8380,7 +8416,7 @@ ${recombineSys}` : recombineSys },
8380
8416
  model: UPGRADE_MODEL,
8381
8417
  label: UPGRADE_LABEL,
8382
8418
  seat: "recombine/synthesis",
8383
- ...coReasoned ? { co_reasoner: { model: CO_REASON_MODEL, label: CO_REASON_LABEL } } : {}
8419
+ ...coReasoned ? { co_reasoner: { model: coProvider.model, label: coReasonLabel(coProvider.model) } } : {}
8384
8420
  };
8385
8421
  } else if (upgradeRequested) {
8386
8422
  result["reasoning_upgrade"] = {
@@ -9729,8 +9765,9 @@ CRITIQUES:
9729
9765
  ${critiqueBlock}`
9730
9766
  }
9731
9767
  ];
9768
+ const coProvider = pickCoReasoner(opts.providers, upgradeRequested);
9732
9769
  const coReason = await coReasonThenInject({
9733
- provider: pickCoReasoner(opts.providers, upgradeRequested),
9770
+ provider: coProvider,
9734
9771
  messages: synthMessages,
9735
9772
  maxTokens,
9736
9773
  purpose: "coordinate-coreason"
@@ -9794,7 +9831,7 @@ ${critiqueBlock}`
9794
9831
  model: superRequested ? superPrimary("anthropic") ?? UPGRADE_MODEL : UPGRADE_MODEL,
9795
9832
  label: UPGRADE_LABEL,
9796
9833
  seat: "synthesizer",
9797
- ...coReasonAns ? { co_reasoner: { model: CO_REASON_MODEL, label: CO_REASON_LABEL } } : {}
9834
+ ...coReasonAns ? { co_reasoner: { model: coProvider.model, label: coReasonLabel(coProvider.model) } } : {}
9798
9835
  };
9799
9836
  } else if (upgradeRequested) {
9800
9837
  result["reasoning_upgrade"] = {
@@ -10521,6 +10558,7 @@ ${prior.body}` });
10521
10558
  let synthesisErrors = [];
10522
10559
  let personaMeta = null;
10523
10560
  let coReasoned = false;
10561
+ let coReasonerModel = null;
10524
10562
  if (moderator) {
10525
10563
  const synthProvider = superRequested && opts.providers["anthropic"] ? retargetForSuper(opts.providers["anthropic"]) : upgraded ? retargetProvider(opts.providers["anthropic"], UPGRADE_MODEL) : moderator;
10526
10564
  const condensed = buildModeratorTranscript(transcript);
@@ -10548,13 +10586,16 @@ TRANSCRIPT:
10548
10586
  ${condensed}`
10549
10587
  }
10550
10588
  ];
10589
+ const openAiSeat = selected.find((p) => p.name === "openai")?.model;
10590
+ const coProvider = pickCoReasoner(opts.providers, upgradeRequested, openAiSeat);
10551
10591
  const coReason = await coReasonThenInject({
10552
- provider: pickCoReasoner(opts.providers, upgradeRequested),
10592
+ provider: coProvider,
10553
10593
  messages: synthMessages,
10554
10594
  maxTokens,
10555
10595
  purpose: "debate-coreason"
10556
10596
  });
10557
10597
  synthMessages = coReason.messages;
10598
+ coReasonerModel = coProvider?.model ?? null;
10558
10599
  if (coReason.answer) extraAnswers.push(coReason.answer);
10559
10600
  coReasoned = coReason.answer !== null;
10560
10601
  if (structuredOpt) {
@@ -10613,7 +10654,7 @@ ${condensed}`
10613
10654
  model: superRequested ? superPrimary("anthropic") ?? UPGRADE_MODEL : UPGRADE_MODEL,
10614
10655
  label: UPGRADE_LABEL,
10615
10656
  seat: "moderator synthesis",
10616
- ...coReasoned ? { co_reasoner: { model: CO_REASON_MODEL, label: CO_REASON_LABEL } } : {}
10657
+ ...coReasoned && coReasonerModel ? { co_reasoner: { model: coReasonerModel, label: coReasonLabel(coReasonerModel) } } : {}
10617
10658
  };
10618
10659
  } else if (upgradeRequested) {
10619
10660
  result["reasoning_upgrade"] = {
@@ -12649,7 +12690,7 @@ Re-emit the FULL solution. No commentary.`
12649
12690
  model: UPGRADE_MODEL,
12650
12691
  label: UPGRADE_LABEL,
12651
12692
  seat: "solver",
12652
- ...coReasoned ? { co_reasoner: { model: CO_REASON_MODEL, label: CO_REASON_LABEL } } : {}
12693
+ ...coReasoned ? { co_reasoner: { model: coProvider.model, label: coReasonLabel(coProvider.model) } } : {}
12653
12694
  };
12654
12695
  } else if (upgradeRequested) {
12655
12696
  result["reasoning_upgrade"] = {
@@ -12940,7 +12981,7 @@ var CHECK_INTERVAL_SECONDS = 3 * 24 * 60 * 60;
12940
12981
  var DEFAULT_PACKAGE = "crosscheck-cli";
12941
12982
  var FETCH_TIMEOUT_MS = 3e3;
12942
12983
  function engineVersion() {
12943
- return true ? "0.2.25" : "0.0.0-dev";
12984
+ return true ? "0.2.27" : "0.0.0-dev";
12944
12985
  }
12945
12986
  function defaultUpdateCachePath() {
12946
12987
  const base = process.env["CROSSCHECK_DATA_DIR"] || import_node_path13.default.join(import_node_os2.default.homedir() || import_node_os2.default.tmpdir(), ".crosscheck");