crosscheck-mcp 0.2.2 → 0.2.4

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.
@@ -1483,7 +1483,10 @@ function buildAnthropicRequest(opts) {
1483
1483
  const headers = {
1484
1484
  "content-type": "application/json",
1485
1485
  "x-api-key": opts.apiKey,
1486
- "anthropic-version": ANTHROPIC_VERSION_HEADER
1486
+ "anthropic-version": ANTHROPIC_VERSION_HEADER,
1487
+ // Required for browser-origin calls (the Chrome extension); harmless from
1488
+ // Node. Without it the Anthropic API rejects requests made from a browser.
1489
+ "anthropic-dangerous-direct-browser-access": "true"
1487
1490
  };
1488
1491
  return { url: ANTHROPIC_API_URL, headers, body };
1489
1492
  }
@@ -1945,7 +1948,7 @@ async function sendOpenAICompatible(args) {
1945
1948
  // src/providers/registry.ts
1946
1949
  var DEFAULT_MODELS = {
1947
1950
  anthropic: "claude-opus-4-8",
1948
- openai: "gpt-5",
1951
+ openai: "gpt-5.5",
1949
1952
  xai: "grok-4-latest",
1950
1953
  mistral: "mistral-large-latest",
1951
1954
  groq: "llama-3.3-70b-versatile",
@@ -2033,7 +2036,7 @@ function makeGeminiProvider(model, apiKey, opts) {
2033
2036
 
2034
2037
  // src/server.ts
2035
2038
  init_cjs_shims();
2036
- var import_server2 = require("@modelcontextprotocol/sdk/server/index.js");
2039
+ var import_server = require("@modelcontextprotocol/sdk/server/index.js");
2037
2040
  var import_types8 = require("@modelcontextprotocol/sdk/types.js");
2038
2041
 
2039
2042
  // src/bridge/index.ts
@@ -2156,6 +2159,11 @@ Spend visibility:
2156
2159
  init_cjs_shims();
2157
2160
  var import_zod = require("zod");
2158
2161
 
2162
+ // src/server-meta.ts
2163
+ init_cjs_shims();
2164
+ var SERVER_NAME = "crosscheck-agent";
2165
+ var SERVER_VERSION = true ? "0.2.4" : "0.0.0-dev";
2166
+
2159
2167
  // src/tools/audit.ts
2160
2168
  init_cjs_shims();
2161
2169
  var import_node_fs5 = require("fs");
@@ -3654,6 +3662,51 @@ async function loadProviderWeights(storage, names) {
3654
3662
  return out;
3655
3663
  }
3656
3664
 
3665
+ // src/core/co-reason.ts
3666
+ init_cjs_shims();
3667
+ var CO_REASON_MODEL = "gpt-5.6";
3668
+ var CO_REASON_PROVIDER = "openai";
3669
+ var CO_REASON_LABEL = "GPT-5.6";
3670
+ function pickCoReasoner(providers, upgradeRequested) {
3671
+ if (!upgradeRequested) return null;
3672
+ const base = providers[CO_REASON_PROVIDER];
3673
+ return base ? retargetProvider(base, CO_REASON_MODEL) : null;
3674
+ }
3675
+ async function coReasonThenInject(opts) {
3676
+ const { provider, messages, maxTokens } = opts;
3677
+ if (!provider) return { messages, answer: null };
3678
+ const answer = await askOne(provider, messages, {
3679
+ maxTokens,
3680
+ temperature: 0.3,
3681
+ purpose: opts.purpose ?? "co-reason"
3682
+ });
3683
+ const text = typeof answer.response === "string" ? answer.response.trim() : "";
3684
+ if (answer.error !== void 0 || !text) {
3685
+ return { messages, answer };
3686
+ }
3687
+ return { messages: injectSecondOpinion(messages, text), answer };
3688
+ }
3689
+ function secondOpinionBlock(analysis) {
3690
+ return `
3691
+
3692
+ --- SECOND-OPINION ANALYSIS (${CO_REASON_LABEL}) ---
3693
+ Another top-tier model analyzed the same task. Weigh it critically \u2014 it may be wrong or incomplete \u2014 then produce your own final answer.
3694
+
3695
+ ${analysis}`;
3696
+ }
3697
+ function injectSecondOpinion(messages, analysis) {
3698
+ const block = secondOpinionBlock(analysis);
3699
+ const out = messages.map((m) => ({ ...m }));
3700
+ for (let i = out.length - 1; i >= 0; i--) {
3701
+ if (out[i].role === "user") {
3702
+ out[i] = { ...out[i], content: String(out[i].content) + block };
3703
+ return out;
3704
+ }
3705
+ }
3706
+ out.push({ role: "user", content: block.trimStart() });
3707
+ return out;
3708
+ }
3709
+
3657
3710
  // src/core/tiers.ts
3658
3711
  init_cjs_shims();
3659
3712
 
@@ -3848,7 +3901,7 @@ function buildSuggestedUpgrade(toolName, assessment) {
3848
3901
  model: UPGRADE_MODEL,
3849
3902
  label: UPGRADE_LABEL,
3850
3903
  reason: assessment.reason,
3851
- how: `re-run \`${toolName}\` with reasoning:"max" (or upgrade:true) to route the lead reasoning seat to ${UPGRADE_LABEL}. Other panel seats stay on their normal models, so only the high-level reasoning uses the premium model.`
3904
+ 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.`
3852
3905
  };
3853
3906
  }
3854
3907
 
@@ -3997,7 +4050,7 @@ ${outputResolved}
3997
4050
 
3998
4051
  RUBRIC ITEMS:
3999
4052
  ${rubricText}`;
4000
- const msgs = [
4053
+ let msgs = [
4001
4054
  { role: "system", content: sysMsg },
4002
4055
  { role: "user", content: userMsg }
4003
4056
  ];
@@ -4121,6 +4174,15 @@ ${rubricText}`;
4121
4174
  const upgradeRequested = isUpgradeRequested(args);
4122
4175
  const upgraded = upgradeRequested && opts.providers["anthropic"] !== void 0;
4123
4176
  const auditorForCall = upgraded ? retargetProvider(opts.providers["anthropic"], UPGRADE_MODEL) : auditor;
4177
+ const coReason = await coReasonThenInject({
4178
+ provider: pickCoReasoner(opts.providers, upgradeRequested),
4179
+ messages: msgs,
4180
+ maxTokens: 2048,
4181
+ purpose: "audit-coreason"
4182
+ });
4183
+ msgs = coReason.messages;
4184
+ if (coReason.answer) auditAnswers.push(coReason.answer);
4185
+ const coReasoned = coReason.answer !== null;
4124
4186
  const r = await requestStructured(auditorForCall, msgs, AUDIT_RUBRIC_SCHEMA, {
4125
4187
  maxTokens: 2048,
4126
4188
  maxRetries: 1,
@@ -4176,7 +4238,8 @@ ${rubricText}`;
4176
4238
  applied: true,
4177
4239
  model: UPGRADE_MODEL,
4178
4240
  label: UPGRADE_LABEL,
4179
- seat: "auditor"
4241
+ seat: "auditor",
4242
+ ...coReasoned ? { co_reasoner: { model: CO_REASON_MODEL, label: CO_REASON_LABEL } } : {}
4180
4243
  };
4181
4244
  } else if (upgradeRequested) {
4182
4245
  result["reasoning_upgrade"] = {
@@ -5702,7 +5765,7 @@ ${ctxBody}` });
5702
5765
  args["worker_tool_cost_cap_mode"],
5703
5766
  opts.workerToolsCfg
5704
5767
  );
5705
- const workerCall = (p) => {
5768
+ const dispatchOne = (p) => {
5706
5769
  if (acceptedWorkerTools.length > 0 && opts.innerCallers) {
5707
5770
  const opts2 = {
5708
5771
  provider: p,
@@ -5724,6 +5787,15 @@ ${ctxBody}` });
5724
5787
  purpose: "confer"
5725
5788
  });
5726
5789
  };
