crosscheck-mcp 0.2.26 → 0.2.28
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/README.md +4 -20
- package/dist/browser-ext.cjs +372 -381
- package/dist/browser-ext.cjs.map +1 -1
- package/dist/browser-ext.js +357 -366
- package/dist/browser-ext.js.map +1 -1
- package/dist/embed.cjs +374 -387
- package/dist/embed.cjs.map +1 -1
- package/dist/embed.d.cts +58 -1
- package/dist/embed.d.ts +58 -1
- package/dist/embed.js +352 -368
- package/dist/embed.js.map +1 -1
- package/dist/node-stdio.cjs +398 -483
- package/dist/node-stdio.cjs.map +1 -1
- package/dist/node-stdio.d.cts +11 -47
- package/dist/node-stdio.d.ts +11 -47
- package/dist/node-stdio.js +369 -454
- package/dist/node-stdio.js.map +1 -1
- package/dist/pricing.json +90 -22
- package/dist/self-check.cjs.map +1 -1
- package/dist/self-check.js.map +1 -1
- package/package.json +7 -2
package/dist/node-stdio.js
CHANGED
|
@@ -934,8 +934,8 @@ var init_better_sqlite3 = __esm({
|
|
|
934
934
|
|
|
935
935
|
// src/entrypoints/node-stdio.ts
|
|
936
936
|
init_esm_shims();
|
|
937
|
-
import { existsSync as existsSync14, mkdirSync as
|
|
938
|
-
import
|
|
937
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync11 } from "fs";
|
|
938
|
+
import path16 from "path";
|
|
939
939
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
940
940
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
941
941
|
|
|
@@ -952,10 +952,10 @@ var StderrEmitter = class {
|
|
|
952
952
|
}
|
|
953
953
|
};
|
|
954
954
|
var FileEmitter = class {
|
|
955
|
-
constructor(
|
|
956
|
-
this.path =
|
|
955
|
+
constructor(path17) {
|
|
956
|
+
this.path = path17;
|
|
957
957
|
try {
|
|
958
|
-
mkdirSync(dirname(
|
|
958
|
+
mkdirSync(dirname(path17), { recursive: true });
|
|
959
959
|
} catch {
|
|
960
960
|
}
|
|
961
961
|
}
|
|
@@ -988,13 +988,13 @@ var NullEmitter = class {
|
|
|
988
988
|
function buildDefaultEmitter(env) {
|
|
989
989
|
const mode = (env["CROSSCHECK_EVENTS"] ?? "stderr").toLowerCase();
|
|
990
990
|
if (mode === "off") return new NullEmitter();
|
|
991
|
-
const
|
|
991
|
+
const path17 = env["CROSSCHECK_EVENTS_PATH"];
|
|
992
992
|
if (mode === "file") {
|
|
993
|
-
return
|
|
993
|
+
return path17 ? new FileEmitter(path17) : new NullEmitter();
|
|
994
994
|
}
|
|
995
995
|
if (mode === "both") {
|
|
996
996
|
const ems = [new StderrEmitter()];
|
|
997
|
-
if (
|
|
997
|
+
if (path17) ems.push(new FileEmitter(path17));
|
|
998
998
|
return new TeeEmitter(ems);
|
|
999
999
|
}
|
|
1000
1000
|
return new StderrEmitter();
|
|
@@ -1043,10 +1043,10 @@ function envelopeBytes(v) {
|
|
|
1043
1043
|
// src/core/pricing.ts
|
|
1044
1044
|
init_esm_shims();
|
|
1045
1045
|
import { readFileSync } from "fs";
|
|
1046
|
-
function loadPricing(
|
|
1046
|
+
function loadPricing(path17) {
|
|
1047
1047
|
let raw;
|
|
1048
1048
|
try {
|
|
1049
|
-
raw = readFileSync(
|
|
1049
|
+
raw = readFileSync(path17, "utf8");
|
|
1050
1050
|
} catch {
|
|
1051
1051
|
return {};
|
|
1052
1052
|
}
|
|
@@ -1063,20 +1063,30 @@ function modelPricing(pricing, provider, model) {
|
|
|
1063
1063
|
const block = pricing[provider];
|
|
1064
1064
|
if (!block || typeof block !== "object" || Array.isArray(block)) return null;
|
|
1065
1065
|
const table = block;
|
|
1066
|
+
if (model.startsWith("_")) return null;
|
|
1066
1067
|
let entry = table[model];
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1068
|
+
let match = "exact";
|
|
1069
|
+
if (!isRates(entry)) {
|
|
1070
|
+
const best = Object.keys(table).filter((k) => !k.startsWith("_")).filter((k) => model.startsWith(k) && DATE_STAMP.test(model.slice(k.length))).sort((a, b) => b.length - a.length)[0];
|
|
1071
|
+
if (best !== void 0) {
|
|
1072
|
+
entry = table[best];
|
|
1073
|
+
match = "stamp";
|
|
1074
|
+
}
|
|
1070
1075
|
}
|
|
1071
|
-
if (!
|
|
1076
|
+
if (!isRates(entry)) return null;
|
|
1072
1077
|
const e = entry;
|
|
1073
1078
|
return {
|
|
1074
1079
|
prompt_per_1k: numberOrZero(e["prompt_per_1k"]),
|
|
1075
1080
|
completion_per_1k: numberOrZero(e["completion_per_1k"]),
|
|
1076
1081
|
cached_per_1k: numberOrZero(e["cached_per_1k"]),
|
|
1077
|
-
...e["estimated"] === true ? { estimated: true } : {}
|
|
1082
|
+
...e["estimated"] === true ? { estimated: true } : {},
|
|
1083
|
+
match
|
|
1078
1084
|
};
|
|
1079
1085
|
}
|
|
1086
|
+
var DATE_STAMP = /^-\d{8}$/;
|
|
1087
|
+
function isRates(v) {
|
|
1088
|
+
return Boolean(v) && typeof v === "object" && !Array.isArray(v);
|
|
1089
|
+
}
|
|
1080
1090
|
function numberOrZero(v) {
|
|
1081
1091
|
if (typeof v === "number" && Number.isFinite(v)) return v;
|
|
1082
1092
|
if (typeof v === "string") {
|
|
@@ -1216,8 +1226,20 @@ var PROVIDER_CAPS = {
|
|
|
1216
1226
|
gemini: {
|
|
1217
1227
|
family: "gemini",
|
|
1218
1228
|
system_role: "separate",
|
|
1219
|
-
|
|
1220
|
-
|
|
1229
|
+
// No sampling, on any Gemini model. Ignored since 3.6 Flash and rejected
|
|
1230
|
+
// by upcoming models (Google, 2026-10). "model" means "omit for reasoning
|
|
1231
|
+
// models", and every Gemini model is reasoning-class (below) — so this
|
|
1232
|
+
// resolves to never, through the same rule the other providers use. The
|
|
1233
|
+
// adapter also never sends it; this keeps the record honest for anything
|
|
1234
|
+
// else that reads it.
|
|
1235
|
+
supports_temperature: "model",
|
|
1236
|
+
// EVERY Gemini model is reasoning-class. The old list named three
|
|
1237
|
+
// families and missed gemini-3.8-flash — the DEFAULT — so the default
|
|
1238
|
+
// model got the small non-reasoning budgets (768 tokens for an audit)
|
|
1239
|
+
// while spending up to ~480 tokens of each call thinking. Google's docs
|
|
1240
|
+
// say thinking cannot be switched off on current models, so a list of
|
|
1241
|
+
// which ones think is a list that can only ever be incomplete.
|
|
1242
|
+
reasoning_prefixes: ["gemini-"]
|
|
1221
1243
|
},
|
|
1222
1244
|
// Qwen's "Max" tier (qwen-v3.8, qwen-v3.7) is a standard instruct/chat
|
|
1223
1245
|
// model, not a visible-reasoning model like QwQ — normal temperature and
|
|
@@ -1342,6 +1364,74 @@ function httpFailureToProviderError(provider, status, bodyText, retryAfterS, mod
|
|
|
1342
1364
|
);
|
|
1343
1365
|
}
|
|
1344
1366
|
|
|
1367
|
+
// src/providers/network-errors.ts
|
|
1368
|
+
init_esm_shims();
|
|
1369
|
+
function codeOf(e) {
|
|
1370
|
+
if (!e || typeof e !== "object") return null;
|
|
1371
|
+
const c = e.code;
|
|
1372
|
+
return typeof c === "string" && c.length > 0 ? c : null;
|
|
1373
|
+
}
|
|
1374
|
+
function rootCause(e, depth = 0) {
|
|
1375
|
+
if (depth > 5 || !e || typeof e !== "object") return e;
|
|
1376
|
+
const o = e;
|
|
1377
|
+
if (Array.isArray(o.errors) && o.errors.length > 0) {
|
|
1378
|
+
const coded = o.errors.find((x) => codeOf(x) !== null);
|
|
1379
|
+
return rootCause(coded ?? o.errors[0], depth + 1);
|
|
1380
|
+
}
|
|
1381
|
+
if (o.cause !== void 0 && o.cause !== null) return rootCause(o.cause, depth + 1);
|
|
1382
|
+
return e;
|
|
1383
|
+
}
|
|
1384
|
+
var BY_CODE = {
|
|
1385
|
+
ENOTFOUND: { cause: "dns", detail: "the provider's hostname did not resolve \u2014 DNS, or a typo'd base URL", transient: false, kind: "network" },
|
|
1386
|
+
EAI_AGAIN: { cause: "dns", detail: "DNS lookup failed temporarily \u2014 resolver or network is flapping", transient: true, kind: "network" },
|
|
1387
|
+
ECONNREFUSED: { cause: "refused", detail: "the connection was refused \u2014 nothing is listening, or a proxy blocked it", transient: false, kind: "network" },
|
|
1388
|
+
ECONNRESET: { cause: "reset", detail: "the peer closed the connection mid-request \u2014 flaky path, or an upstream error behind a proxy", transient: true, kind: "network" },
|
|
1389
|
+
EPIPE: { cause: "reset", detail: "the connection closed while we were still writing", transient: true, kind: "network" },
|
|
1390
|
+
ETIMEDOUT: { cause: "connect_timeout", detail: "the connection timed out before it was established", transient: true, kind: "timeout" },
|
|
1391
|
+
EHOSTUNREACH: { cause: "unreachable", detail: "no route to the provider \u2014 VPN, or offline", transient: true, kind: "network" },
|
|
1392
|
+
ENETUNREACH: { cause: "unreachable", detail: "the network is unreachable \u2014 offline, or a routing change", transient: true, kind: "network" },
|
|
1393
|
+
ENETDOWN: { cause: "unreachable", detail: "the local network is down", transient: true, kind: "network" },
|
|
1394
|
+
EPROTO: { cause: "tls", detail: "the TLS handshake failed \u2014 an intercepting proxy, or a protocol mismatch", transient: false, kind: "network" },
|
|
1395
|
+
ERR_TLS_CERT_ALTNAME_INVALID: { cause: "tls", detail: "the certificate did not match the hostname \u2014 traffic is being intercepted", transient: false, kind: "network" },
|
|
1396
|
+
CERT_HAS_EXPIRED: { cause: "tls", detail: "the server certificate has expired, or this machine's clock is wrong", transient: false, kind: "network" },
|
|
1397
|
+
UNABLE_TO_VERIFY_LEAF_SIGNATURE: { cause: "tls", detail: "the certificate chain could not be verified \u2014 a corporate proxy's root is probably not trusted here", transient: false, kind: "network" },
|
|
1398
|
+
UND_ERR_CONNECT_TIMEOUT: { cause: "connect_timeout", detail: "could not open a connection within the timeout \u2014 firewall, or the host is down", transient: true, kind: "timeout" },
|
|
1399
|
+
UND_ERR_HEADERS_TIMEOUT: { cause: "read_timeout", detail: "connected, but the provider sent no response headers in time \u2014 it is overloaded or thinking too long", transient: true, kind: "timeout" },
|
|
1400
|
+
UND_ERR_BODY_TIMEOUT: { cause: "read_timeout", detail: "the response body stalled mid-stream", transient: true, kind: "timeout" },
|
|
1401
|
+
UND_ERR_SOCKET: { cause: "reset", detail: "the socket closed unexpectedly", transient: true, kind: "network" },
|
|
1402
|
+
UND_ERR_ABORTED: { cause: "aborted", detail: "the request was cancelled", transient: false, kind: "network" },
|
|
1403
|
+
ABORT_ERR: { cause: "aborted", detail: "the request was cancelled", transient: false, kind: "network" }
|
|
1404
|
+
};
|
|
1405
|
+
function diagnoseNetworkError(e) {
|
|
1406
|
+
const root = rootCause(e);
|
|
1407
|
+
const code = codeOf(root) ?? codeOf(e);
|
|
1408
|
+
if (code && BY_CODE[code]) return { ...BY_CODE[code], code };
|
|
1409
|
+
const name = root && typeof root === "object" ? root.name : void 0;
|
|
1410
|
+
if (name === "AbortError" || name === "TimeoutError") {
|
|
1411
|
+
return {
|
|
1412
|
+
cause: name === "TimeoutError" ? "read_timeout" : "aborted",
|
|
1413
|
+
code: code ?? String(name),
|
|
1414
|
+
detail: name === "TimeoutError" ? "the request exceeded its timeout" : "the request was cancelled",
|
|
1415
|
+
transient: name === "TimeoutError",
|
|
1416
|
+
kind: name === "TimeoutError" ? "timeout" : "network"
|
|
1417
|
+
};
|
|
1418
|
+
}
|
|
1419
|
+
return {
|
|
1420
|
+
cause: "unknown",
|
|
1421
|
+
code,
|
|
1422
|
+
detail: code ? `the connection failed with ${code}` : "the connection failed and the underlying error carried no code",
|
|
1423
|
+
transient: true,
|
|
1424
|
+
kind: "network"
|
|
1425
|
+
};
|
|
1426
|
+
}
|
|
1427
|
+
function looksLikeNetworkFailure(d) {
|
|
1428
|
+
return d.code !== null || d.cause !== "unknown";
|
|
1429
|
+
}
|
|
1430
|
+
function networkErrorMessage(provider, d) {
|
|
1431
|
+
const code = d.code ? ` [${d.code}]` : "";
|
|
1432
|
+
return `${provider}: ${d.detail}${code}`;
|
|
1433
|
+
}
|
|
1434
|
+
|
|
1345
1435
|
// src/providers/retry.ts
|
|
1346
1436
|
init_esm_shims();
|
|
1347
1437
|
var override = null;
|
|
@@ -1673,7 +1763,11 @@ async function sendAnthropic(args) {
|
|
|
1673
1763
|
try {
|
|
1674
1764
|
respLike = await doFetch(url, init);
|
|
1675
1765
|
} catch (e) {
|
|
1676
|
-
|
|
1766
|
+
const d = diagnoseNetworkError(e);
|
|
1767
|
+
if (!looksLikeNetworkFailure(d)) throw e;
|
|
1768
|
+
throw new ProviderError(d.kind, networkErrorMessage("anthropic", d), {
|
|
1769
|
+
transient: d.transient
|
|
1770
|
+
});
|
|
1677
1771
|
}
|
|
1678
1772
|
const status = respLike.status;
|
|
1679
1773
|
if (status >= 200 && status < 300) {
|
|
@@ -1747,6 +1841,11 @@ function jsonSchemaToGeminiSchema(schema) {
|
|
|
1747
1841
|
}
|
|
1748
1842
|
return out;
|
|
1749
1843
|
}
|
|
1844
|
+
var GEMINI_THINKING_HEADROOM_TOKENS = 16384;
|
|
1845
|
+
function thinkingHeadroom() {
|
|
1846
|
+
const raw = Number(process.env["CROSSCHECK_GEMINI_THINKING_HEADROOM_TOKENS"]);
|
|
1847
|
+
return Number.isFinite(raw) && raw >= 0 ? Math.trunc(raw) : GEMINI_THINKING_HEADROOM_TOKENS;
|
|
1848
|
+
}
|
|
1750
1849
|
function buildGeminiRequest(opts) {
|
|
1751
1850
|
const contents = [];
|
|
1752
1851
|
let systemText = null;
|
|
@@ -1765,8 +1864,9 @@ function buildGeminiRequest(opts) {
|
|
|
1765
1864
|
const body = {
|
|
1766
1865
|
contents,
|
|
1767
1866
|
generationConfig: {
|
|
1768
|
-
|
|
1769
|
-
|
|
1867
|
+
// Answer budget + thinking headroom. No temperature / topP / topK /
|
|
1868
|
+
// thinkingBudget, on any model — see the header note.
|
|
1869
|
+
maxOutputTokens: opts.maxTokens + thinkingHeadroom()
|
|
1770
1870
|
}
|
|
1771
1871
|
};
|
|
1772
1872
|
if (systemText !== null && systemText !== "") {
|
|
@@ -1776,8 +1876,8 @@ function buildGeminiRequest(opts) {
|
|
|
1776
1876
|
body.generationConfig.responseMimeType = "application/json";
|
|
1777
1877
|
body.generationConfig.responseSchema = jsonSchemaToGeminiSchema(opts.jsonSchema);
|
|
1778
1878
|
}
|
|
1779
|
-
const url = `${GEMINI_API_URL_BASE}/${encodeURIComponent(opts.model)}:generateContent
|
|
1780
|
-
return { url, headers: {}, body };
|
|
1879
|
+
const url = `${GEMINI_API_URL_BASE}/${encodeURIComponent(opts.model)}:generateContent`;
|
|
1880
|
+
return { url, headers: { "x-goog-api-key": opts.apiKey }, body };
|
|
1781
1881
|
}
|
|
1782
1882
|
function parseGeminiResponse(opts) {
|
|
1783
1883
|
const r = opts.resp ?? {};
|
|
@@ -1807,16 +1907,19 @@ function parseGeminiResponse(opts) {
|
|
|
1807
1907
|
}
|
|
1808
1908
|
try {
|
|
1809
1909
|
const first = cands[0];
|
|
1810
|
-
const
|
|
1811
|
-
const
|
|
1910
|
+
const finishReason = typeof first["finishReason"] === "string" ? first["finishReason"] : void 0;
|
|
1911
|
+
const content = first["content"] ?? {};
|
|
1912
|
+
const parts = Array.isArray(content["parts"]) ? content["parts"] : [];
|
|
1812
1913
|
let text = "";
|
|
1813
1914
|
for (const p of parts) {
|
|
1814
1915
|
if (p && typeof p === "object") {
|
|
1815
|
-
const
|
|
1916
|
+
const part = p;
|
|
1917
|
+
if (part["thought"] === true) continue;
|
|
1918
|
+
const t = part["text"];
|
|
1816
1919
|
if (typeof t === "string") text += t;
|
|
1817
1920
|
}
|
|
1818
1921
|
}
|
|
1819
|
-
return { text, usage };
|
|
1922
|
+
return { text, usage, ...finishReason ? { finishReason } : {} };
|
|
1820
1923
|
} catch (e) {
|
|
1821
1924
|
throw new ProviderError(
|
|
1822
1925
|
"parse",
|
|
@@ -1845,7 +1948,8 @@ async function sendGemini(args) {
|
|
|
1845
1948
|
apiKey: args.apiKey,
|
|
1846
1949
|
messages: args.messages,
|
|
1847
1950
|
maxTokens: args.maxTokens,
|
|
1848
|
-
|
|
1951
|
+
// args.temperature is deliberately NOT forwarded: Gemini ignores it and
|
|
1952
|
+
// upcoming models reject it. See the header note.
|
|
1849
1953
|
...args.jsonSchema ? { jsonSchema: args.jsonSchema } : {}
|
|
1850
1954
|
});
|
|
1851
1955
|
const doFetch = args.fetchImpl ?? globalThis.fetch;
|
|
@@ -1860,7 +1964,11 @@ async function sendGemini(args) {
|
|
|
1860
1964
|
try {
|
|
1861
1965
|
respLike = await doFetch(url, init);
|
|
1862
1966
|
} catch (e) {
|
|
1863
|
-
|
|
1967
|
+
const d = diagnoseNetworkError(e);
|
|
1968
|
+
if (!looksLikeNetworkFailure(d)) throw e;
|
|
1969
|
+
throw new ProviderError(d.kind, networkErrorMessage("gemini", d), {
|
|
1970
|
+
transient: d.transient
|
|
1971
|
+
});
|
|
1864
1972
|
}
|
|
1865
1973
|
const status = respLike.status;
|
|
1866
1974
|
if (status >= 200 && status < 300) {
|
|
@@ -1870,11 +1978,18 @@ async function sendGemini(args) {
|
|
|
1870
1978
|
} catch (e) {
|
|
1871
1979
|
throw new ProviderError("parse", `gemini: response body not JSON: ${e.message}`);
|
|
1872
1980
|
}
|
|
1873
|
-
const { text, usage } = parseGeminiResponse({
|
|
1981
|
+
const { text, usage, finishReason } = parseGeminiResponse({
|
|
1874
1982
|
resp: parsed,
|
|
1875
1983
|
model: args.model,
|
|
1876
1984
|
purpose: args.purpose ?? "worker"
|
|
1877
1985
|
});
|
|
1986
|
+
if (text.trim() === "" && finishReason === "MAX_TOKENS") {
|
|
1987
|
+
throw new ProviderError(
|
|
1988
|
+
"parse",
|
|
1989
|
+
`gemini: the answer was cut off before any visible text \u2014 thinking used the whole output budget (${usage.completion_tokens} tokens). Raise CROSSCHECK_GEMINI_THINKING_HEADROOM_TOKENS or the purpose's budget.`,
|
|
1990
|
+
{ transient: false }
|
|
1991
|
+
);
|
|
1992
|
+
}
|
|
1878
1993
|
return { text, attempts: 1, usage: applyPricing2(usage, args.pricing) };
|
|
1879
1994
|
}
|
|
1880
1995
|
const bodyText = await respLike.text().catch(() => "");
|
|
@@ -2042,7 +2157,11 @@ async function sendOpenAICompatible(args) {
|
|
|
2042
2157
|
try {
|
|
2043
2158
|
respLike = await doFetch(url, init);
|
|
2044
2159
|
} catch (e) {
|
|
2045
|
-
|
|
2160
|
+
const d = diagnoseNetworkError(e);
|
|
2161
|
+
if (!looksLikeNetworkFailure(d)) throw e;
|
|
2162
|
+
throw new ProviderError(d.kind, networkErrorMessage(args.provider, d), {
|
|
2163
|
+
transient: d.transient
|
|
2164
|
+
});
|
|
2046
2165
|
}
|
|
2047
2166
|
const status = respLike.status;
|
|
2048
2167
|
if (status >= 200 && status < 300) {
|
|
@@ -2070,7 +2189,7 @@ async function sendOpenAICompatible(args) {
|
|
|
2070
2189
|
// src/providers/registry.ts
|
|
2071
2190
|
var DEFAULT_MODELS = {
|
|
2072
2191
|
anthropic: "claude-opus-5-5",
|
|
2073
|
-
openai: "gpt-
|
|
2192
|
+
openai: "gpt-6-sol",
|
|
2074
2193
|
xai: "grok-4-latest",
|
|
2075
2194
|
mistral: "mistral-large-latest",
|
|
2076
2195
|
groq: "llama-3.3-70b-versatile",
|
|
@@ -2230,50 +2349,6 @@ import {
|
|
|
2230
2349
|
ListToolsRequestSchema
|
|
2231
2350
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
2232
2351
|
|
|
2233
|
-
// src/bridge/index.ts
|
|
2234
|
-
init_esm_shims();
|
|
2235
|
-
|
|
2236
|
-
// src/bridge/proxy-tools.ts
|
|
2237
|
-
init_esm_shims();
|
|
2238
|
-
function buildPythonProxies(bridge) {
|
|
2239
|
-
const proxies = /* @__PURE__ */ new Map();
|
|
2240
|
-
for (const name of bridge.toolNames) {
|
|
2241
|
-
proxies.set(name, makeProxy(bridge, name));
|
|
2242
|
-
}
|
|
2243
|
-
return proxies;
|
|
2244
|
-
}
|
|
2245
|
-
function makeProxy(bridge, name) {
|
|
2246
|
-
return {
|
|
2247
|
-
name,
|
|
2248
|
-
description: `(forwarded to Python crosscheck-agent) ${name}`,
|
|
2249
|
-
// We don't carry the per-tool input schema across the bridge in
|
|
2250
|
-
// route-all mode — the TS server is a transparent forwarder, so
|
|
2251
|
-
// arg validation happens on the Python side. inputSchema is left
|
|
2252
|
-
// permissive; the Python validator throws structured errors that
|
|
2253
|
-
// tunnel back through `callTool()`.
|
|
2254
|
-
inputSchema: {
|
|
2255
|
-
type: "object",
|
|
2256
|
-
additionalProperties: true,
|
|
2257
|
-
description: `Forwarded to Python \u2014 see Python tool '${name}' for full schema.`
|
|
2258
|
-
},
|
|
2259
|
-
handler: async (args) => {
|
|
2260
|
-
const r = await bridge.callTool(name, args);
|
|
2261
|
-
if (!r.content.length) {
|
|
2262
|
-
return {};
|
|
2263
|
-
}
|
|
2264
|
-
const first = r.content[0];
|
|
2265
|
-
if (first.type === "text" && first.text) {
|
|
2266
|
-
try {
|
|
2267
|
-
return JSON.parse(first.text);
|
|
2268
|
-
} catch {
|
|
2269
|
-
return { text: first.text };
|
|
2270
|
-
}
|
|
2271
|
-
}
|
|
2272
|
-
return { content: r.content };
|
|
2273
|
-
}
|
|
2274
|
-
};
|
|
2275
|
-
}
|
|
2276
|
-
|
|
2277
2352
|
// src/instructions.ts
|
|
2278
2353
|
init_esm_shims();
|
|
2279
2354
|
var ROUTABLE_TOOLS = [
|
|
@@ -2337,13 +2412,13 @@ Examples:
|
|
|
2337
2412
|
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.
|
|
2338
2413
|
|
|
2339
2414
|
Reasoning upgrade (Fable 5):
|
|
2340
|
-
- 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
|
|
2415
|
+
- 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.
|
|
2341
2416
|
- 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.
|
|
2342
2417
|
- 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.
|
|
2343
2418
|
|
|
2344
2419
|
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):
|
|
2345
2420
|
- 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 })\`.
|
|
2346
|
-
- 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 +
|
|
2421
|
+
- 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".
|
|
2347
2422
|
- A result with a "super_mode" block confirms it ran; show the panel it used.
|
|
2348
2423
|
- \`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.
|
|
2349
2424
|
|
|
@@ -2360,7 +2435,7 @@ import { z } from "zod";
|
|
|
2360
2435
|
// src/server-meta.ts
|
|
2361
2436
|
init_esm_shims();
|
|
2362
2437
|
var SERVER_NAME = "crosscheck-agent";
|
|
2363
|
-
var SERVER_VERSION = true ? "0.2.
|
|
2438
|
+
var SERVER_VERSION = true ? "0.2.28" : "0.0.0-dev";
|
|
2364
2439
|
|
|
2365
2440
|
// src/tools/audit.ts
|
|
2366
2441
|
init_esm_shims();
|
|
@@ -2427,27 +2502,27 @@ function extractJson(text) {
|
|
|
2427
2502
|
|
|
2428
2503
|
// src/core/json-schema.ts
|
|
2429
2504
|
init_esm_shims();
|
|
2430
|
-
function validateSchema(value, schema,
|
|
2505
|
+
function validateSchema(value, schema, path17 = "") {
|
|
2431
2506
|
const errs = [];
|
|
2432
2507
|
if ("anyOf" in schema) {
|
|
2433
2508
|
const subs = schema["anyOf"].map(
|
|
2434
|
-
(s) => validateSchema(value, s,
|
|
2509
|
+
(s) => validateSchema(value, s, path17)
|
|
2435
2510
|
);
|
|
2436
2511
|
if (!subs.some((e) => e.length === 0)) {
|
|
2437
|
-
errs.push(`${
|
|
2512
|
+
errs.push(`${path17 || "<root>"}: did not match anyOf`);
|
|
2438
2513
|
}
|
|
2439
2514
|
return errs;
|
|
2440
2515
|
}
|
|
2441
2516
|
if ("oneOf" in schema) {
|
|
2442
|
-
const passed = schema["oneOf"].filter((s) => validateSchema(value, s,
|
|
2517
|
+
const passed = schema["oneOf"].filter((s) => validateSchema(value, s, path17).length === 0).length;
|
|
2443
2518
|
if (passed !== 1) {
|
|
2444
|
-
errs.push(`${
|
|
2519
|
+
errs.push(`${path17 || "<root>"}: matched ${passed} of oneOf, expected 1`);
|
|
2445
2520
|
}
|
|
2446
2521
|
return errs;
|
|
2447
2522
|
}
|
|
2448
2523
|
if ("const" in schema && !deepEqual(value, schema["const"])) {
|
|
2449
2524
|
errs.push(
|
|
2450
|
-
`${
|
|
2525
|
+
`${path17 || "<root>"}: expected const ${pyRepr(schema["const"])}, got ${pyRepr(value)}`
|
|
2451
2526
|
);
|
|
2452
2527
|
return errs;
|
|
2453
2528
|
}
|
|
@@ -2457,7 +2532,7 @@ function validateSchema(value, schema, path16 = "") {
|
|
|
2457
2532
|
const ok = types.some((tt) => matchesType(value, String(tt)));
|
|
2458
2533
|
if (!ok) {
|
|
2459
2534
|
errs.push(
|
|
2460
|
-
`${
|
|
2535
|
+
`${path17 || "<root>"}: expected type ${pyReprType(t)}, got ${pyTypeName(value)}`
|
|
2461
2536
|
);
|
|
2462
2537
|
return errs;
|
|
2463
2538
|
}
|
|
@@ -2466,29 +2541,29 @@ function validateSchema(value, schema, path16 = "") {
|
|
|
2466
2541
|
if ("enum" in schema) {
|
|
2467
2542
|
const en = schema["enum"];
|
|
2468
2543
|
if (!en.some((x) => deepEqual(x, value))) {
|
|
2469
|
-
errs.push(`${
|
|
2544
|
+
errs.push(`${path17 || "<root>"}: value ${pyRepr(value)} not in enum`);
|
|
2470
2545
|
}
|
|
2471
2546
|
}
|
|
2472
2547
|
if ("minLength" in schema && value.length < schema["minLength"]) {
|
|
2473
|
-
errs.push(`${
|
|
2548
|
+
errs.push(`${path17 || "<root>"}: shorter than minLength ${schema["minLength"]}`);
|
|
2474
2549
|
}
|
|
2475
2550
|
}
|
|
2476
2551
|
if (typeof value === "number" && !Number.isNaN(value)) {
|
|
2477
2552
|
if ("minimum" in schema && value < schema["minimum"]) {
|
|
2478
|
-
errs.push(`${
|
|
2553
|
+
errs.push(`${path17 || "<root>"}: ${value} < minimum ${schema["minimum"]}`);
|
|
2479
2554
|
}
|
|
2480
2555
|
if ("maximum" in schema && value > schema["maximum"]) {
|
|
2481
|
-
errs.push(`${
|
|
2556
|
+
errs.push(`${path17 || "<root>"}: ${value} > maximum ${schema["maximum"]}`);
|
|
2482
2557
|
}
|
|
2483
2558
|
}
|
|
2484
2559
|
if (Array.isArray(value)) {
|
|
2485
2560
|
if ("minItems" in schema && value.length < schema["minItems"]) {
|
|
2486
|
-
errs.push(`${
|
|
2561
|
+
errs.push(`${path17 || "<root>"}: fewer items than minItems ${schema["minItems"]}`);
|
|
2487
2562
|
}
|
|
2488
2563
|
const itemSchema = schema["items"];
|
|
2489
2564
|
if (isObj(itemSchema)) {
|
|
2490
2565
|
for (let i = 0; i < value.length; i++) {
|
|
2491
|
-
errs.push(...validateSchema(value[i], itemSchema, `${
|
|
2566
|
+
errs.push(...validateSchema(value[i], itemSchema, `${path17}[${i}]`));
|
|
2492
2567
|
}
|
|
2493
2568
|
}
|
|
2494
2569
|
}
|
|
@@ -2497,19 +2572,19 @@ function validateSchema(value, schema, path16 = "") {
|
|
|
2497
2572
|
const required = schema["required"] ?? [];
|
|
2498
2573
|
for (const r of required) {
|
|
2499
2574
|
if (!(r in value)) {
|
|
2500
|
-
errs.push(`${
|
|
2575
|
+
errs.push(`${path17 || "<root>"}: missing required key ${pyRepr(r)}`);
|
|
2501
2576
|
}
|
|
2502
2577
|
}
|
|
2503
2578
|
if (schema["additionalProperties"] === false) {
|
|
2504
2579
|
for (const k of Object.keys(value)) {
|
|
2505
2580
|
if (!(k in props)) {
|
|
2506
|
-
errs.push(`${
|
|
2581
|
+
errs.push(`${path17 || "<root>"}: unknown key ${pyRepr(k)}`);
|
|
2507
2582
|
}
|
|
2508
2583
|
}
|
|
2509
2584
|
}
|
|
2510
2585
|
for (const [k, v] of Object.entries(value)) {
|
|
2511
2586
|
const ps = props[k];
|
|
2512
|
-
if (ps) errs.push(...validateSchema(v, ps,
|
|
2587
|
+
if (ps) errs.push(...validateSchema(v, ps, path17 ? `${path17}.${k}` : k));
|
|
2513
2588
|
}
|
|
2514
2589
|
}
|
|
2515
2590
|
return errs;
|
|
@@ -2591,6 +2666,34 @@ function pyReprType(t) {
|
|
|
2591
2666
|
|
|
2592
2667
|
// src/core/usage.ts
|
|
2593
2668
|
init_esm_shims();
|
|
2669
|
+
|
|
2670
|
+
// src/core/session.ts
|
|
2671
|
+
init_esm_shims();
|
|
2672
|
+
import { randomUUID } from "crypto";
|
|
2673
|
+
var processSessionId = null;
|
|
2674
|
+
var startedAt = null;
|
|
2675
|
+
function engineSessionId() {
|
|
2676
|
+
if (processSessionId === null) {
|
|
2677
|
+
processSessionId = randomUUID();
|
|
2678
|
+
startedAt = Date.now();
|
|
2679
|
+
}
|
|
2680
|
+
return processSessionId;
|
|
2681
|
+
}
|
|
2682
|
+
function resolveSessionId(callerSupplied) {
|
|
2683
|
+
const trimmed = typeof callerSupplied === "string" ? callerSupplied.trim() : "";
|
|
2684
|
+
return trimmed.length > 0 ? trimmed : engineSessionId();
|
|
2685
|
+
}
|
|
2686
|
+
function localSessionRecordingEnabled(env = globalThis.process?.env ?? {}) {
|
|
2687
|
+
const v = (env["CROSSCHECK_RECORD_SESSIONS"] ?? "").trim().toLowerCase();
|
|
2688
|
+
return !["0", "false", "off", "no"].includes(v);
|
|
2689
|
+
}
|
|
2690
|
+
function recordingSessionId(callerSupplied) {
|
|
2691
|
+
if (localSessionRecordingEnabled()) return resolveSessionId(callerSupplied);
|
|
2692
|
+
const trimmed = typeof callerSupplied === "string" ? callerSupplied.trim() : "";
|
|
2693
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
2694
|
+
}
|
|
2695
|
+
|
|
2696
|
+
// src/core/usage.ts
|
|
2594
2697
|
function emptyUsage(provider, model, purpose = "worker") {
|
|
2595
2698
|
return {
|
|
2596
2699
|
provider,
|
|
@@ -2695,11 +2798,11 @@ function withCommas(n) {
|
|
|
2695
2798
|
function renderRunSummary(opts) {
|
|
2696
2799
|
const endedAt = opts.endedAtS ?? Math.trunc(Date.now() / 1e3);
|
|
2697
2800
|
let scope = "call";
|
|
2698
|
-
let
|
|
2801
|
+
let startedAt2 = null;
|
|
2699
2802
|
let rows = [];
|
|
2700
2803
|
if (opts.sessionScope && opts.sessionScope.rows.length > 0) {
|
|
2701
2804
|
scope = "session";
|
|
2702
|
-
|
|
2805
|
+
startedAt2 = opts.sessionScope.startedAt;
|
|
2703
2806
|
rows = opts.sessionScope.rows.map((r) => ({ ...r }));
|
|
2704
2807
|
} else {
|
|
2705
2808
|
const byPurpose = /* @__PURE__ */ new Map();
|
|
@@ -2730,6 +2833,7 @@ function renderRunSummary(opts) {
|
|
|
2730
2833
|
row.cpu_ms += a.cpu_ms ?? 0;
|
|
2731
2834
|
if (a.cache_hit) row.cache_hits += 1;
|
|
2732
2835
|
if (a.error) row.errors += 1;
|
|
2836
|
+
if (a.usage?.estimated) row.estimated = true;
|
|
2733
2837
|
}
|
|
2734
2838
|
rows = Array.from(byPurpose.values());
|
|
2735
2839
|
}
|
|
@@ -2742,16 +2846,18 @@ function renderRunSummary(opts) {
|
|
|
2742
2846
|
wall_ms: rows.reduce((s, r) => s + r.wall_ms, 0),
|
|
2743
2847
|
cpu_ms: rows.reduce((s, r) => s + r.cpu_ms, 0),
|
|
2744
2848
|
cache_hits: rows.reduce((s, r) => s + r.cache_hits, 0),
|
|
2745
|
-
errors: rows.reduce((s, r) => s + r.errors, 0)
|
|
2849
|
+
errors: rows.reduce((s, r) => s + r.errors, 0),
|
|
2850
|
+
...rows.some((r) => r.estimated) ? { estimated: true } : {}
|
|
2746
2851
|
};
|
|
2747
2852
|
const titleLeft = scope === "session" ? `session: ${opts.sessionId ?? ""}` : `call: ${opts.toolName}`;
|
|
2748
|
-
const
|
|
2853
|
+
const costText = totals.estimated ? `$${totals.cost_usd.toFixed(4)}+ (some calls unpriced)` : `$${totals.cost_usd.toFixed(4)}`;
|
|
2854
|
+
const header = `${titleLeft} (${totals.calls} calls, ${withCommas(totals.total_tokens)} tokens, ${costText}, ${(totals.wall_ms / 1e3).toFixed(1)}s wall, ${(totals.cpu_ms / 1e3).toFixed(3)}s cpu)`;
|
|
2749
2855
|
const bodyLines = [];
|
|
2750
2856
|
for (let i = 0; i < rows.length; i++) {
|
|
2751
2857
|
const r = rows[i];
|
|
2752
2858
|
const glyph = i === rows.length - 1 ? "`-" : "|-";
|
|
2753
2859
|
bodyLines.push(
|
|
2754
|
-
`${glyph} purpose: ${r.purpose} (calls=${r.calls} tokens=${withCommas(r.total_tokens)} cost=$${r.cost_usd.toFixed(4)} wall=${(r.wall_ms / 1e3).toFixed(1)}s cpu=${(r.cpu_ms / 1e3).toFixed(3)}s)`
|
|
2860
|
+
`${glyph} purpose: ${r.purpose} (calls=${r.calls} tokens=${withCommas(r.total_tokens)} cost=$${r.cost_usd.toFixed(4)}${r.estimated ? "+" : ""} wall=${(r.wall_ms / 1e3).toFixed(1)}s cpu=${(r.cpu_ms / 1e3).toFixed(3)}s)`
|
|
2755
2861
|
);
|
|
2756
2862
|
}
|
|
2757
2863
|
const callByModel = rollupSpendByModel(
|
|
@@ -2799,7 +2905,7 @@ function renderRunSummary(opts) {
|
|
|
2799
2905
|
tool: opts.toolName,
|
|
2800
2906
|
scope,
|
|
2801
2907
|
currency: "USD",
|
|
2802
|
-
started_at:
|
|
2908
|
+
started_at: startedAt2,
|
|
2803
2909
|
ended_at: endedAt,
|
|
2804
2910
|
rows,
|
|
2805
2911
|
totals,
|
|
@@ -2924,14 +3030,15 @@ async function attachUsageBlock(result, answers, opts) {
|
|
|
2924
3030
|
delete result["_suppress_run_summary"];
|
|
2925
3031
|
}
|
|
2926
3032
|
async function appendUsageLog(storage, sessionId, toolName, answers, nowS) {
|
|
2927
|
-
|
|
3033
|
+
const sid = recordingSessionId(sessionId);
|
|
3034
|
+
if (!sid || answers.length === 0) return;
|
|
2928
3035
|
const now = nowS ?? Math.trunc(Date.now() / 1e3);
|
|
2929
3036
|
const rows = [];
|
|
2930
3037
|
for (const a of answers) {
|
|
2931
3038
|
const u = a.usage;
|
|
2932
3039
|
if (!u || typeof u.provider !== "string" || u.provider === "") continue;
|
|
2933
3040
|
rows.push({
|
|
2934
|
-
session_id:
|
|
3041
|
+
session_id: sid,
|
|
2935
3042
|
ts: now,
|
|
2936
3043
|
tool: toolName,
|
|
2937
3044
|
purpose: u.purpose ?? "worker",
|
|
@@ -2954,13 +3061,14 @@ async function appendUsageLog(storage, sessionId, toolName, answers, nowS) {
|
|
|
2954
3061
|
}
|
|
2955
3062
|
}
|
|
2956
3063
|
async function recordSessionCall(storage, sessionId, answers, wallMs, cpuMs, nowS) {
|
|
2957
|
-
|
|
3064
|
+
const sid = recordingSessionId(sessionId);
|
|
3065
|
+
if (!sid) return;
|
|
2958
3066
|
const now = nowS ?? Math.trunc(Date.now() / 1e3);
|
|
2959
3067
|
try {
|
|
2960
|
-
let existing = await storage.getSession(
|
|
3068
|
+
let existing = await storage.getSession(sid);
|
|
2961
3069
|
if (!existing) {
|
|
2962
3070
|
await storage.upsertSession({
|
|
2963
|
-
session_id:
|
|
3071
|
+
session_id: sid,
|
|
2964
3072
|
started_at: now,
|
|
2965
3073
|
last_at: now,
|
|
2966
3074
|
calls: 0,
|
|
@@ -2973,7 +3081,7 @@ async function recordSessionCall(storage, sessionId, answers, wallMs, cpuMs, now
|
|
|
2973
3081
|
total_cost_usd: 0,
|
|
2974
3082
|
total_cpu_ms: 0
|
|
2975
3083
|
});
|
|
2976
|
-
existing = await storage.getSession(
|
|
3084
|
+
existing = await storage.getSession(sid);
|
|
2977
3085
|
}
|
|
2978
3086
|
if (!existing) return;
|
|
2979
3087
|
let promptDelta = 0;
|
|
@@ -2993,7 +3101,7 @@ async function recordSessionCall(storage, sessionId, answers, wallMs, cpuMs, now
|
|
|
2993
3101
|
}
|
|
2994
3102
|
if (a.cache_hit) cacheHitDelta += 1;
|
|
2995
3103
|
}
|
|
2996
|
-
await storage.accumulateSessionTotals(
|
|
3104
|
+
await storage.accumulateSessionTotals(sid, {
|
|
2997
3105
|
calls: answers.length,
|
|
2998
3106
|
wall_ms: wallMs,
|
|
2999
3107
|
cache_hits: cacheHitDelta,
|
|
@@ -3963,13 +4071,25 @@ import { performance as performance2 } from "perf_hooks";
|
|
|
3963
4071
|
|
|
3964
4072
|
// src/core/co-reason.ts
|
|
3965
4073
|
init_esm_shims();
|
|
3966
|
-
var CO_REASON_MODEL = "gpt-
|
|
4074
|
+
var CO_REASON_MODEL = "gpt-6-sol";
|
|
4075
|
+
var CO_REASON_ALTERNATE = "gpt-6-astra";
|
|
4076
|
+
var LABELS = {
|
|
4077
|
+
"gpt-6-sol": "GPT-6 Sol",
|
|
4078
|
+
"gpt-6-astra": "GPT-6 Astra",
|
|
4079
|
+
"gpt-5.6-sol": "GPT-5.6 Sol"
|
|
4080
|
+
};
|
|
4081
|
+
function coReasonLabel(model) {
|
|
4082
|
+
return LABELS[model] ?? model;
|
|
4083
|
+
}
|
|
4084
|
+
var CO_REASON_LABEL = coReasonLabel(CO_REASON_MODEL);
|
|
3967
4085
|
var CO_REASON_PROVIDER = "openai";
|
|
3968
|
-
|
|
3969
|
-
function pickCoReasoner(providers, upgradeRequested) {
|
|
4086
|
+
function pickCoReasoner(providers, upgradeRequested, openAiSeatModel) {
|
|
3970
4087
|
if (!upgradeRequested) return null;
|
|
3971
4088
|
const base = providers[CO_REASON_PROVIDER];
|
|
3972
|
-
|
|
4089
|
+
if (!base) return null;
|
|
4090
|
+
const seat = openAiSeatModel ?? base.model;
|
|
4091
|
+
const model = seat === CO_REASON_MODEL ? CO_REASON_ALTERNATE : CO_REASON_MODEL;
|
|
4092
|
+
return retargetProvider(base, model);
|
|
3973
4093
|
}
|
|
3974
4094
|
async function coReasonThenInject(opts) {
|
|
3975
4095
|
const { provider, messages, maxTokens } = opts;
|
|
@@ -4200,7 +4320,7 @@ function buildSuggestedUpgrade(toolName, assessment) {
|
|
|
4200
4320
|
model: UPGRADE_MODEL,
|
|
4201
4321
|
label: UPGRADE_LABEL,
|
|
4202
4322
|
reason: assessment.reason,
|
|
4203
|
-
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
|
|
4323
|
+
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.`
|
|
4204
4324
|
};
|
|
4205
4325
|
}
|
|
4206
4326
|
|
|
@@ -4503,8 +4623,9 @@ ${rubricText}`;
|
|
|
4503
4623
|
const upgradeRequested = isUpgradeRequested(args);
|
|
4504
4624
|
const upgraded = upgradeRequested && opts.providers["anthropic"] !== void 0;
|
|
4505
4625
|
const auditorForCall = upgraded ? retargetProvider(opts.providers["anthropic"], UPGRADE_MODEL) : auditor;
|
|
4626
|
+
const coProvider = pickCoReasoner(opts.providers, upgradeRequested);
|
|
4506
4627
|
const coReason = await coReasonThenInject({
|
|
4507
|
-
provider:
|
|
4628
|
+
provider: coProvider,
|
|
4508
4629
|
messages: msgs,
|
|
4509
4630
|
maxTokens: 2048,
|
|
4510
4631
|
purpose: "audit-coreason"
|
|
@@ -4588,7 +4709,7 @@ ${rubricText}`;
|
|
|
4588
4709
|
model: UPGRADE_MODEL,
|
|
4589
4710
|
label: UPGRADE_LABEL,
|
|
4590
4711
|
seat: "auditor",
|
|
4591
|
-
...coReasoned ? { co_reasoner: { model:
|
|
4712
|
+
...coReasoned ? { co_reasoner: { model: coProvider.model, label: coReasonLabel(coProvider.model) } } : {}
|
|
4592
4713
|
};
|
|
4593
4714
|
} else if (upgradeRequested) {
|
|
4594
4715
|
result["reasoning_upgrade"] = {
|
|
@@ -5327,8 +5448,12 @@ var SUPER_MODELS = {
|
|
|
5327
5448
|
// Fable 5.1 verified present on the account; 5 as the fallback for accounts
|
|
5328
5449
|
// that haven't been granted 5.1 yet.
|
|
5329
5450
|
anthropic: ["claude-fable-5-1", UPGRADE_MODEL],
|
|
5330
|
-
// Astra
|
|
5331
|
-
|
|
5451
|
+
// Astra is live (verified against the account's model list 2026-09-23).
|
|
5452
|
+
// The fallback is named explicitly rather than reusing CO_REASON_MODEL:
|
|
5453
|
+
// that constant means "OpenAI's top reasoning model" for the max-reasoning
|
|
5454
|
+
// co-reasoner, which is a different question from "what should super fall
|
|
5455
|
+
// back to". Sharing the symbol silently coupled two unrelated decisions.
|
|
5456
|
+
openai: ["gpt-6-astra", "gpt-6-sol"],
|
|
5332
5457
|
// Explicitly left as-is per product decision. Note grok-4-latest is not in
|
|
5333
5458
|
// xAI's published model list, but it resolves in practice — real panel calls
|
|
5334
5459
|
// on it succeeded as recently as 2026-08-30 — so it is an unlisted alias
|
|
@@ -5945,10 +6070,6 @@ If you need supporting evidence, you may emit ONE \`<tool_call>...</tool_call>\`
|
|
|
5945
6070
|
}
|
|
5946
6071
|
|
|
5947
6072
|
// src/tools/confer.ts
|
|
5948
|
-
var DEFERRED_OPTS = [
|
|
5949
|
-
// empty — every confer opt runs natively except worker_tools, which
|
|
5950
|
-
// is gated below (non-empty list → defer).
|
|
5951
|
-
];
|
|
5952
6073
|
async function runConfer(args, opts) {
|
|
5953
6074
|
const callStartedWall = performance3.now();
|
|
5954
6075
|
const callStartedCpu = process.cpuUsage();
|
|
@@ -5964,16 +6085,11 @@ async function runConfer(args, opts) {
|
|
|
5964
6085
|
rejectedWorkerTools.push(t);
|
|
5965
6086
|
}
|
|
5966
6087
|
}
|
|
5967
|
-
|
|
5968
|
-
const needsBridge = DEFERRED_OPTS.some((k) => Boolean(args[k])) || workerToolsNeedsBridge;
|
|
5969
|
-
if (needsBridge) {
|
|
5970
|
-
if (opts.bridge && opts.bridge.toolNames.has("confer")) {
|
|
5971
|
-
return await deferConfer(args, opts.bridge);
|
|
5972
|
-
}
|
|
6088
|
+
if (acceptedWorkerTools.length > 0 && !opts.innerCallers) {
|
|
5973
6089
|
return errorEnvelope2(
|
|
5974
6090
|
"CONFER_OPT_NOT_NATIVE",
|
|
5975
6091
|
"worker_tools requested but innerCallers are not wired",
|
|
5976
|
-
"Native confer covers untrusted_input + early_stop + extract_claims + inject_session_memory + auto_panel. worker_tools needs innerCallers wired by the host
|
|
6092
|
+
"Native confer covers untrusted_input + early_stop + extract_claims + inject_session_memory + auto_panel. worker_tools needs innerCallers wired by the host."
|
|
5977
6093
|
);
|
|
5978
6094
|
}
|
|
5979
6095
|
const question = typeof args["question"] === "string" ? args["question"] : String(args["question"] ?? "");
|
|
@@ -6324,21 +6440,6 @@ function unknownProviderError(unknownNames, available) {
|
|
|
6324
6440
|
available_now: Object.keys(available).sort()
|
|
6325
6441
|
};
|
|
6326
6442
|
}
|
|
6327
|
-
async function deferConfer(args, bridge) {
|
|
6328
|
-
const r = await bridge.callTool("confer", args);
|
|
6329
|
-
const text = r.content[0]?.text;
|
|
6330
|
-
if (typeof text === "string") {
|
|
6331
|
-
try {
|
|
6332
|
-
return JSON.parse(text);
|
|
6333
|
-
} catch {
|
|
6334
|
-
}
|
|
6335
|
-
}
|
|
6336
|
-
return errorEnvelope2(
|
|
6337
|
-
"CONFER_BRIDGE_BAD_ENVELOPE",
|
|
6338
|
-
"bridge returned an unparseable envelope for confer",
|
|
6339
|
-
"Check that the Python child is healthy."
|
|
6340
|
-
);
|
|
6341
|
-
}
|
|
6342
6443
|
function errorEnvelope2(code, message, hint) {
|
|
6343
6444
|
return {
|
|
6344
6445
|
tool: "confer",
|
|
@@ -6714,7 +6815,7 @@ function errorEnvelope3(code, message, hint) {
|
|
|
6714
6815
|
transient: false
|
|
6715
6816
|
};
|
|
6716
6817
|
}
|
|
6717
|
-
async function runVerify(args,
|
|
6818
|
+
async function runVerify(args, fetchConfig) {
|
|
6718
6819
|
const checks = args["checks"];
|
|
6719
6820
|
if (!Array.isArray(checks) || checks.length === 0) {
|
|
6720
6821
|
return {
|
|
@@ -6726,7 +6827,6 @@ async function runVerify(args, bridge, fetchConfig) {
|
|
|
6726
6827
|
)
|
|
6727
6828
|
};
|
|
6728
6829
|
}
|
|
6729
|
-
void bridge;
|
|
6730
6830
|
const allowShell = Boolean(args["allow_shell"] ?? false);
|
|
6731
6831
|
const wallStart = performance4.now();
|
|
6732
6832
|
const cpuStart = process.cpuUsage();
|
|
@@ -7028,7 +7128,6 @@ async function runBench(args, opts) {
|
|
|
7028
7128
|
const innerOpts = {
|
|
7029
7129
|
providers: opts.providers,
|
|
7030
7130
|
allowlist: opts.allowlist ?? null,
|
|
7031
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
7032
7131
|
...opts.moderator ? { moderator: opts.moderator } : {}
|
|
7033
7132
|
};
|
|
7034
7133
|
let inner;
|
|
@@ -7679,11 +7778,11 @@ function getNodeCache(cfg2, repoRoot, key, nowMs) {
|
|
|
7679
7778
|
return null;
|
|
7680
7779
|
}
|
|
7681
7780
|
}
|
|
7682
|
-
function atomicWriteJson(
|
|
7683
|
-
mkdirSync4(dirname2(
|
|
7684
|
-
const tmp = `${
|
|
7781
|
+
function atomicWriteJson(path17, payload) {
|
|
7782
|
+
mkdirSync4(dirname2(path17), { recursive: true });
|
|
7783
|
+
const tmp = `${path17}.${process.pid}.${Date.now()}.tmp`;
|
|
7685
7784
|
writeFileSync3(tmp, JSON.stringify(payload), "utf8");
|
|
7686
|
-
renameSync(tmp,
|
|
7785
|
+
renameSync(tmp, path17);
|
|
7687
7786
|
}
|
|
7688
7787
|
function putNodeCache(cfg2, repoRoot, key, value) {
|
|
7689
7788
|
if (!cfg2 || cfg2.enabled === false) return;
|
|
@@ -7741,7 +7840,6 @@ var EST_TOKENS = {
|
|
|
7741
7840
|
med: [1500, 800],
|
|
7742
7841
|
high: [2500, 1500]
|
|
7743
7842
|
};
|
|
7744
|
-
var DEFERRED_OPTS2 = [];
|
|
7745
7843
|
var REACTIVE_SIGNAL_RE = /<signals>\s*(\{[\s\S]*?\})\s*<\/signals>/g;
|
|
7746
7844
|
function parseReactiveSignals(output) {
|
|
7747
7845
|
if (typeof output !== "string" || !output.includes("<signals>")) return [];
|
|
@@ -7781,17 +7879,6 @@ async function runOrchestrate(args, opts) {
|
|
|
7781
7879
|
);
|
|
7782
7880
|
if (breakerEnv) return breakerEnv;
|
|
7783
7881
|
}
|
|
7784
|
-
const needsBridge = DEFERRED_OPTS2.some((k) => Boolean(args[k]));
|
|
7785
|
-
if (needsBridge) {
|
|
7786
|
-
if (opts.bridge && opts.bridge.toolNames.has("orchestrate")) {
|
|
7787
|
-
return await deferOrchestrate(args, opts.bridge);
|
|
7788
|
-
}
|
|
7789
|
-
return errorEnvelope5(
|
|
7790
|
-
"ORCHESTRATE_OPT_NOT_NATIVE",
|
|
7791
|
-
"this orchestrate opt-in requires the Python bridge in v1",
|
|
7792
|
-
"v1 native covers the plain DAG flow + cheap_mode. reactive (mid-flight DAG updates) still defers. Set CROSSCHECK_BRIDGE_PYTHON=1 to enable."
|
|
7793
|
-
);
|
|
7794
|
-
}
|
|
7795
7882
|
const goal = typeof args["goal"] === "string" ? args["goal"] : null;
|
|
7796
7883
|
const dagIn = isObj5(args["dag"]) ? args["dag"] : null;
|
|
7797
7884
|
if (goal === null === (dagIn === null)) {
|
|
@@ -8334,8 +8421,9 @@ ${recombineSys}` : recombineSys },
|
|
|
8334
8421
|
provider: synthProvider.name
|
|
8335
8422
|
} }
|
|
8336
8423
|
);
|
|
8424
|
+
const coProvider = pickCoReasoner(opts.providers, upgradeRequested);
|
|
8337
8425
|
const coReason = await coReasonThenInject({
|
|
8338
|
-
provider:
|
|
8426
|
+
provider: coProvider,
|
|
8339
8427
|
messages: recMsgs,
|
|
8340
8428
|
maxTokens,
|
|
8341
8429
|
purpose: "orchestrate-coreason"
|
|
@@ -8394,7 +8482,7 @@ ${recombineSys}` : recombineSys },
|
|
|
8394
8482
|
model: UPGRADE_MODEL,
|
|
8395
8483
|
label: UPGRADE_LABEL,
|
|
8396
8484
|
seat: "recombine/synthesis",
|
|
8397
|
-
...coReasoned ? { co_reasoner: { model:
|
|
8485
|
+
...coReasoned ? { co_reasoner: { model: coProvider.model, label: coReasonLabel(coProvider.model) } } : {}
|
|
8398
8486
|
};
|
|
8399
8487
|
} else if (upgradeRequested) {
|
|
8400
8488
|
result["reasoning_upgrade"] = {
|
|
@@ -8732,21 +8820,6 @@ function resolveProviders3(names, available, allowlist) {
|
|
|
8732
8820
|
}
|
|
8733
8821
|
return out;
|
|
8734
8822
|
}
|
|
8735
|
-
async function deferOrchestrate(args, bridge) {
|
|
8736
|
-
const r = await bridge.callTool("orchestrate", args);
|
|
8737
|
-
const text = r.content[0]?.text;
|
|
8738
|
-
if (typeof text === "string") {
|
|
8739
|
-
try {
|
|
8740
|
-
return JSON.parse(text);
|
|
8741
|
-
} catch {
|
|
8742
|
-
}
|
|
8743
|
-
}
|
|
8744
|
-
return errorEnvelope5(
|
|
8745
|
-
"ORCHESTRATE_BRIDGE_BAD_ENVELOPE",
|
|
8746
|
-
"bridge returned an unparseable envelope for orchestrate",
|
|
8747
|
-
"Check that the Python child is healthy."
|
|
8748
|
-
);
|
|
8749
|
-
}
|
|
8750
8823
|
function errorEnvelope5(code, message, hint, kind = "client") {
|
|
8751
8824
|
return {
|
|
8752
8825
|
tool: "orchestrate",
|
|
@@ -9111,7 +9184,6 @@ ${documentsPayload}`;
|
|
|
9111
9184
|
}, {
|
|
9112
9185
|
providers: opts.providers,
|
|
9113
9186
|
allowlist: opts.allowlist ?? null,
|
|
9114
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
9115
9187
|
ctx
|
|
9116
9188
|
});
|
|
9117
9189
|
const scopeAnswer = Array.isArray(scope["answers"]) ? scope["answers"].filter((a) => typeof a["response"] === "string" && a["response"]).map((a) => `[${a["provider"]}]
|
|
@@ -9134,7 +9206,6 @@ ${scopeAnswer || "(none)"}
|
|
|
9134
9206
|
providers: opts.providers,
|
|
9135
9207
|
allowlist: opts.allowlist ?? null,
|
|
9136
9208
|
moderator,
|
|
9137
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
9138
9209
|
ctx
|
|
9139
9210
|
});
|
|
9140
9211
|
let attempts = 1;
|
|
@@ -9169,7 +9240,6 @@ ${scopeAnswer || "(none)"}
|
|
|
9169
9240
|
}, {
|
|
9170
9241
|
providers: opts.providers,
|
|
9171
9242
|
allowlist: opts.allowlist ?? null,
|
|
9172
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
9173
9243
|
ctx
|
|
9174
9244
|
});
|
|
9175
9245
|
}
|
|
@@ -9192,7 +9262,6 @@ ${scopeAnswer || "(none)"}
|
|
|
9192
9262
|
}, {
|
|
9193
9263
|
providers: opts.providers,
|
|
9194
9264
|
allowlist: opts.allowlist ?? null,
|
|
9195
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
9196
9265
|
ctx
|
|
9197
9266
|
});
|
|
9198
9267
|
let overallF = toNumberOrNull(auditEnvelope["overall_score"]);
|
|
@@ -9217,7 +9286,6 @@ ${documentsPayload}`
|
|
|
9217
9286
|
providers: opts.providers,
|
|
9218
9287
|
allowlist: opts.allowlist ?? null,
|
|
9219
9288
|
moderator,
|
|
9220
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
9221
9289
|
ctx
|
|
9222
9290
|
}
|
|
9223
9291
|
);
|
|
@@ -9237,7 +9305,6 @@ ${documentsPayload}`
|
|
|
9237
9305
|
}, {
|
|
9238
9306
|
providers: opts.providers,
|
|
9239
9307
|
allowlist: opts.allowlist ?? null,
|
|
9240
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
9241
9308
|
ctx
|
|
9242
9309
|
});
|
|
9243
9310
|
overallF = toNumberOrNull(auditEnvelope["overall_score"]);
|
|
@@ -9476,11 +9543,6 @@ function errorEnvelope6(toolName, code, message, hint) {
|
|
|
9476
9543
|
// src/tools/coordinate.ts
|
|
9477
9544
|
init_esm_shims();
|
|
9478
9545
|
import { performance as performance8 } from "perf_hooks";
|
|
9479
|
-
var DEFERRED_OPTS3 = [
|
|
9480
|
-
// empty — every coordinate opt runs natively when its deps
|
|
9481
|
-
// (storage / innerCallers) are wired. Without them the
|
|
9482
|
-
// worker_tools gate still triggers a bridge defer.
|
|
9483
|
-
];
|
|
9484
9546
|
var COORDINATE_DEFAULT_TEMP = 0.4;
|
|
9485
9547
|
var ROLE_TURN_SCHEMA = {
|
|
9486
9548
|
type: "object",
|
|
@@ -9535,23 +9597,18 @@ async function runCoordinate(args, opts) {
|
|
|
9535
9597
|
rejectedWorkerTools.push(t);
|
|
9536
9598
|
}
|
|
9537
9599
|
}
|
|
9538
|
-
|
|
9539
|
-
const needsBridge = DEFERRED_OPTS3.some((k) => Boolean(args[k])) || workerToolsNeedsBridge;
|
|
9540
|
-
if (needsBridge) {
|
|
9600
|
+
if (acceptedWorkerTools.length > 0 && !opts.innerCallers) {
|
|
9541
9601
|
if (superRequested) {
|
|
9542
9602
|
return errorEnvelope7(
|
|
9543
9603
|
"COORDINATE_SUPER_NOT_NATIVE",
|
|
9544
|
-
"super mode requested
|
|
9545
|
-
"worker_tools
|
|
9604
|
+
"super mode requested with worker_tools, but innerCallers are not wired",
|
|
9605
|
+
"worker_tools needs innerCallers wired by the host. Drop worker_tools, or wire innerCallers, to use super."
|
|
9546
9606
|
);
|
|
9547
9607
|
}
|
|
9548
|
-
if (opts.bridge && opts.bridge.toolNames.has("coordinate")) {
|
|
9549
|
-
return await deferCoordinate(args, opts.bridge);
|
|
9550
|
-
}
|
|
9551
9608
|
return errorEnvelope7(
|
|
9552
9609
|
"COORDINATE_OPT_NOT_NATIVE",
|
|
9553
9610
|
"worker_tools requested but innerCallers are not wired",
|
|
9554
|
-
"Native coordinate covers the three-role flow + untrusted_input + inject_session_memory. worker_tools needs innerCallers wired by the host
|
|
9611
|
+
"Native coordinate covers the three-role flow + untrusted_input + inject_session_memory. worker_tools needs innerCallers wired by the host."
|
|
9555
9612
|
);
|
|
9556
9613
|
}
|
|
9557
9614
|
const untrusted = Boolean(args["untrusted_input"]);
|
|
@@ -9743,8 +9800,9 @@ CRITIQUES:
|
|
|
9743
9800
|
${critiqueBlock}`
|
|
9744
9801
|
}
|
|
9745
9802
|
];
|
|
9803
|
+
const coProvider = pickCoReasoner(opts.providers, upgradeRequested);
|
|
9746
9804
|
const coReason = await coReasonThenInject({
|
|
9747
|
-
provider:
|
|
9805
|
+
provider: coProvider,
|
|
9748
9806
|
messages: synthMessages,
|
|
9749
9807
|
maxTokens,
|
|
9750
9808
|
purpose: "coordinate-coreason"
|
|
@@ -9808,7 +9866,7 @@ ${critiqueBlock}`
|
|
|
9808
9866
|
model: superRequested ? superPrimary("anthropic") ?? UPGRADE_MODEL : UPGRADE_MODEL,
|
|
9809
9867
|
label: UPGRADE_LABEL,
|
|
9810
9868
|
seat: "synthesizer",
|
|
9811
|
-
...coReasonAns ? { co_reasoner: { model:
|
|
9869
|
+
...coReasonAns ? { co_reasoner: { model: coProvider.model, label: coReasonLabel(coProvider.model) } } : {}
|
|
9812
9870
|
};
|
|
9813
9871
|
} else if (upgradeRequested) {
|
|
9814
9872
|
result["reasoning_upgrade"] = {
|
|
@@ -9950,21 +10008,6 @@ function unknownProviderError3(unknownNames, available) {
|
|
|
9950
10008
|
available_now: Object.keys(available).sort()
|
|
9951
10009
|
};
|
|
9952
10010
|
}
|
|
9953
|
-
async function deferCoordinate(args, bridge) {
|
|
9954
|
-
const r = await bridge.callTool("coordinate", args);
|
|
9955
|
-
const text = r.content[0]?.text;
|
|
9956
|
-
if (typeof text === "string") {
|
|
9957
|
-
try {
|
|
9958
|
-
return JSON.parse(text);
|
|
9959
|
-
} catch {
|
|
9960
|
-
}
|
|
9961
|
-
}
|
|
9962
|
-
return errorEnvelope7(
|
|
9963
|
-
"COORDINATE_BRIDGE_BAD_ENVELOPE",
|
|
9964
|
-
"bridge returned an unparseable envelope for coordinate",
|
|
9965
|
-
"Check that the Python child is healthy."
|
|
9966
|
-
);
|
|
9967
|
-
}
|
|
9968
10011
|
function errorEnvelope7(code, message, hint) {
|
|
9969
10012
|
return {
|
|
9970
10013
|
tool: "coordinate",
|
|
@@ -10297,10 +10340,6 @@ function buildModeratorTranscript(transcript) {
|
|
|
10297
10340
|
|
|
10298
10341
|
// src/tools/debate.ts
|
|
10299
10342
|
import { performance as performance10 } from "perf_hooks";
|
|
10300
|
-
var DEFERRED_OPTS4 = [
|
|
10301
|
-
// empty — every debate opt runs natively when its deps
|
|
10302
|
-
// (storage / innerCallers) are wired.
|
|
10303
|
-
];
|
|
10304
10343
|
async function runDebate(args, opts) {
|
|
10305
10344
|
const callStartedWall = performance10.now();
|
|
10306
10345
|
const callStartedCpu = process.cpuUsage();
|
|
@@ -10318,23 +10357,18 @@ async function runDebate(args, opts) {
|
|
|
10318
10357
|
rejectedWorkerTools.push(t);
|
|
10319
10358
|
}
|
|
10320
10359
|
}
|
|
10321
|
-
|
|
10322
|
-
const needsBridge = DEFERRED_OPTS4.some((k) => Boolean(args[k])) || workerToolsNeedsBridge;
|
|
10323
|
-
if (needsBridge) {
|
|
10360
|
+
if (acceptedWorkerTools.length > 0 && !opts.innerCallers) {
|
|
10324
10361
|
if (superRequested) {
|
|
10325
10362
|
return errorEnvelope9(
|
|
10326
10363
|
"DEBATE_SUPER_NOT_NATIVE",
|
|
10327
|
-
"super mode requested
|
|
10328
|
-
"worker_tools
|
|
10364
|
+
"super mode requested with worker_tools, but innerCallers are not wired",
|
|
10365
|
+
"worker_tools needs innerCallers wired by the host. Drop worker_tools, or wire innerCallers, to use super."
|
|
10329
10366
|
);
|
|
10330
10367
|
}
|
|
10331
|
-
if (opts.bridge && opts.bridge.toolNames.has("debate")) {
|
|
10332
|
-
return await deferDebate(args, opts.bridge);
|
|
10333
|
-
}
|
|
10334
10368
|
return errorEnvelope9(
|
|
10335
10369
|
"DEBATE_OPT_NOT_NATIVE",
|
|
10336
10370
|
"worker_tools requested but innerCallers are not wired",
|
|
10337
|
-
"Native debate covers N-round + plain/structured moderator synthesis + inject_session_memory + auto_panel + extract_claims + early_stop. worker_tools needs innerCallers wired by the host
|
|
10371
|
+
"Native debate covers N-round + plain/structured moderator synthesis + inject_session_memory + auto_panel + extract_claims + early_stop. worker_tools needs innerCallers wired by the host."
|
|
10338
10372
|
);
|
|
10339
10373
|
}
|
|
10340
10374
|
const topic = typeof args["topic"] === "string" ? args["topic"] : String(args["topic"] ?? "");
|
|
@@ -10535,6 +10569,7 @@ ${prior.body}` });
|
|
|
10535
10569
|
let synthesisErrors = [];
|
|
10536
10570
|
let personaMeta = null;
|
|
10537
10571
|
let coReasoned = false;
|
|
10572
|
+
let coReasonerModel = null;
|
|
10538
10573
|
if (moderator) {
|
|
10539
10574
|
const synthProvider = superRequested && opts.providers["anthropic"] ? retargetForSuper(opts.providers["anthropic"]) : upgraded ? retargetProvider(opts.providers["anthropic"], UPGRADE_MODEL) : moderator;
|
|
10540
10575
|
const condensed = buildModeratorTranscript(transcript);
|
|
@@ -10562,13 +10597,16 @@ TRANSCRIPT:
|
|
|
10562
10597
|
${condensed}`
|
|
10563
10598
|
}
|
|
10564
10599
|
];
|
|
10600
|
+
const openAiSeat = selected.find((p) => p.name === "openai")?.model;
|
|
10601
|
+
const coProvider = pickCoReasoner(opts.providers, upgradeRequested, openAiSeat);
|
|
10565
10602
|
const coReason = await coReasonThenInject({
|
|
10566
|
-
provider:
|
|
10603
|
+
provider: coProvider,
|
|
10567
10604
|
messages: synthMessages,
|
|
10568
10605
|
maxTokens,
|
|
10569
10606
|
purpose: "debate-coreason"
|
|
10570
10607
|
});
|
|
10571
10608
|
synthMessages = coReason.messages;
|
|
10609
|
+
coReasonerModel = coProvider?.model ?? null;
|
|
10572
10610
|
if (coReason.answer) extraAnswers.push(coReason.answer);
|
|
10573
10611
|
coReasoned = coReason.answer !== null;
|
|
10574
10612
|
if (structuredOpt) {
|
|
@@ -10627,7 +10665,7 @@ ${condensed}`
|
|
|
10627
10665
|
model: superRequested ? superPrimary("anthropic") ?? UPGRADE_MODEL : UPGRADE_MODEL,
|
|
10628
10666
|
label: UPGRADE_LABEL,
|
|
10629
10667
|
seat: "moderator synthesis",
|
|
10630
|
-
...coReasoned ? { co_reasoner: { model:
|
|
10668
|
+
...coReasoned && coReasonerModel ? { co_reasoner: { model: coReasonerModel, label: coReasonLabel(coReasonerModel) } } : {}
|
|
10631
10669
|
};
|
|
10632
10670
|
} else if (upgradeRequested) {
|
|
10633
10671
|
result["reasoning_upgrade"] = {
|
|
@@ -10767,21 +10805,6 @@ function unknownProviderError5(unknownNames, available) {
|
|
|
10767
10805
|
available_now: Object.keys(available).sort()
|
|
10768
10806
|
};
|
|
10769
10807
|
}
|
|
10770
|
-
async function deferDebate(args, bridge) {
|
|
10771
|
-
const r = await bridge.callTool("debate", args);
|
|
10772
|
-
const text = r.content[0]?.text;
|
|
10773
|
-
if (typeof text === "string") {
|
|
10774
|
-
try {
|
|
10775
|
-
return JSON.parse(text);
|
|
10776
|
-
} catch {
|
|
10777
|
-
}
|
|
10778
|
-
}
|
|
10779
|
-
return errorEnvelope9(
|
|
10780
|
-
"DEBATE_BRIDGE_BAD_ENVELOPE",
|
|
10781
|
-
"bridge returned an unparseable envelope for debate",
|
|
10782
|
-
"Check that the Python child is healthy."
|
|
10783
|
-
);
|
|
10784
|
-
}
|
|
10785
10808
|
function errorEnvelope9(code, message, hint) {
|
|
10786
10809
|
return {
|
|
10787
10810
|
tool: "debate",
|
|
@@ -10802,9 +10825,6 @@ var DEFAULT_DELEGATION_LIMITS = {
|
|
|
10802
10825
|
};
|
|
10803
10826
|
async function runDelegate(args, opts) {
|
|
10804
10827
|
if (!opts.storage) {
|
|
10805
|
-
if (opts.bridge && opts.bridge.toolNames.has("delegate")) {
|
|
10806
|
-
return await deferDelegate(args, opts.bridge);
|
|
10807
|
-
}
|
|
10808
10828
|
return errorEnvelope10(
|
|
10809
10829
|
"DELEGATE_STORAGE_UNAVAILABLE",
|
|
10810
10830
|
"delegate needs the local database (for quota tracking), which isn't available",
|
|
@@ -10876,7 +10896,6 @@ async function runDelegate(args, opts) {
|
|
|
10876
10896
|
const innerOpts = {
|
|
10877
10897
|
providers: opts.providers,
|
|
10878
10898
|
allowlist: opts.allowlist ?? null,
|
|
10879
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
10880
10899
|
...opts.moderator ? { moderator: opts.moderator } : {}
|
|
10881
10900
|
};
|
|
10882
10901
|
let result;
|
|
@@ -10915,21 +10934,6 @@ async function record(storage, sessionId, requester, toolCall, via, accepted, no
|
|
|
10915
10934
|
created_at: nowEpochSeconds
|
|
10916
10935
|
});
|
|
10917
10936
|
}
|
|
10918
|
-
async function deferDelegate(args, bridge) {
|
|
10919
|
-
const r = await bridge.callTool("delegate", args);
|
|
10920
|
-
const text = r.content[0]?.text;
|
|
10921
|
-
if (typeof text === "string") {
|
|
10922
|
-
try {
|
|
10923
|
-
return JSON.parse(text);
|
|
10924
|
-
} catch {
|
|
10925
|
-
}
|
|
10926
|
-
}
|
|
10927
|
-
return errorEnvelope10(
|
|
10928
|
-
"DELEGATE_BRIDGE_BAD_ENVELOPE",
|
|
10929
|
-
"bridge returned an unparseable envelope for delegate",
|
|
10930
|
-
"Check that the Python child is healthy."
|
|
10931
|
-
);
|
|
10932
|
-
}
|
|
10933
10937
|
function errorEnvelope10(code, message, hint) {
|
|
10934
10938
|
return {
|
|
10935
10939
|
tool: "delegate",
|
|
@@ -10973,9 +10977,6 @@ async function runExplain(args, opts) {
|
|
|
10973
10977
|
);
|
|
10974
10978
|
}
|
|
10975
10979
|
if (!opts.storage) {
|
|
10976
|
-
if (opts.bridge && opts.bridge.toolNames.has("explain")) {
|
|
10977
|
-
return await deferExplain(args, opts.bridge);
|
|
10978
|
-
}
|
|
10979
10980
|
return errorEnvelope11(
|
|
10980
10981
|
"EXPLAIN_STORAGE_UNAVAILABLE",
|
|
10981
10982
|
"explain needs the local transcript/stats database, which isn't available",
|
|
@@ -11257,21 +11258,6 @@ function pyRepr5(v) {
|
|
|
11257
11258
|
}
|
|
11258
11259
|
return String(v);
|
|
11259
11260
|
}
|
|
11260
|
-
async function deferExplain(args, bridge) {
|
|
11261
|
-
const r = await bridge.callTool("explain", args);
|
|
11262
|
-
const text = r.content[0]?.text;
|
|
11263
|
-
if (typeof text === "string") {
|
|
11264
|
-
try {
|
|
11265
|
-
return JSON.parse(text);
|
|
11266
|
-
} catch {
|
|
11267
|
-
}
|
|
11268
|
-
}
|
|
11269
|
-
return errorEnvelope11(
|
|
11270
|
-
"EXPLAIN_BRIDGE_BAD_ENVELOPE",
|
|
11271
|
-
"bridge returned an unparseable envelope for explain",
|
|
11272
|
-
"Check that the Python child is healthy."
|
|
11273
|
-
);
|
|
11274
|
-
}
|
|
11275
11261
|
function errorEnvelope11(code, message, hint, kind = "client", extra = {}) {
|
|
11276
11262
|
return {
|
|
11277
11263
|
tool: "explain",
|
|
@@ -11829,9 +11815,6 @@ async function runRecall(args, opts) {
|
|
|
11829
11815
|
if (k < 1) k = 1;
|
|
11830
11816
|
if (k > 50) k = 50;
|
|
11831
11817
|
if (!opts.storage) {
|
|
11832
|
-
if (opts.bridge && opts.bridge.toolNames.has("recall")) {
|
|
11833
|
-
return await deferRecall(args, opts.bridge);
|
|
11834
|
-
}
|
|
11835
11818
|
return errorEnvelope12(
|
|
11836
11819
|
"RECALL_STORAGE_UNAVAILABLE",
|
|
11837
11820
|
"recall needs the local database, which isn't available",
|
|
@@ -11884,21 +11867,6 @@ async function runRecall(args, opts) {
|
|
|
11884
11867
|
applied_filters: applied
|
|
11885
11868
|
};
|
|
11886
11869
|
}
|
|
11887
|
-
async function deferRecall(args, bridge) {
|
|
11888
|
-
const r = await bridge.callTool("recall", args);
|
|
11889
|
-
const text = r.content[0]?.text;
|
|
11890
|
-
if (typeof text === "string") {
|
|
11891
|
-
try {
|
|
11892
|
-
return JSON.parse(text);
|
|
11893
|
-
} catch {
|
|
11894
|
-
}
|
|
11895
|
-
}
|
|
11896
|
-
return errorEnvelope12(
|
|
11897
|
-
"RECALL_BRIDGE_BAD_ENVELOPE",
|
|
11898
|
-
"bridge returned an unparseable envelope for recall",
|
|
11899
|
-
"Check that the Python child is healthy."
|
|
11900
|
-
);
|
|
11901
|
-
}
|
|
11902
11870
|
function errorEnvelope12(code, message, hint) {
|
|
11903
11871
|
return {
|
|
11904
11872
|
tool: "recall",
|
|
@@ -11922,9 +11890,6 @@ async function runRecommendPanel(args, opts) {
|
|
|
11922
11890
|
);
|
|
11923
11891
|
}
|
|
11924
11892
|
if (!opts.storage) {
|
|
11925
|
-
if (opts.bridge && opts.bridge.toolNames.has("recommend_panel")) {
|
|
11926
|
-
return await deferRecommendPanel(args, opts.bridge);
|
|
11927
|
-
}
|
|
11928
11893
|
return errorEnvelope13(
|
|
11929
11894
|
"RECOMMEND_PANEL_STORAGE_UNAVAILABLE",
|
|
11930
11895
|
"recommend_panel needs the local stats database, which isn't available",
|
|
@@ -11987,21 +11952,6 @@ async function runRecommendPanel(args, opts) {
|
|
|
11987
11952
|
meta: result.meta
|
|
11988
11953
|
};
|
|
11989
11954
|
}
|
|
11990
|
-
async function deferRecommendPanel(args, bridge) {
|
|
11991
|
-
const r = await bridge.callTool("recommend_panel", args);
|
|
11992
|
-
const text = r.content[0]?.text;
|
|
11993
|
-
if (typeof text === "string") {
|
|
11994
|
-
try {
|
|
11995
|
-
return JSON.parse(text);
|
|
11996
|
-
} catch {
|
|
11997
|
-
}
|
|
11998
|
-
}
|
|
11999
|
-
return errorEnvelope13(
|
|
12000
|
-
"RECOMMEND_PANEL_BRIDGE_BAD_ENVELOPE",
|
|
12001
|
-
"bridge returned an unparseable envelope for recommend_panel",
|
|
12002
|
-
"Check that the Python child is healthy."
|
|
12003
|
-
);
|
|
12004
|
-
}
|
|
12005
11955
|
function errorEnvelope13(code, message, hint) {
|
|
12006
11956
|
return {
|
|
12007
11957
|
tool: "recommend_panel",
|
|
@@ -12032,9 +11982,6 @@ init_esm_shims();
|
|
|
12032
11982
|
import { readFileSync as readFileSync10, existsSync as existsSync8 } from "fs";
|
|
12033
11983
|
async function runScoreboard(args, opts) {
|
|
12034
11984
|
if (!opts.storage) {
|
|
12035
|
-
if (opts.bridge && opts.bridge.toolNames.has("scoreboard")) {
|
|
12036
|
-
return await deferScoreboard(args, opts.bridge);
|
|
12037
|
-
}
|
|
12038
11985
|
return errorEnvelope14(
|
|
12039
11986
|
"SCOREBOARD_STORAGE_UNAVAILABLE",
|
|
12040
11987
|
"scoreboard needs the local stats database, which isn't available",
|
|
@@ -12157,21 +12104,6 @@ function clampInt3(raw, min, max, fallback) {
|
|
|
12157
12104
|
if (!Number.isFinite(n)) return fallback;
|
|
12158
12105
|
return Math.min(max, Math.max(min, Math.trunc(n)));
|
|
12159
12106
|
}
|
|
12160
|
-
async function deferScoreboard(args, bridge) {
|
|
12161
|
-
const r = await bridge.callTool("scoreboard", args);
|
|
12162
|
-
const text = r.content[0]?.text;
|
|
12163
|
-
if (typeof text === "string") {
|
|
12164
|
-
try {
|
|
12165
|
-
return JSON.parse(text);
|
|
12166
|
-
} catch {
|
|
12167
|
-
}
|
|
12168
|
-
}
|
|
12169
|
-
return errorEnvelope14(
|
|
12170
|
-
"SCOREBOARD_BRIDGE_BAD_ENVELOPE",
|
|
12171
|
-
"bridge returned an unparseable envelope for scoreboard",
|
|
12172
|
-
"Check that the Python child is healthy."
|
|
12173
|
-
);
|
|
12174
|
-
}
|
|
12175
12107
|
function errorEnvelope14(code, message, hint) {
|
|
12176
12108
|
return {
|
|
12177
12109
|
tool: "scoreboard",
|
|
@@ -12209,9 +12141,6 @@ async function runSessionMemory(args, opts) {
|
|
|
12209
12141
|
);
|
|
12210
12142
|
}
|
|
12211
12143
|
if (!opts.storage) {
|
|
12212
|
-
if (opts.bridge && opts.bridge.toolNames.has("session_memory")) {
|
|
12213
|
-
return await deferSessionMemory(args, opts.bridge);
|
|
12214
|
-
}
|
|
12215
12144
|
return errorEnvelope15(
|
|
12216
12145
|
"SESSION_MEMORY_STORAGE_UNAVAILABLE",
|
|
12217
12146
|
"session_memory needs the local database, which isn't available",
|
|
@@ -12316,21 +12245,6 @@ function clampInt4(raw, min, max, fallback) {
|
|
|
12316
12245
|
if (!Number.isFinite(n)) return fallback;
|
|
12317
12246
|
return Math.min(max, Math.max(min, Math.trunc(n)));
|
|
12318
12247
|
}
|
|
12319
|
-
async function deferSessionMemory(args, bridge) {
|
|
12320
|
-
const r = await bridge.callTool("session_memory", args);
|
|
12321
|
-
const text = r.content[0]?.text;
|
|
12322
|
-
if (typeof text === "string") {
|
|
12323
|
-
try {
|
|
12324
|
-
return JSON.parse(text);
|
|
12325
|
-
} catch {
|
|
12326
|
-
}
|
|
12327
|
-
}
|
|
12328
|
-
return errorEnvelope15(
|
|
12329
|
-
"SESSION_MEMORY_BRIDGE_BAD_ENVELOPE",
|
|
12330
|
-
"bridge returned an unparseable envelope for session_memory",
|
|
12331
|
-
"Check that the Python child is healthy."
|
|
12332
|
-
);
|
|
12333
|
-
}
|
|
12334
12248
|
function errorEnvelope15(code, message, hint) {
|
|
12335
12249
|
return {
|
|
12336
12250
|
tool: "session_memory",
|
|
@@ -12663,7 +12577,7 @@ Re-emit the FULL solution. No commentary.`
|
|
|
12663
12577
|
model: UPGRADE_MODEL,
|
|
12664
12578
|
label: UPGRADE_LABEL,
|
|
12665
12579
|
seat: "solver",
|
|
12666
|
-
...coReasoned ? { co_reasoner: { model:
|
|
12580
|
+
...coReasoned ? { co_reasoner: { model: coProvider.model, label: coReasonLabel(coProvider.model) } } : {}
|
|
12667
12581
|
};
|
|
12668
12582
|
} else if (upgradeRequested) {
|
|
12669
12583
|
result["reasoning_upgrade"] = {
|
|
@@ -12954,7 +12868,7 @@ var CHECK_INTERVAL_SECONDS = 3 * 24 * 60 * 60;
|
|
|
12954
12868
|
var DEFAULT_PACKAGE = "crosscheck-cli";
|
|
12955
12869
|
var FETCH_TIMEOUT_MS = 3e3;
|
|
12956
12870
|
function engineVersion() {
|
|
12957
|
-
return true ? "0.2.
|
|
12871
|
+
return true ? "0.2.28" : "0.0.0-dev";
|
|
12958
12872
|
}
|
|
12959
12873
|
function defaultUpdateCachePath() {
|
|
12960
12874
|
const base = process.env["CROSSCHECK_DATA_DIR"] || path10.join(os.homedir() || os.tmpdir(), ".crosscheck");
|
|
@@ -13728,12 +13642,11 @@ function helpTool() {
|
|
|
13728
13642
|
}
|
|
13729
13643
|
});
|
|
13730
13644
|
}
|
|
13731
|
-
function registerCoreTools(
|
|
13732
|
-
const o = opts && typeof opts === "object" && "toolNames" in opts ? { bridge: opts } : opts;
|
|
13645
|
+
function registerCoreTools(o = {}) {
|
|
13733
13646
|
const tools = /* @__PURE__ */ new Map();
|
|
13734
13647
|
const list = [
|
|
13735
13648
|
pingTool(),
|
|
13736
|
-
verifyTool(o.
|
|
13649
|
+
verifyTool(o.fetchConfig),
|
|
13737
13650
|
pickTool(
|
|
13738
13651
|
o.providers ?? {},
|
|
13739
13652
|
o.providerAllowlist ?? null,
|
|
@@ -13745,7 +13658,6 @@ function registerCoreTools(opts = {}) {
|
|
|
13745
13658
|
auditTool(
|
|
13746
13659
|
o.providers ?? {},
|
|
13747
13660
|
o.providerAllowlist ?? null,
|
|
13748
|
-
o.bridge,
|
|
13749
13661
|
o.transcriptsDir,
|
|
13750
13662
|
o.pricing,
|
|
13751
13663
|
o.storage,
|
|
@@ -13755,7 +13667,6 @@ function registerCoreTools(opts = {}) {
|
|
|
13755
13667
|
conferTool(
|
|
13756
13668
|
o.providers ?? {},
|
|
13757
13669
|
o.providerAllowlist ?? null,
|
|
13758
|
-
o.bridge,
|
|
13759
13670
|
o.moderatorDefault ?? "anthropic",
|
|
13760
13671
|
o.pricing,
|
|
13761
13672
|
o.storage,
|
|
@@ -13768,7 +13679,6 @@ function registerCoreTools(opts = {}) {
|
|
|
13768
13679
|
debateTool(
|
|
13769
13680
|
o.providers ?? {},
|
|
13770
13681
|
o.providerAllowlist ?? null,
|
|
13771
|
-
o.bridge,
|
|
13772
13682
|
buildInnerCallers(o),
|
|
13773
13683
|
o.storage,
|
|
13774
13684
|
o.pricing,
|
|
@@ -13780,7 +13690,6 @@ function registerCoreTools(opts = {}) {
|
|
|
13780
13690
|
coordinateTool(
|
|
13781
13691
|
o.providers ?? {},
|
|
13782
13692
|
o.providerAllowlist ?? null,
|
|
13783
|
-
o.bridge,
|
|
13784
13693
|
buildInnerCallers(o),
|
|
13785
13694
|
o.storage,
|
|
13786
13695
|
o.circuitBreakers,
|
|
@@ -13791,7 +13700,6 @@ function registerCoreTools(opts = {}) {
|
|
|
13791
13700
|
triangulateTool(
|
|
13792
13701
|
o.providers ?? {},
|
|
13793
13702
|
o.providerAllowlist ?? null,
|
|
13794
|
-
o.bridge,
|
|
13795
13703
|
o.storage,
|
|
13796
13704
|
o.circuitBreakers,
|
|
13797
13705
|
o.transcriptsDir,
|
|
@@ -13800,7 +13708,6 @@ function registerCoreTools(opts = {}) {
|
|
|
13800
13708
|
planTool(
|
|
13801
13709
|
o.providers ?? {},
|
|
13802
13710
|
o.providerAllowlist ?? null,
|
|
13803
|
-
o.bridge,
|
|
13804
13711
|
o.storage,
|
|
13805
13712
|
o.circuitBreakers,
|
|
13806
13713
|
o.transcriptsDir,
|
|
@@ -13809,7 +13716,6 @@ function registerCoreTools(opts = {}) {
|
|
|
13809
13716
|
critiqueTool(
|
|
13810
13717
|
o.providers ?? {},
|
|
13811
13718
|
o.providerAllowlist ?? null,
|
|
13812
|
-
o.bridge,
|
|
13813
13719
|
o.storage,
|
|
13814
13720
|
o.circuitBreakers,
|
|
13815
13721
|
o.transcriptsDir,
|
|
@@ -13818,7 +13724,6 @@ function registerCoreTools(opts = {}) {
|
|
|
13818
13724
|
reviewTool(
|
|
13819
13725
|
o.providers ?? {},
|
|
13820
13726
|
o.providerAllowlist ?? null,
|
|
13821
|
-
o.bridge,
|
|
13822
13727
|
o.storage,
|
|
13823
13728
|
o.circuitBreakers,
|
|
13824
13729
|
o.transcriptsDir,
|
|
@@ -13826,25 +13731,23 @@ function registerCoreTools(opts = {}) {
|
|
|
13826
13731
|
),
|
|
13827
13732
|
listProvidersTool(o.providers ?? {}, o.activeProviders ?? null, o.moderatorDefault ?? "anthropic"),
|
|
13828
13733
|
modelsTool(o.providers ?? {}, o.activeProviders ?? null),
|
|
13829
|
-
recallTool(o.storage
|
|
13830
|
-
sessionMemoryTool(o.storage
|
|
13831
|
-
scoreboardTool(o.storage, o.
|
|
13832
|
-
explainTool(o.storage, o.
|
|
13734
|
+
recallTool(o.storage),
|
|
13735
|
+
sessionMemoryTool(o.storage),
|
|
13736
|
+
scoreboardTool(o.storage, o.eventsPath),
|
|
13737
|
+
explainTool(o.storage, o.transcriptsDir),
|
|
13833
13738
|
delegateTool(
|
|
13834
13739
|
o.providers ?? {},
|
|
13835
13740
|
o.providerAllowlist ?? null,
|
|
13836
13741
|
o.storage,
|
|
13837
|
-
o.bridge,
|
|
13838
13742
|
o.moderatorDefault ?? "anthropic"
|
|
13839
13743
|
),
|
|
13840
13744
|
fetchTool(o.storage, o.fetchConfig, o.repoRoot),
|
|
13841
|
-
recommendPanelTool(o.providers ?? {}, o.storage
|
|
13745
|
+
recommendPanelTool(o.providers ?? {}, o.storage),
|
|
13842
13746
|
updateCrosscheckTool(o.repoRoot ?? null),
|
|
13843
13747
|
benchTool(
|
|
13844
13748
|
o.providers ?? {},
|
|
13845
13749
|
o.providerAllowlist ?? null,
|
|
13846
13750
|
o.storage,
|
|
13847
|
-
o.bridge,
|
|
13848
13751
|
o.moderatorDefault ?? "anthropic",
|
|
13849
13752
|
o.benchGoldensDir,
|
|
13850
13753
|
o.circuitBreakers,
|
|
@@ -13855,7 +13758,6 @@ function registerCoreTools(opts = {}) {
|
|
|
13855
13758
|
solveTool(
|
|
13856
13759
|
o.providers ?? {},
|
|
13857
13760
|
o.providerAllowlist ?? null,
|
|
13858
|
-
o.bridge,
|
|
13859
13761
|
o.storage,
|
|
13860
13762
|
o.circuitBreakers,
|
|
13861
13763
|
o.transcriptsDir,
|
|
@@ -13864,7 +13766,6 @@ function registerCoreTools(opts = {}) {
|
|
|
13864
13766
|
orchestrateTool(
|
|
13865
13767
|
o.providers ?? {},
|
|
13866
13768
|
o.providerAllowlist ?? null,
|
|
13867
|
-
o.bridge,
|
|
13868
13769
|
o.moderatorDefault ?? "anthropic",
|
|
13869
13770
|
o.storage,
|
|
13870
13771
|
o.pricing,
|
|
@@ -13911,7 +13812,6 @@ function createTool(o, toolName, cheapDefault) {
|
|
|
13911
13812
|
providers: o.providers ?? {},
|
|
13912
13813
|
allowlist: o.providerAllowlist ?? null,
|
|
13913
13814
|
...o.storage ? { storage: o.storage } : {},
|
|
13914
|
-
...o.bridge ? { bridge: o.bridge } : {},
|
|
13915
13815
|
...o.moderatorDefault ? { moderator: o.moderatorDefault } : {},
|
|
13916
13816
|
...o.fetchConfig ? { fetchConfig: o.fetchConfig } : {},
|
|
13917
13817
|
...o.repoRoot ? { repoRoot: o.repoRoot } : {},
|
|
@@ -13920,7 +13820,7 @@ function createTool(o, toolName, cheapDefault) {
|
|
|
13920
13820
|
})
|
|
13921
13821
|
};
|
|
13922
13822
|
}
|
|
13923
|
-
function orchestrateTool(providers, allowlist,
|
|
13823
|
+
function orchestrateTool(providers, allowlist, moderator, storage, pricing, breakers, transcriptsDir, repoRoot, nodeCache) {
|
|
13924
13824
|
return {
|
|
13925
13825
|
name: "orchestrate",
|
|
13926
13826
|
description: "Plan and execute a DAG of LLM subtasks. Either supply a `goal` (planner will draft the DAG) OR a hand-authored `dag`. Workers run topologically; recombine produces a single `final`. Covers the sequential flow, cheap_mode (per-node tier picking), and reactive (mid-flight DAG updates) \u2014 all native.",
|
|
@@ -13945,7 +13845,6 @@ function orchestrateTool(providers, allowlist, bridge, moderator, storage, prici
|
|
|
13945
13845
|
providers,
|
|
13946
13846
|
allowlist,
|
|
13947
13847
|
moderator,
|
|
13948
|
-
...bridge ? { bridge } : {},
|
|
13949
13848
|
...storage ? { storage } : {},
|
|
13950
13849
|
...pricing ? { pricing } : {},
|
|
13951
13850
|
...breakers ? { breakers } : {},
|
|
@@ -13955,7 +13854,7 @@ function orchestrateTool(providers, allowlist, bridge, moderator, storage, prici
|
|
|
13955
13854
|
})
|
|
13956
13855
|
};
|
|
13957
13856
|
}
|
|
13958
|
-
function solveTool(providers, allowlist,
|
|
13857
|
+
function solveTool(providers, allowlist, storage, breakers, transcriptsDir, repoRoot) {
|
|
13959
13858
|
return {
|
|
13960
13859
|
name: "solve",
|
|
13961
13860
|
description: "Iterative LLM solver. Generates a proposal, verifies it against the supplied verifier, and retries with feedback up to max_attempts. Verifier kinds: regex_response and shell (run in a native sandbox with wall-clock + optional memory/CPU limits). With target_path, returns a unified-diff patch.",
|
|
@@ -13977,7 +13876,6 @@ function solveTool(providers, allowlist, bridge, storage, breakers, transcriptsD
|
|
|
13977
13876
|
handler: (args) => runSolve(args, {
|
|
13978
13877
|
providers,
|
|
13979
13878
|
allowlist,
|
|
13980
|
-
...bridge ? { bridge } : {},
|
|
13981
13879
|
...storage ? { storage } : {},
|
|
13982
13880
|
...breakers ? { breakers } : {},
|
|
13983
13881
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -14016,7 +13914,7 @@ function configPinTool(repoRoot, config2, rejectDriftEnv) {
|
|
|
14016
13914
|
}
|
|
14017
13915
|
};
|
|
14018
13916
|
}
|
|
14019
|
-
function benchTool(providers, allowlist, storage,
|
|
13917
|
+
function benchTool(providers, allowlist, storage, moderator, defaultGoldensDir, breakers, transcriptsDir, repoRoot) {
|
|
14020
13918
|
return {
|
|
14021
13919
|
name: "bench",
|
|
14022
13920
|
description: "Run benchmark goldens against each provider's confer/review output. Each golden: {name, tool_call: confer|review, args, verifiers[]}. Returns per-provider pass/fail/error + a ranking sorted by score. Records ballots into provider_stats when storage is wired (used by triangulate's win-rate weights).",
|
|
@@ -14035,7 +13933,6 @@ function benchTool(providers, allowlist, storage, bridge, moderator, defaultGold
|
|
|
14035
13933
|
allowlist,
|
|
14036
13934
|
moderator,
|
|
14037
13935
|
...storage ? { storage } : {},
|
|
14038
|
-
...bridge ? { bridge } : {},
|
|
14039
13936
|
...defaultGoldensDir ? { defaultGoldensDir } : {},
|
|
14040
13937
|
...breakers ? { breakers } : {},
|
|
14041
13938
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -14062,7 +13959,7 @@ function updateCrosscheckTool(repoRoot) {
|
|
|
14062
13959
|
}
|
|
14063
13960
|
};
|
|
14064
13961
|
}
|
|
14065
|
-
function recommendPanelTool(providers, storage
|
|
13962
|
+
function recommendPanelTool(providers, storage) {
|
|
14066
13963
|
return {
|
|
14067
13964
|
name: "recommend_panel",
|
|
14068
13965
|
description: "Recommend a minimal effective panel for a given purpose, based on historical usage_log + provider_stats. Cold-start falls back to the configured panel ordered by win-rate.",
|
|
@@ -14080,8 +13977,7 @@ function recommendPanelTool(providers, storage, bridge) {
|
|
|
14080
13977
|
},
|
|
14081
13978
|
handler: (args) => runRecommendPanel(args, {
|
|
14082
13979
|
providers,
|
|
14083
|
-
...storage ? { storage } : {}
|
|
14084
|
-
...bridge ? { bridge } : {}
|
|
13980
|
+
...storage ? { storage } : {}
|
|
14085
13981
|
})
|
|
14086
13982
|
};
|
|
14087
13983
|
}
|
|
@@ -14106,7 +14002,7 @@ function fetchTool(storage, fetchConfig, repoRoot) {
|
|
|
14106
14002
|
})
|
|
14107
14003
|
};
|
|
14108
14004
|
}
|
|
14109
|
-
function delegateTool(providers, allowlist, storage,
|
|
14005
|
+
function delegateTool(providers, allowlist, storage, moderator) {
|
|
14110
14006
|
return {
|
|
14111
14007
|
name: "delegate",
|
|
14112
14008
|
description: "Run a delegable tool (confer | review) restricted to a single named provider, with explicit quota check. Records every attempt (accepted or refused) to the delegations table; quota in the response reflects counts AFTER the current call.",
|
|
@@ -14126,12 +14022,11 @@ function delegateTool(providers, allowlist, storage, bridge, moderator) {
|
|
|
14126
14022
|
providers,
|
|
14127
14023
|
allowlist,
|
|
14128
14024
|
moderator,
|
|
14129
|
-
...storage ? { storage } : {}
|
|
14130
|
-
...bridge ? { bridge } : {}
|
|
14025
|
+
...storage ? { storage } : {}
|
|
14131
14026
|
})
|
|
14132
14027
|
};
|
|
14133
14028
|
}
|
|
14134
|
-
function explainTool(storage,
|
|
14029
|
+
function explainTool(storage, transcriptsDir) {
|
|
14135
14030
|
return {
|
|
14136
14031
|
name: "explain",
|
|
14137
14032
|
description: "Replay a session as a navigable tree with cost/latency annotations. Reads usage_log + optionally walks the transcripts directory for per-tool summaries.",
|
|
@@ -14149,12 +14044,11 @@ function explainTool(storage, bridge, transcriptsDir) {
|
|
|
14149
14044
|
},
|
|
14150
14045
|
handler: (args) => runExplain(args, {
|
|
14151
14046
|
...storage ? { storage } : {},
|
|
14152
|
-
...bridge ? { bridge } : {},
|
|
14153
14047
|
...transcriptsDir ? { transcriptsDir } : {}
|
|
14154
14048
|
})
|
|
14155
14049
|
};
|
|
14156
14050
|
}
|
|
14157
|
-
function scoreboardTool(storage,
|
|
14051
|
+
function scoreboardTool(storage, eventsPath) {
|
|
14158
14052
|
return {
|
|
14159
14053
|
name: "scoreboard",
|
|
14160
14054
|
description: "Aggregate provider ballot stats + delegation counts + table totals. Supports top_k (rank limit) and recent_limit (tail of events.jsonl when configured). Reads the engine's local stats database (auto-created at <data dir>/db.sqlite).",
|
|
@@ -14168,12 +14062,11 @@ function scoreboardTool(storage, bridge, eventsPath) {
|
|
|
14168
14062
|
},
|
|
14169
14063
|
handler: (args) => runScoreboard(args, {
|
|
14170
14064
|
...storage ? { storage } : {},
|
|
14171
|
-
...bridge ? { bridge } : {},
|
|
14172
14065
|
...eventsPath ? { eventsPath } : {}
|
|
14173
14066
|
})
|
|
14174
14067
|
};
|
|
14175
14068
|
}
|
|
14176
|
-
function sessionMemoryTool(storage
|
|
14069
|
+
function sessionMemoryTool(storage) {
|
|
14177
14070
|
return {
|
|
14178
14071
|
name: "session_memory",
|
|
14179
14072
|
description: "CRUD over the per-session working memory ledger. Actions: list, add, mark_stale, clear. Uses the engine's local database (auto-created at <data dir>/db.sqlite).",
|
|
@@ -14196,15 +14089,14 @@ function sessionMemoryTool(storage, bridge) {
|
|
|
14196
14089
|
required: ["action", "session_id"]
|
|
14197
14090
|
},
|
|
14198
14091
|
handler: (args) => runSessionMemory(args, {
|
|
14199
|
-
...storage ? { storage } : {}
|
|
14200
|
-
...bridge ? { bridge } : {}
|
|
14092
|
+
...storage ? { storage } : {}
|
|
14201
14093
|
})
|
|
14202
14094
|
};
|
|
14203
14095
|
}
|
|
14204
|
-
function recallTool(storage
|
|
14096
|
+
function recallTool(storage) {
|
|
14205
14097
|
return {
|
|
14206
14098
|
name: "recall",
|
|
14207
|
-
description: "Full-text search across persisted transcripts via SQLite FTS5. Returns rows ordered by relevance with a windowed snippet. Requires a wired Storage adapter
|
|
14099
|
+
description: "Full-text search across persisted transcripts via SQLite FTS5. Returns rows ordered by relevance with a windowed snippet. Requires a wired Storage adapter.",
|
|
14208
14100
|
inputSchema: {
|
|
14209
14101
|
type: "object",
|
|
14210
14102
|
additionalProperties: true,
|
|
@@ -14218,8 +14110,7 @@ function recallTool(storage, bridge) {
|
|
|
14218
14110
|
required: ["query"]
|
|
14219
14111
|
},
|
|
14220
14112
|
handler: (args) => runRecall(args, {
|
|
14221
|
-
...storage ? { storage } : {}
|
|
14222
|
-
...bridge ? { bridge } : {}
|
|
14113
|
+
...storage ? { storage } : {}
|
|
14223
14114
|
})
|
|
14224
14115
|
};
|
|
14225
14116
|
}
|
|
@@ -14255,7 +14146,7 @@ function modelsTool(providers, activeProviders) {
|
|
|
14255
14146
|
handler: async (args) => runModels(args, { providers, activeProviders })
|
|
14256
14147
|
};
|
|
14257
14148
|
}
|
|
14258
|
-
function reviewTool(providers, allowlist,
|
|
14149
|
+
function reviewTool(providers, allowlist, storage, breakers, transcriptsDir, repoRoot) {
|
|
14259
14150
|
return {
|
|
14260
14151
|
name: "review",
|
|
14261
14152
|
description: "Have an LLM panel peer-review a code or proposal snippet. Returns the confer envelope (one answer per provider).",
|
|
@@ -14274,7 +14165,6 @@ function reviewTool(providers, allowlist, bridge, storage, breakers, transcripts
|
|
|
14274
14165
|
handler: (args) => runReview(args, {
|
|
14275
14166
|
providers,
|
|
14276
14167
|
allowlist,
|
|
14277
|
-
...bridge ? { bridge } : {},
|
|
14278
14168
|
...storage ? { storage } : {},
|
|
14279
14169
|
...breakers ? { breakers } : {},
|
|
14280
14170
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -14282,7 +14172,7 @@ function reviewTool(providers, allowlist, bridge, storage, breakers, transcripts
|
|
|
14282
14172
|
})
|
|
14283
14173
|
};
|
|
14284
14174
|
}
|
|
14285
|
-
function critiqueTool(providers, allowlist,
|
|
14175
|
+
function critiqueTool(providers, allowlist, storage, breakers, transcriptsDir, repoRoot) {
|
|
14286
14176
|
return {
|
|
14287
14177
|
name: "critique",
|
|
14288
14178
|
description: "Have each LLM panelist list the top weaknesses of a proposed answer or approach (severity-rated). Returns per-provider weakness lists + a merged list ordered by severity.",
|
|
@@ -14302,7 +14192,6 @@ function critiqueTool(providers, allowlist, bridge, storage, breakers, transcrip
|
|
|
14302
14192
|
handler: (args) => runCritique(args, {
|
|
14303
14193
|
providers,
|
|
14304
14194
|
allowlist,
|
|
14305
|
-
...bridge ? { bridge } : {},
|
|
14306
14195
|
...storage ? { storage } : {},
|
|
14307
14196
|
...breakers ? { breakers } : {},
|
|
14308
14197
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -14310,7 +14199,7 @@ function critiqueTool(providers, allowlist, bridge, storage, breakers, transcrip
|
|
|
14310
14199
|
})
|
|
14311
14200
|
};
|
|
14312
14201
|
}
|
|
14313
|
-
function planTool(providers, allowlist,
|
|
14202
|
+
function planTool(providers, allowlist, storage, breakers, transcriptsDir, repoRoot) {
|
|
14314
14203
|
return {
|
|
14315
14204
|
name: "plan",
|
|
14316
14205
|
description: 'Have an LLM panel debate a step-by-step plan for the stated goal under the given constraints. Returns the debate envelope with a moderator-synthesised plan. Defaults to `mode: "fast"` (2 rounds + early_stop) \u2014 set `mode: "thorough"` for 5 rounds without early_stop. Explicit `max_rounds` / `early_stop` / `early_stop_threshold` always override the mode preset. Use `structured: true` for schema-validated synthesis.',
|
|
@@ -14337,7 +14226,6 @@ function planTool(providers, allowlist, bridge, storage, breakers, transcriptsDi
|
|
|
14337
14226
|
handler: (args) => runPlan(args, {
|
|
14338
14227
|
providers,
|
|
14339
14228
|
allowlist,
|
|
14340
|
-
...bridge ? { bridge } : {},
|
|
14341
14229
|
...storage ? { storage } : {},
|
|
14342
14230
|
...breakers ? { breakers } : {},
|
|
14343
14231
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -14345,7 +14233,7 @@ function planTool(providers, allowlist, bridge, storage, breakers, transcriptsDi
|
|
|
14345
14233
|
})
|
|
14346
14234
|
};
|
|
14347
14235
|
}
|
|
14348
|
-
function triangulateTool(providers, allowlist,
|
|
14236
|
+
function triangulateTool(providers, allowlist, storage, breakers, transcriptsDir, repoRoot) {
|
|
14349
14237
|
return {
|
|
14350
14238
|
name: "triangulate",
|
|
14351
14239
|
description: "Run a coordinate flow and reshape the output as a consensus + minority report with per-provider weights. v1 uses 1.0 weights (matches a fresh provider_stats DB); future versions thread real win-rate weights when the DB layer ports.",
|
|
@@ -14366,7 +14254,6 @@ function triangulateTool(providers, allowlist, bridge, storage, breakers, transc
|
|
|
14366
14254
|
handler: (args) => runTriangulate(args, {
|
|
14367
14255
|
providers,
|
|
14368
14256
|
allowlist,
|
|
14369
|
-
...bridge ? { bridge } : {},
|
|
14370
14257
|
...storage ? { storage } : {},
|
|
14371
14258
|
...breakers ? { breakers } : {},
|
|
14372
14259
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -14374,7 +14261,7 @@ function triangulateTool(providers, allowlist, bridge, storage, breakers, transc
|
|
|
14374
14261
|
})
|
|
14375
14262
|
};
|
|
14376
14263
|
}
|
|
14377
|
-
function coordinateTool(providers, allowlist,
|
|
14264
|
+
function coordinateTool(providers, allowlist, innerCallers, storage, breakers, transcriptsDir, repoRoot, workerToolsCfg) {
|
|
14378
14265
|
return {
|
|
14379
14266
|
name: "coordinate",
|
|
14380
14267
|
description: "Run a three-role coordination flow (proposer \u2192 critics \u2192 synthesizer) with structured output at every step. Native opts: untrusted_input (canary + neutralize), worker_tools (bounded ReAct on proposer + critic roles; synth never sees inner tools), inject_session_memory (storage-backed working-memory block prepended to the topic).",
|
|
@@ -14399,7 +14286,6 @@ function coordinateTool(providers, allowlist, bridge, innerCallers, storage, bre
|
|
|
14399
14286
|
handler: (args) => runCoordinate(args, {
|
|
14400
14287
|
providers,
|
|
14401
14288
|
allowlist,
|
|
14402
|
-
...bridge ? { bridge } : {},
|
|
14403
14289
|
innerCallers,
|
|
14404
14290
|
...storage ? { storage } : {},
|
|
14405
14291
|
...breakers ? { breakers } : {},
|
|
@@ -14409,7 +14295,7 @@ function coordinateTool(providers, allowlist, bridge, innerCallers, storage, bre
|
|
|
14409
14295
|
})
|
|
14410
14296
|
};
|
|
14411
14297
|
}
|
|
14412
|
-
function debateTool(providers, allowlist,
|
|
14298
|
+
function debateTool(providers, allowlist, innerCallers, storage, pricing, breakers, transcriptsDir, repoRoot, workerToolsCfg) {
|
|
14413
14299
|
return {
|
|
14414
14300
|
name: "debate",
|
|
14415
14301
|
description: "Run a multi-round debate between LLM providers and synthesise the result via a moderator. Native opts: inject_session_memory, auto_panel, worker_tools, structured synthesis (schema-validated), extract_claims (final-round distillation), early_stop (post-round agreement check).",
|
|
@@ -14439,7 +14325,6 @@ function debateTool(providers, allowlist, bridge, innerCallers, storage, pricing
|
|
|
14439
14325
|
handler: (args) => runDebate(args, {
|
|
14440
14326
|
providers,
|
|
14441
14327
|
allowlist,
|
|
14442
|
-
...bridge ? { bridge } : {},
|
|
14443
14328
|
innerCallers,
|
|
14444
14329
|
...storage ? { storage } : {},
|
|
14445
14330
|
...pricing ? { pricing } : {},
|
|
@@ -14459,10 +14344,10 @@ function buildInnerCallers(o) {
|
|
|
14459
14344
|
...o.repoRoot ? { repoRoot: o.repoRoot } : {}
|
|
14460
14345
|
});
|
|
14461
14346
|
}
|
|
14462
|
-
out.verify = (args) => runVerify(args, o.
|
|
14347
|
+
out.verify = (args) => runVerify(args, o.fetchConfig);
|
|
14463
14348
|
return out;
|
|
14464
14349
|
}
|
|
14465
|
-
function conferTool(providers, allowlist,
|
|
14350
|
+
function conferTool(providers, allowlist, moderator, pricing, storage, innerCallers, breakers, transcriptsDir, repoRoot, workerToolsCfg) {
|
|
14466
14351
|
return {
|
|
14467
14352
|
name: "confer",
|
|
14468
14353
|
description: "Ask a panel of LLM providers the same question; return one answer per provider. Native opts: untrusted_input (canary + neutralization), early_stop (cheap-tier agreement check after first 2 panelists when N>=3), extract_claims (cheap-tier extractor with per-provider support maps), inject_session_memory (storage-backed working-memory block prepended to the first user message), auto_panel (router-driven top-N panel pick), worker_tools (bounded ReAct loop per panelist when innerCallers are wired by the host).",
|
|
@@ -14489,7 +14374,6 @@ function conferTool(providers, allowlist, bridge, moderator, pricing, storage, i
|
|
|
14489
14374
|
handler: (args) => runConfer(args, {
|
|
14490
14375
|
providers,
|
|
14491
14376
|
allowlist,
|
|
14492
|
-
...bridge ? { bridge } : {},
|
|
14493
14377
|
moderator,
|
|
14494
14378
|
...pricing ? { pricing } : {},
|
|
14495
14379
|
...storage ? { storage } : {},
|
|
@@ -14501,7 +14385,7 @@ function conferTool(providers, allowlist, bridge, moderator, pricing, storage, i
|
|
|
14501
14385
|
})
|
|
14502
14386
|
};
|
|
14503
14387
|
}
|
|
14504
|
-
function auditTool(providers, allowlist,
|
|
14388
|
+
function auditTool(providers, allowlist, transcriptsDir, pricing, storage, breakers, repoRoot) {
|
|
14505
14389
|
return {
|
|
14506
14390
|
name: "audit",
|
|
14507
14391
|
description: "Score a piece of output against an audit rubric. Single-judge by default; coalesce-mode (multi-judge consensus) and panel-exhausted self-audit run natively. cheap_mode picks the cheapest 'med'-tier model as auditor when a pricing.json is wired. session_id-only inputs load the latest transcript automatically when a transcripts directory is wired.",
|
|
@@ -14527,7 +14411,6 @@ function auditTool(providers, allowlist, bridge, transcriptsDir, pricing, storag
|
|
|
14527
14411
|
handler: (args) => runAudit(args, {
|
|
14528
14412
|
providers,
|
|
14529
14413
|
allowlist,
|
|
14530
|
-
...bridge ? { bridge } : {},
|
|
14531
14414
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
14532
14415
|
...pricing ? { pricing } : {},
|
|
14533
14416
|
...storage ? { storage } : {},
|
|
@@ -14591,7 +14474,7 @@ function pickTool(providers, allowlist, storage, breakers, transcriptsDir, repoR
|
|
|
14591
14474
|
})
|
|
14592
14475
|
};
|
|
14593
14476
|
}
|
|
14594
|
-
function verifyTool(
|
|
14477
|
+
function verifyTool(fetchConfig) {
|
|
14595
14478
|
return {
|
|
14596
14479
|
name: "verify",
|
|
14597
14480
|
description: "Run a list of deterministic property checks against caller-supplied data. No LLM calls; everything is local. Returns per-check {passed, reason} plus all_passed / summary / timing fields. Supports the text kinds (contains, not_contains, regex_match, contains_any, contains_all, min_length), shell (sandboxed subprocess with timeout + Unix pgid isolation), and url_head (HEAD request gated by fetch.url_allowlist). All kinds run natively.",
|
|
@@ -14609,7 +14492,7 @@ function verifyTool(bridge, fetchConfig) {
|
|
|
14609
14492
|
},
|
|
14610
14493
|
required: ["checks"]
|
|
14611
14494
|
},
|
|
14612
|
-
handler: (args) => runVerify(args,
|
|
14495
|
+
handler: (args) => runVerify(args, fetchConfig)
|
|
14613
14496
|
};
|
|
14614
14497
|
}
|
|
14615
14498
|
function pingTool() {
|
|
@@ -14941,10 +14824,12 @@ function canonicalEventBody(e) {
|
|
|
14941
14824
|
e.status,
|
|
14942
14825
|
e.errorClass ?? ""
|
|
14943
14826
|
].join("|");
|
|
14944
|
-
|
|
14945
|
-
|
|
14946
|
-
|
|
14947
|
-
|
|
14827
|
+
const hasV2 = e.runId !== void 0 || e.purpose !== void 0 || e.fingerprint !== void 0;
|
|
14828
|
+
const hasV3 = e.sessionId !== void 0;
|
|
14829
|
+
if (!hasV2 && !hasV3) return base;
|
|
14830
|
+
const parts = [base, e.runId ?? "", e.purpose ?? "", e.fingerprint ?? ""];
|
|
14831
|
+
if (hasV3) parts.push(e.sessionId ?? "");
|
|
14832
|
+
return parts.join("|");
|
|
14948
14833
|
}
|
|
14949
14834
|
function normalizePurpose(v) {
|
|
14950
14835
|
if (typeof v !== "string") return void 0;
|
|
@@ -15062,7 +14947,7 @@ function scheduleFlush() {
|
|
|
15062
14947
|
}, FLUSH_INTERVAL_MS);
|
|
15063
14948
|
if (typeof flushTimer.unref === "function") flushTimer.unref();
|
|
15064
14949
|
}
|
|
15065
|
-
function enqueue(cfg2, input, runId, fingerprint) {
|
|
14950
|
+
function enqueue(cfg2, input, runId, fingerprint, sessionId) {
|
|
15066
14951
|
const base = {
|
|
15067
14952
|
eventId: crypto4.randomUUID(),
|
|
15068
14953
|
seatId: cfg2.seatId,
|
|
@@ -15081,6 +14966,7 @@ function enqueue(cfg2, input, runId, fingerprint) {
|
|
|
15081
14966
|
// omitting keeps the JSON honest about what we actually know.
|
|
15082
14967
|
...input.errorClass === void 0 ? {} : { errorClass: input.errorClass },
|
|
15083
14968
|
runId,
|
|
14969
|
+
sessionId,
|
|
15084
14970
|
// Omit entirely (not "") when unknown, so the canonical body stays
|
|
15085
14971
|
// consistent with what the server reconstructs from the JSON.
|
|
15086
14972
|
...input.purpose === void 0 ? {} : { purpose: input.purpose },
|
|
@@ -15095,15 +14981,23 @@ function enqueue(cfg2, input, runId, fingerprint) {
|
|
|
15095
14981
|
if (queue.length >= FLUSH_BATCH_AT) void flush();
|
|
15096
14982
|
else scheduleFlush();
|
|
15097
14983
|
}
|
|
14984
|
+
function sessionIdFromEnvelope(out) {
|
|
14985
|
+
if (!out || typeof out !== "object") return null;
|
|
14986
|
+
const rs = out["run_summary"];
|
|
14987
|
+
if (!rs || typeof rs !== "object") return null;
|
|
14988
|
+
const v = rs["session_id"];
|
|
14989
|
+
return typeof v === "string" && v.trim().length > 0 ? v : null;
|
|
14990
|
+
}
|
|
15098
14991
|
function recordUsage(out, toolName) {
|
|
15099
14992
|
try {
|
|
15100
14993
|
const cfg2 = getConfig2();
|
|
15101
14994
|
if (!cfg2) return;
|
|
15102
14995
|
if (toolName === "update_crosscheck") return;
|
|
15103
14996
|
const runId = crypto4.randomUUID();
|
|
14997
|
+
const sessionId = resolveSessionId(sessionIdFromEnvelope(out));
|
|
15104
14998
|
const fingerprint = currentFingerprint();
|
|
15105
14999
|
for (const ev of usageEventsFromEnvelope(out, toolName)) {
|
|
15106
|
-
enqueue(cfg2, ev, runId, fingerprint);
|
|
15000
|
+
enqueue(cfg2, ev, runId, fingerprint, sessionId);
|
|
15107
15001
|
}
|
|
15108
15002
|
} catch {
|
|
15109
15003
|
}
|
|
@@ -15210,7 +15104,7 @@ function createServer(opts = {}) {
|
|
|
15210
15104
|
throw new Error(`unknown tool: ${name}`);
|
|
15211
15105
|
}
|
|
15212
15106
|
const args = req.params.arguments ?? {};
|
|
15213
|
-
const
|
|
15107
|
+
const startedAt2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
15214
15108
|
const startedHr = process.hrtime.bigint();
|
|
15215
15109
|
const id = nextEventId();
|
|
15216
15110
|
syncSegment(opts.repoRoot);
|
|
@@ -15224,7 +15118,7 @@ function createServer(opts = {}) {
|
|
|
15224
15118
|
event: "tool_invoke",
|
|
15225
15119
|
id,
|
|
15226
15120
|
tool: name,
|
|
15227
|
-
started_at:
|
|
15121
|
+
started_at: startedAt2,
|
|
15228
15122
|
duration_ms: 0,
|
|
15229
15123
|
status: "ok",
|
|
15230
15124
|
args_keys: topLevelKeys(args),
|
|
@@ -15258,7 +15152,7 @@ function createServer(opts = {}) {
|
|
|
15258
15152
|
event: "tool_invoke",
|
|
15259
15153
|
id,
|
|
15260
15154
|
tool: name,
|
|
15261
|
-
started_at:
|
|
15155
|
+
started_at: startedAt2,
|
|
15262
15156
|
duration_ms: durationMs,
|
|
15263
15157
|
status: "ok",
|
|
15264
15158
|
args_keys: topLevelKeys(args),
|
|
@@ -15280,7 +15174,7 @@ function createServer(opts = {}) {
|
|
|
15280
15174
|
event: "tool_invoke",
|
|
15281
15175
|
id,
|
|
15282
15176
|
tool: name,
|
|
15283
|
-
started_at:
|
|
15177
|
+
started_at: startedAt2,
|
|
15284
15178
|
duration_ms: durationMs,
|
|
15285
15179
|
status: "error",
|
|
15286
15180
|
args_keys: topLevelKeys(args),
|
|
@@ -15311,7 +15205,6 @@ async function connectAndServe(transport, opts = {}) {
|
|
|
15311
15205
|
}
|
|
15312
15206
|
function buildToolRegistry(opts) {
|
|
15313
15207
|
const registerOpts = {};
|
|
15314
|
-
if (opts.bridge) registerOpts.bridge = opts.bridge;
|
|
15315
15208
|
if (opts.providers) registerOpts.providers = opts.providers;
|
|
15316
15209
|
if (opts.providerAllowlist !== void 0)
|
|
15317
15210
|
registerOpts.providerAllowlist = opts.providerAllowlist;
|
|
@@ -15328,13 +15221,7 @@ function buildToolRegistry(opts) {
|
|
|
15328
15221
|
if (opts.moderatorDefault) registerOpts.moderatorDefault = opts.moderatorDefault;
|
|
15329
15222
|
if (opts.benchGoldensDir) registerOpts.benchGoldensDir = opts.benchGoldensDir;
|
|
15330
15223
|
if (opts.eventsPath) registerOpts.eventsPath = opts.eventsPath;
|
|
15331
|
-
|
|
15332
|
-
if (!opts.bridge) return tools;
|
|
15333
|
-
const proxies = buildPythonProxies(opts.bridge);
|
|
15334
|
-
for (const [name, proxy] of proxies) {
|
|
15335
|
-
if (!tools.has(name)) tools.set(name, proxy);
|
|
15336
|
-
}
|
|
15337
|
-
return tools;
|
|
15224
|
+
return registerCoreTools(registerOpts);
|
|
15338
15225
|
}
|
|
15339
15226
|
|
|
15340
15227
|
// src/core/config-file.ts
|
|
@@ -15509,14 +15396,39 @@ function loadConfigFile(opts) {
|
|
|
15509
15396
|
return mapConfig(obj, file);
|
|
15510
15397
|
}
|
|
15511
15398
|
|
|
15399
|
+
// src/core/process-registry.ts
|
|
15400
|
+
init_esm_shims();
|
|
15401
|
+
import { mkdirSync as mkdirSync10, readdirSync as readdirSync5, readFileSync as readFileSync16, rmSync, writeFileSync as writeFileSync9 } from "fs";
|
|
15402
|
+
import os2 from "os";
|
|
15403
|
+
import path15 from "path";
|
|
15404
|
+
function registryDir(env = process.env) {
|
|
15405
|
+
const base = env["CROSSCHECK_DATA_DIR"] || path15.join(env["HOME"] ?? env["USERPROFILE"] ?? os2.homedir(), ".crosscheck");
|
|
15406
|
+
return path15.join(base, "procs");
|
|
15407
|
+
}
|
|
15408
|
+
function registerProcess(rec, env = process.env) {
|
|
15409
|
+
try {
|
|
15410
|
+
const dir = registryDir(env);
|
|
15411
|
+
mkdirSync10(dir, { recursive: true, mode: 448 });
|
|
15412
|
+
writeFileSync9(path15.join(dir, `${rec.pid}.json`), JSON.stringify(rec), { mode: 384 });
|
|
15413
|
+
} catch {
|
|
15414
|
+
}
|
|
15415
|
+
}
|
|
15416
|
+
function unregisterProcess(pid = process.pid, env = process.env) {
|
|
15417
|
+
try {
|
|
15418
|
+
rmSync(path15.join(registryDir(env), `${pid}.json`), { force: true });
|
|
15419
|
+
} catch {
|
|
15420
|
+
}
|
|
15421
|
+
}
|
|
15422
|
+
|
|
15512
15423
|
// src/entrypoints/node-stdio.ts
|
|
15424
|
+
var HERE = typeof __dirname !== "undefined" ? __dirname : path16.dirname(fileURLToPath3(import.meta.url));
|
|
15513
15425
|
var SHUTDOWN_TIMEOUT_MS = 2e3;
|
|
15514
15426
|
async function main() {
|
|
15515
15427
|
enforceLicenseOrExit();
|
|
15516
|
-
const cfgDataDir = process.env["CROSSCHECK_DATA_DIR"] ||
|
|
15428
|
+
const cfgDataDir = process.env["CROSSCHECK_DATA_DIR"] || path16.join(process.env["HOME"] ?? process.env["USERPROFILE"] ?? "", ".crosscheck");
|
|
15517
15429
|
const configFile = loadConfigFile({
|
|
15518
15430
|
startDir: process.cwd(),
|
|
15519
|
-
repoRoot: findGitRoot(
|
|
15431
|
+
repoRoot: findGitRoot(HERE),
|
|
15520
15432
|
dataDir: cfgDataDir
|
|
15521
15433
|
});
|
|
15522
15434
|
if (configFile) {
|
|
@@ -15530,15 +15442,17 @@ async function main() {
|
|
|
15530
15442
|
`);
|
|
15531
15443
|
}
|
|
15532
15444
|
setEventEmitter(buildDefaultEmitter(process.env));
|
|
15533
|
-
if (process.env["CROSSCHECK_BRIDGE_PYTHON"] === "1") {
|
|
15534
|
-
process.stderr.write(
|
|
15535
|
-
"crosscheck-agent: CROSSCHECK_BRIDGE_PYTHON is deprecated and ignored \u2014 the engine is native-only.\n"
|
|
15536
|
-
);
|
|
15537
|
-
}
|
|
15538
15445
|
installShutdownHandlers();
|
|
15446
|
+
registerProcess({
|
|
15447
|
+
pid: process.pid,
|
|
15448
|
+
version: SERVER_VERSION,
|
|
15449
|
+
startedAt: Date.now(),
|
|
15450
|
+
ppid: process.ppid,
|
|
15451
|
+
sessionId: engineSessionId()
|
|
15452
|
+
});
|
|
15539
15453
|
const bundledPricing = (() => {
|
|
15540
15454
|
try {
|
|
15541
|
-
return
|
|
15455
|
+
return path16.join(path16.dirname(fileURLToPath3(import.meta.url)), "pricing.json");
|
|
15542
15456
|
} catch {
|
|
15543
15457
|
return void 0;
|
|
15544
15458
|
}
|
|
@@ -15565,10 +15479,10 @@ async function main() {
|
|
|
15565
15479
|
}
|
|
15566
15480
|
let storage;
|
|
15567
15481
|
if (process.env["CROSSCHECK_DB_DISABLED"] !== "1") {
|
|
15568
|
-
const dbPath = process.env["CROSSCHECK_DB_PATH"] ?? resolveRepoFile(".crosscheck/db.sqlite") ??
|
|
15482
|
+
const dbPath = process.env["CROSSCHECK_DB_PATH"] ?? resolveRepoFile(".crosscheck/db.sqlite") ?? path16.join(cfgDataDir, "db.sqlite");
|
|
15569
15483
|
if (dbPath) {
|
|
15570
15484
|
try {
|
|
15571
|
-
|
|
15485
|
+
mkdirSync11(path16.dirname(dbPath), { recursive: true });
|
|
15572
15486
|
const { openBetterSqliteStorage: openBetterSqliteStorage2 } = await Promise.resolve().then(() => (init_better_sqlite3(), better_sqlite3_exports));
|
|
15573
15487
|
storage = openBetterSqliteStorage2({ path: dbPath });
|
|
15574
15488
|
await storage.migrate();
|
|
@@ -15586,7 +15500,7 @@ async function main() {
|
|
|
15586
15500
|
}
|
|
15587
15501
|
}
|
|
15588
15502
|
const transcriptsDir = configFile?.logTranscripts === false ? void 0 : process.env["CROSSCHECK_TRANSCRIPTS_DIR"] ?? configFile?.transcriptsDir ?? resolveRepoFile(".crosscheck/transcripts");
|
|
15589
|
-
const repoRoot = process.env["CROSSCHECK_REPO_ROOT"] ?? findGitRoot(
|
|
15503
|
+
const repoRoot = process.env["CROSSCHECK_REPO_ROOT"] ?? findGitRoot(HERE);
|
|
15590
15504
|
const transport = new StdioServerTransport();
|
|
15591
15505
|
const serverOpts = { providers };
|
|
15592
15506
|
if (storage) serverOpts.storage = storage;
|
|
@@ -15616,6 +15530,7 @@ function installShutdownHandlers() {
|
|
|
15616
15530
|
new Promise((resolve2) => setTimeout(resolve2, SHUTDOWN_TIMEOUT_MS))
|
|
15617
15531
|
]).catch(() => {
|
|
15618
15532
|
});
|
|
15533
|
+
unregisterProcess();
|
|
15619
15534
|
process.stderr.write(`crosscheck-agent: shutdown (${reason})
|
|
15620
15535
|
`);
|
|
15621
15536
|
process.exit(0);
|
|
@@ -15634,11 +15549,11 @@ function installShutdownHandlers() {
|
|
|
15634
15549
|
});
|
|
15635
15550
|
}
|
|
15636
15551
|
function resolveRepoFile(rel) {
|
|
15637
|
-
let dir =
|
|
15552
|
+
let dir = HERE;
|
|
15638
15553
|
for (let i = 0; i < 8; i++) {
|
|
15639
|
-
const candidate =
|
|
15554
|
+
const candidate = path16.join(dir, rel);
|
|
15640
15555
|
if (existsSync14(candidate)) return candidate;
|
|
15641
|
-
const parent =
|
|
15556
|
+
const parent = path16.dirname(dir);
|
|
15642
15557
|
if (parent === dir) break;
|
|
15643
15558
|
dir = parent;
|
|
15644
15559
|
}
|
|
@@ -15647,8 +15562,8 @@ function resolveRepoFile(rel) {
|
|
|
15647
15562
|
function findGitRoot(startDir) {
|
|
15648
15563
|
let dir = startDir;
|
|
15649
15564
|
for (let i = 0; i < 12; i++) {
|
|
15650
|
-
if (existsSync14(
|
|
15651
|
-
const parent =
|
|
15565
|
+
if (existsSync14(path16.join(dir, ".git"))) return dir;
|
|
15566
|
+
const parent = path16.dirname(dir);
|
|
15652
15567
|
if (parent === dir) break;
|
|
15653
15568
|
dir = parent;
|
|
15654
15569
|
}
|
|
@@ -15658,7 +15573,7 @@ var isMainEntry = (() => {
|
|
|
15658
15573
|
try {
|
|
15659
15574
|
const argv1 = process.argv[1];
|
|
15660
15575
|
if (!argv1) return false;
|
|
15661
|
-
return /(?:\/|\\)node-stdio\.(?:js|cjs|mjs)$/.test(argv1);
|
|
15576
|
+
return /(?:\/|\\)node-stdio\.(?:js|cjs|mjs|ts)$/.test(argv1);
|
|
15662
15577
|
} catch {
|
|
15663
15578
|
return false;
|
|
15664
15579
|
}
|