5790
+ const onAnswer = opts.onAnswer;
5791
+ const workerCall = onAnswer ? async (p) => {
5792
+ const answer = await dispatchOne(p);
5793
+ try {
5794
+ onAnswer(answer, p.name);
5795
+ } catch {
5796
+ }
5797
+ return answer;
5798
+ } : dispatchOne;
5727
5799
  if (earlyStop && selected.length >= 3) {
5728
5800
  const phase1 = await Promise.all(selected.slice(0, 2).map(workerCall));
5729
5801
  const phase1Clean = phase1.filter(
@@ -7835,7 +7907,7 @@ Synthesize the node outputs into a single coherent deliverable. Preserve any [MI
7835
7907
  });
7836
7908
  const personaMeta = persona.meta;
7837
7909
  const recombineSys = "You are the orchestrator. Combine node outputs into the final result.";
7838
- const recMsgs = [
7910
+ let recMsgs = [
7839
7911
  { role: "system", content: persona.block ? `${persona.block}
7840
7912
 
7841
7913
  ${recombineSys}` : recombineSys },
@@ -7874,6 +7946,15 @@ ${recombineSys}` : recombineSys },
7874
7946
  provider: synthProvider.name
7875
7947
  } }
7876
7948
  );
7949
+ const coReason = await coReasonThenInject({
7950
+ provider: pickCoReasoner(opts.providers, upgradeRequested),
7951
+ messages: recMsgs,
7952
+ maxTokens,
7953
+ purpose: "orchestrate-coreason"
7954
+ });
7955
+ recMsgs = coReason.messages;
7956
+ if (coReason.answer) orchAnswers.push(coReason.answer);
7957
+ const coReasoned = coReason.answer !== null;
7877
7958
  let synthAns = await askOne(synthProvider, recMsgs, {
7878
7959
  maxTokens,
7879
7960
  temperature: 0.4,
@@ -7924,7 +8005,8 @@ ${recombineSys}` : recombineSys },
7924
8005
  applied: true,
7925
8006
  model: UPGRADE_MODEL,
7926
8007
  label: UPGRADE_LABEL,
7927
- seat: "recombine/synthesis"
8008
+ seat: "recombine/synthesis",
8009
+ ...coReasoned ? { co_reasoner: { model: CO_REASON_MODEL, label: CO_REASON_LABEL } } : {}
7928
8010
  };
7929
8011
  } else if (upgradeRequested) {
7930
8012
  result["reasoning_upgrade"] = {
@@ -9245,7 +9327,7 @@ ${proposalRender}`
9245
9327
  critiqueAnswers[i]?.response ?? ""
9246
9328
  )
9247
9329
  ).join("\n\n") : "(no critiques)";
9248
- const synthMessages = [
9330
+ let synthMessages = [
9249
9331
  { role: "system", content: synthSystem },
9250
9332
  {
9251
9333
  role: "user",
@@ -9258,6 +9340,14 @@ CRITIQUES:
9258
9340
  ${critiqueBlock}`
9259
9341
  }
9260
9342
  ];
9343
+ const coReason = await coReasonThenInject({
9344
+ provider: pickCoReasoner(opts.providers, upgradeRequested),
9345
+ messages: synthMessages,
9346
+ maxTokens,
9347
+ purpose: "coordinate-coreason"
9348
+ });
9349
+ synthMessages = coReason.messages;
9350
+ const coReasonAns = coReason.answer;
9261
9351
  const synthResult = await requestStructured(
9262
9352
  synthForCall,
9263
9353
  synthMessages,
@@ -9313,7 +9403,8 @@ ${critiqueBlock}`
9313
9403
  applied: true,
9314
9404
  model: UPGRADE_MODEL,
9315
9405
  label: UPGRADE_LABEL,
9316
- seat: "synthesizer"
9406
+ seat: "synthesizer",
9407
+ ...coReasonAns ? { co_reasoner: { model: CO_REASON_MODEL, label: CO_REASON_LABEL } } : {}
9317
9408
  };
9318
9409
  } else if (upgradeRequested) {
9319
9410
  result["reasoning_upgrade"] = {
@@ -9329,6 +9420,7 @@ ${critiqueBlock}`
9329
9420
  const allCallEnvelopes = [
9330
9421
  scannedProposal,
9331
9422
  ...scannedCritiques,
9423
+ ...coReasonAns ? [coReasonAns] : [],
9332
9424
  synthAns
9333
9425
  ];
9334
9426
  const wallMs = Math.trunc(import_node_perf_hooks7.performance.now() - callStartedWall);
@@ -9893,7 +9985,14 @@ ${prior}` });
9893
9985
  }
9894
9986
  for (const p of selected) {
9895
9987
  const entry = await callPanelist(p, roundMessages);
9896
- transcript.push({ ...entry, round: rnd });
9988
+ const withRound = { ...entry, round: rnd };
9989
+ transcript.push(withRound);
9990
+ if (opts.onTurn) {
9991
+ try {
9992
+ opts.onTurn(withRound, rnd, p.name);
9993
+ } catch {
9994
+ }
9995
+ }
9897
9996
  }
9898
9997
  if (earlyStopOpt && rnd < maxRounds) {
9899
9998
  const thisRound = transcript.filter(
@@ -9928,6 +10027,7 @@ ${prior}` });
9928
10027
  let synthesisStructured = null;
9929
10028
  let synthesisErrors = [];
9930
10029
  let personaMeta = null;
10030
+ let coReasoned = false;
9931
10031
  if (moderator) {
9932
10032
  const synthProvider = upgraded ? retargetProvider(opts.providers["anthropic"], UPGRADE_MODEL) : moderator;
9933
10033
  const condensed = transcript.map(
@@ -9943,7 +10043,7 @@ ${e.response ?? "(error)"}`
9943
10043
  });
9944
10044
  personaMeta = persona.meta;
9945
10045
  const synthSys = "You are the moderator. Synthesise the debate into a single grounded recommendation.";
9946
- const synthMessages = [
10046
+ let synthMessages = [
9947
10047
  {
9948
10048
  role: "system",
9949
10049
  content: persona.block ? `${persona.block}
@@ -9958,6 +10058,15 @@ TRANSCRIPT:
9958
10058
  ${condensed}`
9959
10059
  }
9960
10060
  ];
10061
+ const coReason = await coReasonThenInject({
10062
+ provider: pickCoReasoner(opts.providers, upgradeRequested),
10063
+ messages: synthMessages,
10064
+ maxTokens,
10065
+ purpose: "debate-coreason"
10066
+ });
10067
+ synthMessages = coReason.messages;
10068
+ if (coReason.answer) extraAnswers.push(coReason.answer);
10069
+ coReasoned = coReason.answer !== null;
9961
10070
  if (structuredOpt) {
9962
10071
  const r = await requestStructured(
9963
10072
  synthProvider,
@@ -9975,6 +10084,12 @@ ${condensed}`
9975
10084
  purpose: "synth"
9976
10085
  });
9977
10086
  }
10087
+ if (synthesis && opts.onSynthesis) {
10088
+ try {
10089
+ opts.onSynthesis(synthesis);
10090
+ } catch {
10091
+ }
10092
+ }
9978
10093
  }
9979
10094
  let claimsBlock = null;
9980
10095
  if (Boolean(args["extract_claims"])) {
@@ -10006,7 +10121,8 @@ ${condensed}`
10006
10121
  applied: true,
10007
10122
  model: UPGRADE_MODEL,
10008
10123
  label: UPGRADE_LABEL,
10009
- seat: "moderator synthesis"
10124
+ seat: "moderator synthesis",
10125
+ ...coReasoned ? { co_reasoner: { model: CO_REASON_MODEL, label: CO_REASON_LABEL } } : {}
10010
10126
  };
10011
10127
  } else if (upgradeRequested) {
10012
10128
  result["reasoning_upgrade"] = {
@@ -11807,7 +11923,7 @@ async function runSolve(args, opts) {
11807
11923
  return { error: "no active providers have API keys in .env" };
11808
11924
  }
11809
11925
  const systemMsg = "You are solving a problem step-by-step. Produce ONLY the literal solution (code, command, or text) with no commentary, no markdown fences, no preamble. Your output is fed directly to a verifier.";
11810
- const userBlock = context ? `CONTEXT:
11926
+ let userBlock = context ? `CONTEXT:
11811
11927
  ${context}
11812
11928
 
11813
11929
  PROBLEM:
@@ -11834,6 +11950,20 @@ ${problem}` : problem;
11834
11950
  const upgradeRequested = isUpgradeRequested(args);
11835
11951
  const fableProvider = upgradeRequested && opts.providers["anthropic"] ? retargetProvider(opts.providers["anthropic"], UPGRADE_MODEL) : null;
11836
11952
  const upgraded = fableProvider !== null;
11953
+ const coProvider = pickCoReasoner(opts.providers, upgradeRequested);
11954
+ let coReasoned = false;
11955
+ if (coProvider) {
11956
+ const coAns = await askOne(
11957
+ coProvider,
11958
+ [{ role: "system", content: systemMsg }, { role: "user", content: userBlock }],
11959
+ { maxTokens, temperature: 0.3, purpose: "solve-coreason" }
11960
+ );
11961
+ solveAnswers.push(coAns);
11962
+ coReasoned = true;
11963
+ if (coAns.error === void 0 && typeof coAns.response === "string" && coAns.response.trim()) {
11964
+ userBlock += secondOpinionBlock(coAns.response.trim());
11965
+ }
11966
+ }
11837
11967
  for (let i = 1; i <= maxAttempts; i++) {
11838
11968
  const provider = fableProvider ?? selected[(i - 1) % selected.length];
11839
11969
  const msgs = [
@@ -11937,7 +12067,8 @@ Re-emit the FULL solution. No commentary.`
11937
12067
  applied: true,
11938
12068
  model: UPGRADE_MODEL,
11939
12069
  label: UPGRADE_LABEL,
11940
- seat: "solver"
12070
+ seat: "solver",
12071
+ ...coReasoned ? { co_reasoner: { model: CO_REASON_MODEL, label: CO_REASON_LABEL } } : {}
11941
12072
  };
11942
12073
  } else if (upgradeRequested) {
11943
12074
  result["reasoning_upgrade"] = {
@@ -12228,7 +12359,7 @@ var CHECK_INTERVAL_SECONDS = 3 * 24 * 60 * 60;
12228
12359
  var DEFAULT_PACKAGE = "crosscheck-cli";
12229
12360
  var FETCH_TIMEOUT_MS = 3e3;
12230
12361
  function engineVersion() {
12231
- return true ? "0.2.2" : "0.0.0-dev";
12362
+ return true ? "0.2.4" : "0.0.0-dev";
12232
12363
  }
12233
12364
  function defaultUpdateCachePath() {
12234
12365
  const base = process.env["CROSSCHECK_DATA_DIR"] || import_node_path13.default.join(import_node_os2.default.homedir() || import_node_os2.default.tmpdir(), ".crosscheck");
@@ -14079,8 +14210,6 @@ async function flush() {
14079
14210
  }
14080
14211
 
14081
14212
  // src/server.ts
14082
- var SERVER_NAME = "crosscheck-agent";
14083
- var SERVER_VERSION = true ? "0.2.2" : "0.0.0-dev";
14084
14213
  function extractRunSummaryText(out) {
14085
14214
  if (out === null || typeof out !== "object" || Array.isArray(out)) return void 0;
14086
14215
  const rec = out;
@@ -14094,7 +14223,7 @@ function extractRunSummaryText(out) {
14094
14223
  return void 0;
14095
14224
  }
14096
14225
  function createServer(opts = {}) {
14097
- const server = new import_server2.Server(
14226
+ const server = new import_server.Server(
14098
14227
  { name: SERVER_NAME, version: SERVER_VERSION },
14099
14228
  {
14100
14229
  capabilities: { tools: {} },