crosscheck-mcp 0.2.27 → 0.2.29
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 +386 -360
- package/dist/browser-ext.cjs.map +1 -1
- package/dist/browser-ext.js +371 -345
- package/dist/browser-ext.js.map +1 -1
- package/dist/embed.cjs +635 -381
- package/dist/embed.cjs.map +1 -1
- package/dist/embed.d.cts +151 -2
- package/dist/embed.d.ts +151 -2
- package/dist/embed.js +612 -362
- package/dist/embed.js.map +1 -1
- package/dist/node-stdio.cjs +453 -473
- package/dist/node-stdio.cjs.map +1 -1
- package/dist/node-stdio.d.cts +12 -122
- package/dist/node-stdio.d.ts +12 -122
- package/dist/node-stdio.js +424 -444
- package/dist/node-stdio.js.map +1 -1
- package/dist/pricing.json +47 -9
- package/dist/self-check.cjs.map +1 -1
- package/dist/self-check.js.map +1 -1
- package/dist/types-BcprisDl.d.cts +76 -0
- package/dist/types-BcprisDl.d.ts +76 -0
- package/package.json +7 -2
package/dist/node-stdio.cjs
CHANGED
|
@@ -958,8 +958,8 @@ __export(node_stdio_exports, {
|
|
|
958
958
|
});
|
|
959
959
|
module.exports = __toCommonJS(node_stdio_exports);
|
|
960
960
|
init_cjs_shims();
|
|
961
|
-
var
|
|
962
|
-
var
|
|
961
|
+
var import_node_fs20 = require("fs");
|
|
962
|
+
var import_node_path19 = __toESM(require("path"), 1);
|
|
963
963
|
var import_node_url2 = require("url");
|
|
964
964
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
965
965
|
|
|
@@ -976,10 +976,10 @@ var StderrEmitter = class {
|
|
|
976
976
|
}
|
|
977
977
|
};
|
|
978
978
|
var FileEmitter = class {
|
|
979
|
-
constructor(
|
|
980
|
-
this.path =
|
|
979
|
+
constructor(path16) {
|
|
980
|
+
this.path = path16;
|
|
981
981
|
try {
|
|
982
|
-
(0, import_node_fs.mkdirSync)((0, import_node_path.dirname)(
|
|
982
|
+
(0, import_node_fs.mkdirSync)((0, import_node_path.dirname)(path16), { recursive: true });
|
|
983
983
|
} catch {
|
|
984
984
|
}
|
|
985
985
|
}
|
|
@@ -1012,13 +1012,13 @@ var NullEmitter = class {
|
|
|
1012
1012
|
function buildDefaultEmitter(env) {
|
|
1013
1013
|
const mode = (env["CROSSCHECK_EVENTS"] ?? "stderr").toLowerCase();
|
|
1014
1014
|
if (mode === "off") return new NullEmitter();
|
|
1015
|
-
const
|
|
1015
|
+
const path16 = env["CROSSCHECK_EVENTS_PATH"];
|
|
1016
1016
|
if (mode === "file") {
|
|
1017
|
-
return
|
|
1017
|
+
return path16 ? new FileEmitter(path16) : new NullEmitter();
|
|
1018
1018
|
}
|
|
1019
1019
|
if (mode === "both") {
|
|
1020
1020
|
const ems = [new StderrEmitter()];
|
|
1021
|
-
if (
|
|
1021
|
+
if (path16) ems.push(new FileEmitter(path16));
|
|
1022
1022
|
return new TeeEmitter(ems);
|
|
1023
1023
|
}
|
|
1024
1024
|
return new StderrEmitter();
|
|
@@ -1067,10 +1067,10 @@ function envelopeBytes(v) {
|
|
|
1067
1067
|
// src/core/pricing.ts
|
|
1068
1068
|
init_cjs_shims();
|
|
1069
1069
|
var import_node_fs2 = require("fs");
|
|
1070
|
-
function loadPricing(
|
|
1070
|
+
function loadPricing(path16) {
|
|
1071
1071
|
let raw;
|
|
1072
1072
|
try {
|
|
1073
|
-
raw = (0, import_node_fs2.readFileSync)(
|
|
1073
|
+
raw = (0, import_node_fs2.readFileSync)(path16, "utf8");
|
|
1074
1074
|
} catch {
|
|
1075
1075
|
return {};
|
|
1076
1076
|
}
|
|
@@ -1087,20 +1087,30 @@ function modelPricing(pricing, provider, model) {
|
|
|
1087
1087
|
const block = pricing[provider];
|
|
1088
1088
|
if (!block || typeof block !== "object" || Array.isArray(block)) return null;
|
|
1089
1089
|
const table = block;
|
|
1090
|
+
if (model.startsWith("_")) return null;
|
|
1090
1091
|
let entry = table[model];
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1092
|
+
let match = "exact";
|
|
1093
|
+
if (!isRates(entry)) {
|
|
1094
|
+
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];
|
|
1095
|
+
if (best !== void 0) {
|
|
1096
|
+
entry = table[best];
|
|
1097
|
+
match = "stamp";
|
|
1098
|
+
}
|
|
1094
1099
|
}
|
|
1095
|
-
if (!
|
|
1100
|
+
if (!isRates(entry)) return null;
|
|
1096
1101
|
const e = entry;
|
|
1097
1102
|
return {
|
|
1098
1103
|
prompt_per_1k: numberOrZero(e["prompt_per_1k"]),
|
|
1099
1104
|
completion_per_1k: numberOrZero(e["completion_per_1k"]),
|
|
1100
1105
|
cached_per_1k: numberOrZero(e["cached_per_1k"]),
|
|
1101
|
-
...e["estimated"] === true ? { estimated: true } : {}
|
|
1106
|
+
...e["estimated"] === true ? { estimated: true } : {},
|
|
1107
|
+
match
|
|
1102
1108
|
};
|
|
1103
1109
|
}
|
|
1110
|
+
var DATE_STAMP = /^-\d{8}$/;
|
|
1111
|
+
function isRates(v) {
|
|
1112
|
+
return Boolean(v) && typeof v === "object" && !Array.isArray(v);
|
|
1113
|
+
}
|
|
1104
1114
|
function numberOrZero(v) {
|
|
1105
1115
|
if (typeof v === "number" && Number.isFinite(v)) return v;
|
|
1106
1116
|
if (typeof v === "string") {
|
|
@@ -1240,8 +1250,20 @@ var PROVIDER_CAPS = {
|
|
|
1240
1250
|
gemini: {
|
|
1241
1251
|
family: "gemini",
|
|
1242
1252
|
system_role: "separate",
|
|
1243
|
-
|
|
1244
|
-
|
|
1253
|
+
// No sampling, on any Gemini model. Ignored since 3.6 Flash and rejected
|
|
1254
|
+
// by upcoming models (Google, 2026-10). "model" means "omit for reasoning
|
|
1255
|
+
// models", and every Gemini model is reasoning-class (below) — so this
|
|
1256
|
+
// resolves to never, through the same rule the other providers use. The
|
|
1257
|
+
// adapter also never sends it; this keeps the record honest for anything
|
|
1258
|
+
// else that reads it.
|
|
1259
|
+
supports_temperature: "model",
|
|
1260
|
+
// EVERY Gemini model is reasoning-class. The old list named three
|
|
1261
|
+
// families and missed gemini-3.8-flash — the DEFAULT — so the default
|
|
1262
|
+
// model got the small non-reasoning budgets (768 tokens for an audit)
|
|
1263
|
+
// while spending up to ~480 tokens of each call thinking. Google's docs
|
|
1264
|
+
// say thinking cannot be switched off on current models, so a list of
|
|
1265
|
+
// which ones think is a list that can only ever be incomplete.
|
|
1266
|
+
reasoning_prefixes: ["gemini-"]
|
|
1245
1267
|
},
|
|
1246
1268
|
// Qwen's "Max" tier (qwen-v3.8, qwen-v3.7) is a standard instruct/chat
|
|
1247
1269
|
// model, not a visible-reasoning model like QwQ — normal temperature and
|
|
@@ -1366,6 +1388,74 @@ function httpFailureToProviderError(provider, status, bodyText, retryAfterS, mod
|
|
|
1366
1388
|
);
|
|
1367
1389
|
}
|
|
1368
1390
|
|
|
1391
|
+
// src/providers/network-errors.ts
|
|
1392
|
+
init_cjs_shims();
|
|
1393
|
+
function codeOf(e) {
|
|
1394
|
+
if (!e || typeof e !== "object") return null;
|
|
1395
|
+
const c = e.code;
|
|
1396
|
+
return typeof c === "string" && c.length > 0 ? c : null;
|
|
1397
|
+
}
|
|
1398
|
+
function rootCause(e, depth = 0) {
|
|
1399
|
+
if (depth > 5 || !e || typeof e !== "object") return e;
|
|
1400
|
+
const o = e;
|
|
1401
|
+
if (Array.isArray(o.errors) && o.errors.length > 0) {
|
|
1402
|
+
const coded = o.errors.find((x) => codeOf(x) !== null);
|
|
1403
|
+
return rootCause(coded ?? o.errors[0], depth + 1);
|
|
1404
|
+
}
|
|
1405
|
+
if (o.cause !== void 0 && o.cause !== null) return rootCause(o.cause, depth + 1);
|
|
1406
|
+
return e;
|
|
1407
|
+
}
|
|
1408
|
+
var BY_CODE = {
|
|
1409
|
+
ENOTFOUND: { cause: "dns", detail: "the provider's hostname did not resolve \u2014 DNS, or a typo'd base URL", transient: false, kind: "network" },
|
|
1410
|
+
EAI_AGAIN: { cause: "dns", detail: "DNS lookup failed temporarily \u2014 resolver or network is flapping", transient: true, kind: "network" },
|
|
1411
|
+
ECONNREFUSED: { cause: "refused", detail: "the connection was refused \u2014 nothing is listening, or a proxy blocked it", transient: false, kind: "network" },
|
|
1412
|
+
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" },
|
|
1413
|
+
EPIPE: { cause: "reset", detail: "the connection closed while we were still writing", transient: true, kind: "network" },
|
|
1414
|
+
ETIMEDOUT: { cause: "connect_timeout", detail: "the connection timed out before it was established", transient: true, kind: "timeout" },
|
|
1415
|
+
EHOSTUNREACH: { cause: "unreachable", detail: "no route to the provider \u2014 VPN, or offline", transient: true, kind: "network" },
|
|
1416
|
+
ENETUNREACH: { cause: "unreachable", detail: "the network is unreachable \u2014 offline, or a routing change", transient: true, kind: "network" },
|
|
1417
|
+
ENETDOWN: { cause: "unreachable", detail: "the local network is down", transient: true, kind: "network" },
|
|
1418
|
+
EPROTO: { cause: "tls", detail: "the TLS handshake failed \u2014 an intercepting proxy, or a protocol mismatch", transient: false, kind: "network" },
|
|
1419
|
+
ERR_TLS_CERT_ALTNAME_INVALID: { cause: "tls", detail: "the certificate did not match the hostname \u2014 traffic is being intercepted", transient: false, kind: "network" },
|
|
1420
|
+
CERT_HAS_EXPIRED: { cause: "tls", detail: "the server certificate has expired, or this machine's clock is wrong", transient: false, kind: "network" },
|
|
1421
|
+
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" },
|
|
1422
|
+
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" },
|
|
1423
|
+
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" },
|
|
1424
|
+
UND_ERR_BODY_TIMEOUT: { cause: "read_timeout", detail: "the response body stalled mid-stream", transient: true, kind: "timeout" },
|
|
1425
|
+
UND_ERR_SOCKET: { cause: "reset", detail: "the socket closed unexpectedly", transient: true, kind: "network" },
|
|
1426
|
+
UND_ERR_ABORTED: { cause: "aborted", detail: "the request was cancelled", transient: false, kind: "network" },
|
|
1427
|
+
ABORT_ERR: { cause: "aborted", detail: "the request was cancelled", transient: false, kind: "network" }
|
|
1428
|
+
};
|
|
1429
|
+
function diagnoseNetworkError(e) {
|
|
1430
|
+
const root = rootCause(e);
|
|
1431
|
+
const code = codeOf(root) ?? codeOf(e);
|
|
1432
|
+
if (code && BY_CODE[code]) return { ...BY_CODE[code], code };
|
|
1433
|
+
const name = root && typeof root === "object" ? root.name : void 0;
|
|
1434
|
+
if (name === "AbortError" || name === "TimeoutError") {
|
|
1435
|
+
return {
|
|
1436
|
+
cause: name === "TimeoutError" ? "read_timeout" : "aborted",
|
|
1437
|
+
code: code ?? String(name),
|
|
1438
|
+
detail: name === "TimeoutError" ? "the request exceeded its timeout" : "the request was cancelled",
|
|
1439
|
+
transient: name === "TimeoutError",
|
|
1440
|
+
kind: name === "TimeoutError" ? "timeout" : "network"
|
|
1441
|
+
};
|
|
1442
|
+
}
|
|
1443
|
+
return {
|
|
1444
|
+
cause: "unknown",
|
|
1445
|
+
code,
|
|
1446
|
+
detail: code ? `the connection failed with ${code}` : "the connection failed and the underlying error carried no code",
|
|
1447
|
+
transient: true,
|
|
1448
|
+
kind: "network"
|
|
1449
|
+
};
|
|
1450
|
+
}
|
|
1451
|
+
function looksLikeNetworkFailure(d) {
|
|
1452
|
+
return d.code !== null || d.cause !== "unknown";
|
|
1453
|
+
}
|
|
1454
|
+
function networkErrorMessage(provider, d) {
|
|
1455
|
+
const code = d.code ? ` [${d.code}]` : "";
|
|
1456
|
+
return `${provider}: ${d.detail}${code}`;
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1369
1459
|
// src/providers/retry.ts
|
|
1370
1460
|
init_cjs_shims();
|
|
1371
1461
|
var override = null;
|
|
@@ -1527,6 +1617,52 @@ function rejectsDisabledThinking(model) {
|
|
|
1527
1617
|
const m = model.toLowerCase();
|
|
1528
1618
|
return ADAPTIVE_THINKING_PREFIXES.some((p) => m.startsWith(p));
|
|
1529
1619
|
}
|
|
1620
|
+
var NO_FORCED_TOOL_PREFIXES = [
|
|
1621
|
+
"claude-fable-5-1",
|
|
1622
|
+
"claude-mythos-5-1",
|
|
1623
|
+
"claude-opus-5-5",
|
|
1624
|
+
"claude-sonnet-5-5"
|
|
1625
|
+
];
|
|
1626
|
+
function rejectsForcedToolUse(model) {
|
|
1627
|
+
const m = model.toLowerCase();
|
|
1628
|
+
return NO_FORCED_TOOL_PREFIXES.some((p) => m.startsWith(p));
|
|
1629
|
+
}
|
|
1630
|
+
var UNSUPPORTED_SCHEMA_KEYS = /* @__PURE__ */ new Set([
|
|
1631
|
+
"minimum",
|
|
1632
|
+
"maximum",
|
|
1633
|
+
"exclusiveMinimum",
|
|
1634
|
+
"exclusiveMaximum",
|
|
1635
|
+
"multipleOf",
|
|
1636
|
+
"minLength",
|
|
1637
|
+
"maxLength",
|
|
1638
|
+
"pattern",
|
|
1639
|
+
"minItems",
|
|
1640
|
+
"maxItems",
|
|
1641
|
+
"uniqueItems",
|
|
1642
|
+
"minProperties",
|
|
1643
|
+
"maxProperties",
|
|
1644
|
+
"$schema"
|
|
1645
|
+
]);
|
|
1646
|
+
function toStructuredOutputSchema(schema) {
|
|
1647
|
+
const walk = (node) => {
|
|
1648
|
+
if (Array.isArray(node)) return node.map(walk);
|
|
1649
|
+
if (!node || typeof node !== "object") return node;
|
|
1650
|
+
const out = {};
|
|
1651
|
+
for (const [k, v] of Object.entries(node)) {
|
|
1652
|
+
if (UNSUPPORTED_SCHEMA_KEYS.has(k)) continue;
|
|
1653
|
+
if (k === "properties" && v && typeof v === "object") {
|
|
1654
|
+
out[k] = Object.fromEntries(Object.entries(v).map(([pk, pv]) => [pk, walk(pv)]));
|
|
1655
|
+
} else if (["items", "anyOf", "allOf", "oneOf", "not", "$defs", "definitions"].includes(k)) {
|
|
1656
|
+
out[k] = k === "$defs" || k === "definitions" ? Object.fromEntries(Object.entries(v ?? {}).map(([dk, dv]) => [dk, walk(dv)])) : walk(v);
|
|
1657
|
+
} else {
|
|
1658
|
+
out[k] = v;
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1661
|
+
if (out["type"] === "object" || "properties" in out) out["additionalProperties"] = false;
|
|
1662
|
+
return out;
|
|
1663
|
+
};
|
|
1664
|
+
return walk(schema);
|
|
1665
|
+
}
|
|
1530
1666
|
var ANTHROPIC_STRUCTURED_TOOL_NAME = "structured_output";
|
|
1531
1667
|
function applyPromptCaching(body, env = process.env) {
|
|
1532
1668
|
const flag = (env["CROSSCHECK_ANTHROPIC_PROMPT_CACHE"] ?? "").trim();
|
|
@@ -1578,7 +1714,12 @@ function buildAnthropicRequest(opts) {
|
|
|
1578
1714
|
body.thinking = { type: "disabled" };
|
|
1579
1715
|
}
|
|
1580
1716
|
}
|
|
1581
|
-
if (opts.jsonSchema) {
|
|
1717
|
+
if (opts.jsonSchema && rejectsForcedToolUse(opts.model)) {
|
|
1718
|
+
body.output_config = {
|
|
1719
|
+
...body.output_config ?? {},
|
|
1720
|
+
format: { type: "json_schema", schema: toStructuredOutputSchema(opts.jsonSchema) }
|
|
1721
|
+
};
|
|
1722
|
+
} else if (opts.jsonSchema) {
|
|
1582
1723
|
body.tools = [{
|
|
1583
1724
|
name: ANTHROPIC_STRUCTURED_TOOL_NAME,
|
|
1584
1725
|
description: "Emit a single JSON object matching the requested schema.",
|
|
@@ -1697,7 +1838,11 @@ async function sendAnthropic(args) {
|
|
|
1697
1838
|
try {
|
|
1698
1839
|
respLike = await doFetch(url, init);
|
|
1699
1840
|
} catch (e) {
|
|
1700
|
-
|
|
1841
|
+
const d = diagnoseNetworkError(e);
|
|
1842
|
+
if (!looksLikeNetworkFailure(d)) throw e;
|
|
1843
|
+
throw new ProviderError(d.kind, networkErrorMessage("anthropic", d), {
|
|
1844
|
+
transient: d.transient
|
|
1845
|
+
});
|
|
1701
1846
|
}
|
|
1702
1847
|
const status = respLike.status;
|
|
1703
1848
|
if (status >= 200 && status < 300) {
|
|
@@ -1771,6 +1916,11 @@ function jsonSchemaToGeminiSchema(schema) {
|
|
|
1771
1916
|
}
|
|
1772
1917
|
return out;
|
|
1773
1918
|
}
|
|
1919
|
+
var GEMINI_THINKING_HEADROOM_TOKENS = 16384;
|
|
1920
|
+
function thinkingHeadroom() {
|
|
1921
|
+
const raw = Number(process.env["CROSSCHECK_GEMINI_THINKING_HEADROOM_TOKENS"]);
|
|
1922
|
+
return Number.isFinite(raw) && raw >= 0 ? Math.trunc(raw) : GEMINI_THINKING_HEADROOM_TOKENS;
|
|
1923
|
+
}
|
|
1774
1924
|
function buildGeminiRequest(opts) {
|
|
1775
1925
|
const contents = [];
|
|
1776
1926
|
let systemText = null;
|
|
@@ -1789,8 +1939,9 @@ function buildGeminiRequest(opts) {
|
|
|
1789
1939
|
const body = {
|
|
1790
1940
|
contents,
|
|
1791
1941
|
generationConfig: {
|
|
1792
|
-
|
|
1793
|
-
|
|
1942
|
+
// Answer budget + thinking headroom. No temperature / topP / topK /
|
|
1943
|
+
// thinkingBudget, on any model — see the header note.
|
|
1944
|
+
maxOutputTokens: opts.maxTokens + thinkingHeadroom()
|
|
1794
1945
|
}
|
|
1795
1946
|
};
|
|
1796
1947
|
if (systemText !== null && systemText !== "") {
|
|
@@ -1800,8 +1951,8 @@ function buildGeminiRequest(opts) {
|
|
|
1800
1951
|
body.generationConfig.responseMimeType = "application/json";
|
|
1801
1952
|
body.generationConfig.responseSchema = jsonSchemaToGeminiSchema(opts.jsonSchema);
|
|
1802
1953
|
}
|
|
1803
|
-
const url = `${GEMINI_API_URL_BASE}/${encodeURIComponent(opts.model)}:generateContent
|
|
1804
|
-
return { url, headers: {}, body };
|
|
1954
|
+
const url = `${GEMINI_API_URL_BASE}/${encodeURIComponent(opts.model)}:generateContent`;
|
|
1955
|
+
return { url, headers: { "x-goog-api-key": opts.apiKey }, body };
|
|
1805
1956
|
}
|
|
1806
1957
|
function parseGeminiResponse(opts) {
|
|
1807
1958
|
const r = opts.resp ?? {};
|
|
@@ -1831,16 +1982,19 @@ function parseGeminiResponse(opts) {
|
|
|
1831
1982
|
}
|
|
1832
1983
|
try {
|
|
1833
1984
|
const first = cands[0];
|
|
1834
|
-
const
|
|
1835
|
-
const
|
|
1985
|
+
const finishReason = typeof first["finishReason"] === "string" ? first["finishReason"] : void 0;
|
|
1986
|
+
const content = first["content"] ?? {};
|
|
1987
|
+
const parts = Array.isArray(content["parts"]) ? content["parts"] : [];
|
|
1836
1988
|
let text = "";
|
|
1837
1989
|
for (const p of parts) {
|
|
1838
1990
|
if (p && typeof p === "object") {
|
|
1839
|
-
const
|
|
1991
|
+
const part = p;
|
|
1992
|
+
if (part["thought"] === true) continue;
|
|
1993
|
+
const t = part["text"];
|
|
1840
1994
|
if (typeof t === "string") text += t;
|
|
1841
1995
|
}
|
|
1842
1996
|
}
|
|
1843
|
-
return { text, usage };
|
|
1997
|
+
return { text, usage, ...finishReason ? { finishReason } : {} };
|
|
1844
1998
|
} catch (e) {
|
|
1845
1999
|
throw new ProviderError(
|
|
1846
2000
|
"parse",
|
|
@@ -1869,7 +2023,8 @@ async function sendGemini(args) {
|
|
|
1869
2023
|
apiKey: args.apiKey,
|
|
1870
2024
|
messages: args.messages,
|
|
1871
2025
|
maxTokens: args.maxTokens,
|
|
1872
|
-
|
|
2026
|
+
// args.temperature is deliberately NOT forwarded: Gemini ignores it and
|
|
2027
|
+
// upcoming models reject it. See the header note.
|
|
1873
2028
|
...args.jsonSchema ? { jsonSchema: args.jsonSchema } : {}
|
|
1874
2029
|
});
|
|
1875
2030
|
const doFetch = args.fetchImpl ?? globalThis.fetch;
|
|
@@ -1884,7 +2039,11 @@ async function sendGemini(args) {
|
|
|
1884
2039
|
try {
|
|
1885
2040
|
respLike = await doFetch(url, init);
|
|
1886
2041
|
} catch (e) {
|
|
1887
|
-
|
|
2042
|
+
const d = diagnoseNetworkError(e);
|
|
2043
|
+
if (!looksLikeNetworkFailure(d)) throw e;
|
|
2044
|
+
throw new ProviderError(d.kind, networkErrorMessage("gemini", d), {
|
|
2045
|
+
transient: d.transient
|
|
2046
|
+
});
|
|
1888
2047
|
}
|
|
1889
2048
|
const status = respLike.status;
|
|
1890
2049
|
if (status >= 200 && status < 300) {
|
|
@@ -1894,11 +2053,18 @@ async function sendGemini(args) {
|
|
|
1894
2053
|
} catch (e) {
|
|
1895
2054
|
throw new ProviderError("parse", `gemini: response body not JSON: ${e.message}`);
|
|
1896
2055
|
}
|
|
1897
|
-
const { text, usage } = parseGeminiResponse({
|
|
2056
|
+
const { text, usage, finishReason } = parseGeminiResponse({
|
|
1898
2057
|
resp: parsed,
|
|
1899
2058
|
model: args.model,
|
|
1900
2059
|
purpose: args.purpose ?? "worker"
|
|
1901
2060
|
});
|
|
2061
|
+
if (text.trim() === "" && finishReason === "MAX_TOKENS") {
|
|
2062
|
+
throw new ProviderError(
|
|
2063
|
+
"parse",
|
|
2064
|
+
`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.`,
|
|
2065
|
+
{ transient: false }
|
|
2066
|
+
);
|
|
2067
|
+
}
|
|
1902
2068
|
return { text, attempts: 1, usage: applyPricing2(usage, args.pricing) };
|
|
1903
2069
|
}
|
|
1904
2070
|
const bodyText = await respLike.text().catch(() => "");
|
|
@@ -1956,7 +2122,15 @@ function buildOpenAICompatibleRequest(opts) {
|
|
|
1956
2122
|
json_schema: {
|
|
1957
2123
|
name: "structured_output",
|
|
1958
2124
|
schema: opts.jsonSchema,
|
|
1959
|
-
strict:
|
|
2125
|
+
// NOT strict. Strict mode requires `additionalProperties: false` on
|
|
2126
|
+
// every object and every property listed in `required` — the
|
|
2127
|
+
// engine's schemas don't meet that, so every structured OpenAI call
|
|
2128
|
+
// (planner, judges, synthesis) was a 400, unnoticed until the canary
|
|
2129
|
+
// grew a structured check (2026-10-11). Non-strict still shapes the
|
|
2130
|
+
// reply to the schema, and structured.ts validates it against the
|
|
2131
|
+
// full schema regardless, so strictness added a failure mode and no
|
|
2132
|
+
// safety.
|
|
2133
|
+
strict: false
|
|
1960
2134
|
}
|
|
1961
2135
|
};
|
|
1962
2136
|
}
|
|
@@ -2066,7 +2240,11 @@ async function sendOpenAICompatible(args) {
|
|
|
2066
2240
|
try {
|
|
2067
2241
|
respLike = await doFetch(url, init);
|
|
2068
2242
|
} catch (e) {
|
|
2069
|
-
|
|
2243
|
+
const d = diagnoseNetworkError(e);
|
|
2244
|
+
if (!looksLikeNetworkFailure(d)) throw e;
|
|
2245
|
+
throw new ProviderError(d.kind, networkErrorMessage(args.provider, d), {
|
|
2246
|
+
transient: d.transient
|
|
2247
|
+
});
|
|
2070
2248
|
}
|
|
2071
2249
|
const status = respLike.status;
|
|
2072
2250
|
if (status >= 200 && status < 300) {
|
|
@@ -2251,50 +2429,6 @@ init_cjs_shims();
|
|
|
2251
2429
|
var import_server = require("@modelcontextprotocol/sdk/server/index.js");
|
|
2252
2430
|
var import_types9 = require("@modelcontextprotocol/sdk/types.js");
|
|
2253
2431
|
|
|
2254
|
-
// src/bridge/index.ts
|
|
2255
|
-
init_cjs_shims();
|
|
2256
|
-
|
|
2257
|
-
// src/bridge/proxy-tools.ts
|
|
2258
|
-
init_cjs_shims();
|
|
2259
|
-
function buildPythonProxies(bridge) {
|
|
2260
|
-
const proxies = /* @__PURE__ */ new Map();
|
|
2261
|
-
for (const name of bridge.toolNames) {
|
|
2262
|
-
proxies.set(name, makeProxy(bridge, name));
|
|
2263
|
-
}
|
|
2264
|
-
return proxies;
|
|
2265
|
-
}
|
|
2266
|
-
function makeProxy(bridge, name) {
|
|
2267
|
-
return {
|
|
2268
|
-
name,
|
|
2269
|
-
description: `(forwarded to Python crosscheck-agent) ${name}`,
|
|
2270
|
-
// We don't carry the per-tool input schema across the bridge in
|
|
2271
|
-
// route-all mode — the TS server is a transparent forwarder, so
|
|
2272
|
-
// arg validation happens on the Python side. inputSchema is left
|
|
2273
|
-
// permissive; the Python validator throws structured errors that
|
|
2274
|
-
// tunnel back through `callTool()`.
|
|
2275
|
-
inputSchema: {
|
|
2276
|
-
type: "object",
|
|
2277
|
-
additionalProperties: true,
|
|
2278
|
-
description: `Forwarded to Python \u2014 see Python tool '${name}' for full schema.`
|
|
2279
|
-
},
|
|
2280
|
-
handler: async (args) => {
|
|
2281
|
-
const r = await bridge.callTool(name, args);
|
|
2282
|
-
if (!r.content.length) {
|
|
2283
|
-
return {};
|
|
2284
|
-
}
|
|
2285
|
-
const first = r.content[0];
|
|
2286
|
-
if (first.type === "text" && first.text) {
|
|
2287
|
-
try {
|
|
2288
|
-
return JSON.parse(first.text);
|
|
2289
|
-
} catch {
|
|
2290
|
-
return { text: first.text };
|
|
2291
|
-
}
|
|
2292
|
-
}
|
|
2293
|
-
return { content: r.content };
|
|
2294
|
-
}
|
|
2295
|
-
};
|
|
2296
|
-
}
|
|
2297
|
-
|
|
2298
2432
|
// src/instructions.ts
|
|
2299
2433
|
init_cjs_shims();
|
|
2300
2434
|
var ROUTABLE_TOOLS = [
|
|
@@ -2381,7 +2515,7 @@ var import_zod = require("zod");
|
|
|
2381
2515
|
// src/server-meta.ts
|
|
2382
2516
|
init_cjs_shims();
|
|
2383
2517
|
var SERVER_NAME = "crosscheck-agent";
|
|
2384
|
-
var SERVER_VERSION = true ? "0.2.
|
|
2518
|
+
var SERVER_VERSION = true ? "0.2.29" : "0.0.0-dev";
|
|
2385
2519
|
|
|
2386
2520
|
// src/tools/audit.ts
|
|
2387
2521
|
init_cjs_shims();
|
|
@@ -2448,27 +2582,27 @@ function extractJson(text) {
|
|
|
2448
2582
|
|
|
2449
2583
|
// src/core/json-schema.ts
|
|
2450
2584
|
init_cjs_shims();
|
|
2451
|
-
function validateSchema(value, schema,
|
|
2585
|
+
function validateSchema(value, schema, path16 = "") {
|
|
2452
2586
|
const errs = [];
|
|
2453
2587
|
if ("anyOf" in schema) {
|
|
2454
2588
|
const subs = schema["anyOf"].map(
|
|
2455
|
-
(s) => validateSchema(value, s,
|
|
2589
|
+
(s) => validateSchema(value, s, path16)
|
|
2456
2590
|
);
|
|
2457
2591
|
if (!subs.some((e) => e.length === 0)) {
|
|
2458
|
-
errs.push(`${
|
|
2592
|
+
errs.push(`${path16 || "<root>"}: did not match anyOf`);
|
|
2459
2593
|
}
|
|
2460
2594
|
return errs;
|
|
2461
2595
|
}
|
|
2462
2596
|
if ("oneOf" in schema) {
|
|
2463
|
-
const passed = schema["oneOf"].filter((s) => validateSchema(value, s,
|
|
2597
|
+
const passed = schema["oneOf"].filter((s) => validateSchema(value, s, path16).length === 0).length;
|
|
2464
2598
|
if (passed !== 1) {
|
|
2465
|
-
errs.push(`${
|
|
2599
|
+
errs.push(`${path16 || "<root>"}: matched ${passed} of oneOf, expected 1`);
|
|
2466
2600
|
}
|
|
2467
2601
|
return errs;
|
|
2468
2602
|
}
|
|
2469
2603
|
if ("const" in schema && !deepEqual(value, schema["const"])) {
|
|
2470
2604
|
errs.push(
|
|
2471
|
-
`${
|
|
2605
|
+
`${path16 || "<root>"}: expected const ${pyRepr(schema["const"])}, got ${pyRepr(value)}`
|
|
2472
2606
|
);
|
|
2473
2607
|
return errs;
|
|
2474
2608
|
}
|
|
@@ -2478,7 +2612,7 @@ function validateSchema(value, schema, path15 = "") {
|
|
|
2478
2612
|
const ok = types.some((tt) => matchesType(value, String(tt)));
|
|
2479
2613
|
if (!ok) {
|
|
2480
2614
|
errs.push(
|
|
2481
|
-
`${
|
|
2615
|
+
`${path16 || "<root>"}: expected type ${pyReprType(t)}, got ${pyTypeName(value)}`
|
|
2482
2616
|
);
|
|
2483
2617
|
return errs;
|
|
2484
2618
|
}
|
|
@@ -2487,29 +2621,29 @@ function validateSchema(value, schema, path15 = "") {
|
|
|
2487
2621
|
if ("enum" in schema) {
|
|
2488
2622
|
const en = schema["enum"];
|
|
2489
2623
|
if (!en.some((x) => deepEqual(x, value))) {
|
|
2490
|
-
errs.push(`${
|
|
2624
|
+
errs.push(`${path16 || "<root>"}: value ${pyRepr(value)} not in enum`);
|
|
2491
2625
|
}
|
|
2492
2626
|
}
|
|
2493
2627
|
if ("minLength" in schema && value.length < schema["minLength"]) {
|
|
2494
|
-
errs.push(`${
|
|
2628
|
+
errs.push(`${path16 || "<root>"}: shorter than minLength ${schema["minLength"]}`);
|
|
2495
2629
|
}
|
|
2496
2630
|
}
|
|
2497
2631
|
if (typeof value === "number" && !Number.isNaN(value)) {
|
|
2498
2632
|
if ("minimum" in schema && value < schema["minimum"]) {
|
|
2499
|
-
errs.push(`${
|
|
2633
|
+
errs.push(`${path16 || "<root>"}: ${value} < minimum ${schema["minimum"]}`);
|
|
2500
2634
|
}
|
|
2501
2635
|
if ("maximum" in schema && value > schema["maximum"]) {
|
|
2502
|
-
errs.push(`${
|
|
2636
|
+
errs.push(`${path16 || "<root>"}: ${value} > maximum ${schema["maximum"]}`);
|
|
2503
2637
|
}
|
|
2504
2638
|
}
|
|
2505
2639
|
if (Array.isArray(value)) {
|
|
2506
2640
|
if ("minItems" in schema && value.length < schema["minItems"]) {
|
|
2507
|
-
errs.push(`${
|
|
2641
|
+
errs.push(`${path16 || "<root>"}: fewer items than minItems ${schema["minItems"]}`);
|
|
2508
2642
|
}
|
|
2509
2643
|
const itemSchema = schema["items"];
|
|
2510
2644
|
if (isObj(itemSchema)) {
|
|
2511
2645
|
for (let i = 0; i < value.length; i++) {
|
|
2512
|
-
errs.push(...validateSchema(value[i], itemSchema, `${
|
|
2646
|
+
errs.push(...validateSchema(value[i], itemSchema, `${path16}[${i}]`));
|
|
2513
2647
|
}
|
|
2514
2648
|
}
|
|
2515
2649
|
}
|
|
@@ -2518,19 +2652,19 @@ function validateSchema(value, schema, path15 = "") {
|
|
|
2518
2652
|
const required = schema["required"] ?? [];
|
|
2519
2653
|
for (const r of required) {
|
|
2520
2654
|
if (!(r in value)) {
|
|
2521
|
-
errs.push(`${
|
|
2655
|
+
errs.push(`${path16 || "<root>"}: missing required key ${pyRepr(r)}`);
|
|
2522
2656
|
}
|
|
2523
2657
|
}
|
|
2524
2658
|
if (schema["additionalProperties"] === false) {
|
|
2525
2659
|
for (const k of Object.keys(value)) {
|
|
2526
2660
|
if (!(k in props)) {
|
|
2527
|
-
errs.push(`${
|
|
2661
|
+
errs.push(`${path16 || "<root>"}: unknown key ${pyRepr(k)}`);
|
|
2528
2662
|
}
|
|
2529
2663
|
}
|
|
2530
2664
|
}
|
|
2531
2665
|
for (const [k, v] of Object.entries(value)) {
|
|
2532
2666
|
const ps = props[k];
|
|
2533
|
-
if (ps) errs.push(...validateSchema(v, ps,
|
|
2667
|
+
if (ps) errs.push(...validateSchema(v, ps, path16 ? `${path16}.${k}` : k));
|
|
2534
2668
|
}
|
|
2535
2669
|
}
|
|
2536
2670
|
return errs;
|
|
@@ -2612,6 +2746,34 @@ function pyReprType(t) {
|
|
|
2612
2746
|
|
|
2613
2747
|
// src/core/usage.ts
|
|
2614
2748
|
init_cjs_shims();
|
|
2749
|
+
|
|
2750
|
+
// src/core/session.ts
|
|
2751
|
+
init_cjs_shims();
|
|
2752
|
+
var import_node_crypto2 = require("crypto");
|
|
2753
|
+
var processSessionId = null;
|
|
2754
|
+
var startedAt = null;
|
|
2755
|
+
function engineSessionId() {
|
|
2756
|
+
if (processSessionId === null) {
|
|
2757
|
+
processSessionId = (0, import_node_crypto2.randomUUID)();
|
|
2758
|
+
startedAt = Date.now();
|
|
2759
|
+
}
|
|
2760
|
+
return processSessionId;
|
|
2761
|
+
}
|
|
2762
|
+
function resolveSessionId(callerSupplied) {
|
|
2763
|
+
const trimmed = typeof callerSupplied === "string" ? callerSupplied.trim() : "";
|
|
2764
|
+
return trimmed.length > 0 ? trimmed : engineSessionId();
|
|
2765
|
+
}
|
|
2766
|
+
function localSessionRecordingEnabled(env = globalThis.process?.env ?? {}) {
|
|
2767
|
+
const v = (env["CROSSCHECK_RECORD_SESSIONS"] ?? "").trim().toLowerCase();
|
|
2768
|
+
return !["0", "false", "off", "no"].includes(v);
|
|
2769
|
+
}
|
|
2770
|
+
function recordingSessionId(callerSupplied) {
|
|
2771
|
+
if (localSessionRecordingEnabled()) return resolveSessionId(callerSupplied);
|
|
2772
|
+
const trimmed = typeof callerSupplied === "string" ? callerSupplied.trim() : "";
|
|
2773
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
2774
|
+
}
|
|
2775
|
+
|
|
2776
|
+
// src/core/usage.ts
|
|
2615
2777
|
function emptyUsage(provider, model, purpose = "worker") {
|
|
2616
2778
|
return {
|
|
2617
2779
|
provider,
|
|
@@ -2716,11 +2878,11 @@ function withCommas(n) {
|
|
|
2716
2878
|
function renderRunSummary(opts) {
|
|
2717
2879
|
const endedAt = opts.endedAtS ?? Math.trunc(Date.now() / 1e3);
|
|
2718
2880
|
let scope = "call";
|
|
2719
|
-
let
|
|
2881
|
+
let startedAt2 = null;
|
|
2720
2882
|
let rows = [];
|
|
2721
2883
|
if (opts.sessionScope && opts.sessionScope.rows.length > 0) {
|
|
2722
2884
|
scope = "session";
|
|
2723
|
-
|
|
2885
|
+
startedAt2 = opts.sessionScope.startedAt;
|
|
2724
2886
|
rows = opts.sessionScope.rows.map((r) => ({ ...r }));
|
|
2725
2887
|
} else {
|
|
2726
2888
|
const byPurpose = /* @__PURE__ */ new Map();
|
|
@@ -2751,6 +2913,7 @@ function renderRunSummary(opts) {
|
|
|
2751
2913
|
row.cpu_ms += a.cpu_ms ?? 0;
|
|
2752
2914
|
if (a.cache_hit) row.cache_hits += 1;
|
|
2753
2915
|
if (a.error) row.errors += 1;
|
|
2916
|
+
if (a.usage?.estimated) row.estimated = true;
|
|
2754
2917
|
}
|
|
2755
2918
|
rows = Array.from(byPurpose.values());
|
|
2756
2919
|
}
|
|
@@ -2763,16 +2926,18 @@ function renderRunSummary(opts) {
|
|
|
2763
2926
|
wall_ms: rows.reduce((s, r) => s + r.wall_ms, 0),
|
|
2764
2927
|
cpu_ms: rows.reduce((s, r) => s + r.cpu_ms, 0),
|
|
2765
2928
|
cache_hits: rows.reduce((s, r) => s + r.cache_hits, 0),
|
|
2766
|
-
errors: rows.reduce((s, r) => s + r.errors, 0)
|
|
2929
|
+
errors: rows.reduce((s, r) => s + r.errors, 0),
|
|
2930
|
+
...rows.some((r) => r.estimated) ? { estimated: true } : {}
|
|
2767
2931
|
};
|
|
2768
2932
|
const titleLeft = scope === "session" ? `session: ${opts.sessionId ?? ""}` : `call: ${opts.toolName}`;
|
|
2769
|
-
const
|
|
2933
|
+
const costText = totals.estimated ? `$${totals.cost_usd.toFixed(4)}+ (some calls unpriced)` : `$${totals.cost_usd.toFixed(4)}`;
|
|
2934
|
+
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)`;
|
|
2770
2935
|
const bodyLines = [];
|
|
2771
2936
|
for (let i = 0; i < rows.length; i++) {
|
|
2772
2937
|
const r = rows[i];
|
|
2773
2938
|
const glyph = i === rows.length - 1 ? "`-" : "|-";
|
|
2774
2939
|
bodyLines.push(
|
|
2775
|
-
`${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)`
|
|
2940
|
+
`${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)`
|
|
2776
2941
|
);
|
|
2777
2942
|
}
|
|
2778
2943
|
const callByModel = rollupSpendByModel(
|
|
@@ -2820,7 +2985,7 @@ function renderRunSummary(opts) {
|
|
|
2820
2985
|
tool: opts.toolName,
|
|
2821
2986
|
scope,
|
|
2822
2987
|
currency: "USD",
|
|
2823
|
-
started_at:
|
|
2988
|
+
started_at: startedAt2,
|
|
2824
2989
|
ended_at: endedAt,
|
|
2825
2990
|
rows,
|
|
2826
2991
|
totals,
|
|
@@ -2945,14 +3110,15 @@ async function attachUsageBlock(result, answers, opts) {
|
|
|
2945
3110
|
delete result["_suppress_run_summary"];
|
|
2946
3111
|
}
|
|
2947
3112
|
async function appendUsageLog(storage, sessionId, toolName, answers, nowS) {
|
|
2948
|
-
|
|
3113
|
+
const sid = recordingSessionId(sessionId);
|
|
3114
|
+
if (!sid || answers.length === 0) return;
|
|
2949
3115
|
const now = nowS ?? Math.trunc(Date.now() / 1e3);
|
|
2950
3116
|
const rows = [];
|
|
2951
3117
|
for (const a of answers) {
|
|
2952
3118
|
const u = a.usage;
|
|
2953
3119
|
if (!u || typeof u.provider !== "string" || u.provider === "") continue;
|
|
2954
3120
|
rows.push({
|
|
2955
|
-
session_id:
|
|
3121
|
+
session_id: sid,
|
|
2956
3122
|
ts: now,
|
|
2957
3123
|
tool: toolName,
|
|
2958
3124
|
purpose: u.purpose ?? "worker",
|
|
@@ -2975,13 +3141,14 @@ async function appendUsageLog(storage, sessionId, toolName, answers, nowS) {
|
|
|
2975
3141
|
}
|
|
2976
3142
|
}
|
|
2977
3143
|
async function recordSessionCall(storage, sessionId, answers, wallMs, cpuMs, nowS) {
|
|
2978
|
-
|
|
3144
|
+
const sid = recordingSessionId(sessionId);
|
|
3145
|
+
if (!sid) return;
|
|
2979
3146
|
const now = nowS ?? Math.trunc(Date.now() / 1e3);
|
|
2980
3147
|
try {
|
|
2981
|
-
let existing = await storage.getSession(
|
|
3148
|
+
let existing = await storage.getSession(sid);
|
|
2982
3149
|
if (!existing) {
|
|
2983
3150
|
await storage.upsertSession({
|
|
2984
|
-
session_id:
|
|
3151
|
+
session_id: sid,
|
|
2985
3152
|
started_at: now,
|
|
2986
3153
|
last_at: now,
|
|
2987
3154
|
calls: 0,
|
|
@@ -2994,7 +3161,7 @@ async function recordSessionCall(storage, sessionId, answers, wallMs, cpuMs, now
|
|
|
2994
3161
|
total_cost_usd: 0,
|
|
2995
3162
|
total_cpu_ms: 0
|
|
2996
3163
|
});
|
|
2997
|
-
existing = await storage.getSession(
|
|
3164
|
+
existing = await storage.getSession(sid);
|
|
2998
3165
|
}
|
|
2999
3166
|
if (!existing) return;
|
|
3000
3167
|
let promptDelta = 0;
|
|
@@ -3014,7 +3181,7 @@ async function recordSessionCall(storage, sessionId, answers, wallMs, cpuMs, now
|
|
|
3014
3181
|
}
|
|
3015
3182
|
if (a.cache_hit) cacheHitDelta += 1;
|
|
3016
3183
|
}
|
|
3017
|
-
await storage.accumulateSessionTotals(
|
|
3184
|
+
await storage.accumulateSessionTotals(sid, {
|
|
3018
3185
|
calls: answers.length,
|
|
3019
3186
|
wall_ms: wallMs,
|
|
3020
3187
|
cache_hits: cacheHitDelta,
|
|
@@ -3409,7 +3576,7 @@ function buildPersonaInjection(opts) {
|
|
|
3409
3576
|
|
|
3410
3577
|
// src/core/canary.ts
|
|
3411
3578
|
init_cjs_shims();
|
|
3412
|
-
var
|
|
3579
|
+
var import_node_crypto3 = require("crypto");
|
|
3413
3580
|
|
|
3414
3581
|
// src/core/injection.ts
|
|
3415
3582
|
init_cjs_shims();
|
|
@@ -3428,8 +3595,8 @@ var UNTRUSTED_SYSTEM_NOTE = "Some inputs in this conversation are wrapped in <un
|
|
|
3428
3595
|
function mintCanary() {
|
|
3429
3596
|
const t = process.hrtime.bigint().toString();
|
|
3430
3597
|
const pid = String(process.pid);
|
|
3431
|
-
const r = (0,
|
|
3432
|
-
const hex = (0,
|
|
3598
|
+
const r = (0, import_node_crypto3.randomBytes)(16).toString("hex");
|
|
3599
|
+
const hex = (0, import_node_crypto3.createHash)("sha256").update(`${t}-${pid}-${r}`).digest("hex").slice(0, 16).toUpperCase();
|
|
3433
3600
|
return `CC_CANARY_${hex}`;
|
|
3434
3601
|
}
|
|
3435
3602
|
function wrapUntrusted(content, canary) {
|
|
@@ -3619,7 +3786,7 @@ var import_node_path3 = __toESM(require("path"), 1);
|
|
|
3619
3786
|
|
|
3620
3787
|
// src/core/redact.ts
|
|
3621
3788
|
init_cjs_shims();
|
|
3622
|
-
var
|
|
3789
|
+
var import_node_crypto4 = require("crypto");
|
|
3623
3790
|
function builtinRedactionRules() {
|
|
3624
3791
|
return [
|
|
3625
3792
|
{ pattern: /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g, label: "EMAIL", prefix_group: false },
|
|
@@ -3646,7 +3813,7 @@ function hmacSuffix(cfg2, label, value) {
|
|
|
3646
3813
|
const sid = cfg2.session_id ?? "";
|
|
3647
3814
|
const sidBytes = Buffer.from(sid, "utf8");
|
|
3648
3815
|
const key = Buffer.concat([Buffer.from(secret), sidBytes]);
|
|
3649
|
-
const digest = (0,
|
|
3816
|
+
const digest = (0, import_node_crypto4.createHmac)("sha256", key).update(`${label}:${value}`, "utf8").digest("hex");
|
|
3650
3817
|
return digest.slice(0, 8);
|
|
3651
3818
|
}
|
|
3652
3819
|
function redactText(s, cfg2) {
|
|
@@ -5983,10 +6150,6 @@ If you need supporting evidence, you may emit ONE \`<tool_call>...</tool_call>\`
|
|
|
5983
6150
|
}
|
|
5984
6151
|
|
|
5985
6152
|
// src/tools/confer.ts
|
|
5986
|
-
var DEFERRED_OPTS = [
|
|
5987
|
-
// empty — every confer opt runs natively except worker_tools, which
|
|
5988
|
-
// is gated below (non-empty list → defer).
|
|
5989
|
-
];
|
|
5990
6153
|
async function runConfer(args, opts) {
|
|
5991
6154
|
const callStartedWall = import_node_perf_hooks2.performance.now();
|
|
5992
6155
|
const callStartedCpu = process.cpuUsage();
|
|
@@ -6002,16 +6165,11 @@ async function runConfer(args, opts) {
|
|
|
6002
6165
|
rejectedWorkerTools.push(t);
|
|
6003
6166
|
}
|
|
6004
6167
|
}
|
|
6005
|
-
|
|
6006
|
-
const needsBridge = DEFERRED_OPTS.some((k) => Boolean(args[k])) || workerToolsNeedsBridge;
|
|
6007
|
-
if (needsBridge) {
|
|
6008
|
-
if (opts.bridge && opts.bridge.toolNames.has("confer")) {
|
|
6009
|
-
return await deferConfer(args, opts.bridge);
|
|
6010
|
-
}
|
|
6168
|
+
if (acceptedWorkerTools.length > 0 && !opts.innerCallers) {
|
|
6011
6169
|
return errorEnvelope2(
|
|
6012
6170
|
"CONFER_OPT_NOT_NATIVE",
|
|
6013
6171
|
"worker_tools requested but innerCallers are not wired",
|
|
6014
|
-
"Native confer covers untrusted_input + early_stop + extract_claims + inject_session_memory + auto_panel. worker_tools needs innerCallers wired by the host
|
|
6172
|
+
"Native confer covers untrusted_input + early_stop + extract_claims + inject_session_memory + auto_panel. worker_tools needs innerCallers wired by the host."
|
|
6015
6173
|
);
|
|
6016
6174
|
}
|
|
6017
6175
|
const question = typeof args["question"] === "string" ? args["question"] : String(args["question"] ?? "");
|
|
@@ -6362,21 +6520,6 @@ function unknownProviderError(unknownNames, available) {
|
|
|
6362
6520
|
available_now: Object.keys(available).sort()
|
|
6363
6521
|
};
|
|
6364
6522
|
}
|
|
6365
|
-
async function deferConfer(args, bridge) {
|
|
6366
|
-
const r = await bridge.callTool("confer", args);
|
|
6367
|
-
const text = r.content[0]?.text;
|
|
6368
|
-
if (typeof text === "string") {
|
|
6369
|
-
try {
|
|
6370
|
-
return JSON.parse(text);
|
|
6371
|
-
} catch {
|
|
6372
|
-
}
|
|
6373
|
-
}
|
|
6374
|
-
return errorEnvelope2(
|
|
6375
|
-
"CONFER_BRIDGE_BAD_ENVELOPE",
|
|
6376
|
-
"bridge returned an unparseable envelope for confer",
|
|
6377
|
-
"Check that the Python child is healthy."
|
|
6378
|
-
);
|
|
6379
|
-
}
|
|
6380
6523
|
function errorEnvelope2(code, message, hint) {
|
|
6381
6524
|
return {
|
|
6382
6525
|
tool: "confer",
|
|
@@ -6752,7 +6895,7 @@ function errorEnvelope3(code, message, hint) {
|
|
|
6752
6895
|
transient: false
|
|
6753
6896
|
};
|
|
6754
6897
|
}
|
|
6755
|
-
async function runVerify(args,
|
|
6898
|
+
async function runVerify(args, fetchConfig) {
|
|
6756
6899
|
const checks = args["checks"];
|
|
6757
6900
|
if (!Array.isArray(checks) || checks.length === 0) {
|
|
6758
6901
|
return {
|
|
@@ -6764,7 +6907,6 @@ async function runVerify(args, bridge, fetchConfig) {
|
|
|
6764
6907
|
)
|
|
6765
6908
|
};
|
|
6766
6909
|
}
|
|
6767
|
-
void bridge;
|
|
6768
6910
|
const allowShell = Boolean(args["allow_shell"] ?? false);
|
|
6769
6911
|
const wallStart = import_node_perf_hooks3.performance.now();
|
|
6770
6912
|
const cpuStart = process.cpuUsage();
|
|
@@ -7066,7 +7208,6 @@ async function runBench(args, opts) {
|
|
|
7066
7208
|
const innerOpts = {
|
|
7067
7209
|
providers: opts.providers,
|
|
7068
7210
|
allowlist: opts.allowlist ?? null,
|
|
7069
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
7070
7211
|
...opts.moderator ? { moderator: opts.moderator } : {}
|
|
7071
7212
|
};
|
|
7072
7213
|
let inner;
|
|
@@ -7279,7 +7420,7 @@ function isObj4(v) {
|
|
|
7279
7420
|
|
|
7280
7421
|
// src/tools/config-pin.ts
|
|
7281
7422
|
init_cjs_shims();
|
|
7282
|
-
var
|
|
7423
|
+
var import_node_crypto5 = require("crypto");
|
|
7283
7424
|
var import_node_fs7 = require("fs");
|
|
7284
7425
|
var import_node_path7 = __toESM(require("path"), 1);
|
|
7285
7426
|
var DEFAULT_PIN_PATH = ".crosscheck/config_pins.json";
|
|
@@ -7434,7 +7575,7 @@ function hashFile(abs) {
|
|
|
7434
7575
|
return "";
|
|
7435
7576
|
}
|
|
7436
7577
|
const normalized = stripCrBeforeLf(raw);
|
|
7437
|
-
return "sha256:" + (0,
|
|
7578
|
+
return "sha256:" + (0, import_node_crypto5.createHash)("sha256").update(normalized).digest("hex");
|
|
7438
7579
|
}
|
|
7439
7580
|
function stripCrBeforeLf(buf) {
|
|
7440
7581
|
const out = [];
|
|
@@ -7512,7 +7653,7 @@ function pyRepr2(v) {
|
|
|
7512
7653
|
|
|
7513
7654
|
// src/tools/create.ts
|
|
7514
7655
|
init_cjs_shims();
|
|
7515
|
-
var
|
|
7656
|
+
var import_node_crypto8 = require("crypto");
|
|
7516
7657
|
var import_node_fs10 = require("fs");
|
|
7517
7658
|
var import_node_path10 = __toESM(require("path"), 1);
|
|
7518
7659
|
|
|
@@ -7615,7 +7756,7 @@ function isDeadModelError(err) {
|
|
|
7615
7756
|
|
|
7616
7757
|
// src/core/node-cache.ts
|
|
7617
7758
|
init_cjs_shims();
|
|
7618
|
-
var
|
|
7759
|
+
var import_node_crypto6 = require("crypto");
|
|
7619
7760
|
var import_node_fs8 = require("fs");
|
|
7620
7761
|
var import_node_path8 = require("path");
|
|
7621
7762
|
var NODE_CACHE_KEY_VERSION = "v2";
|
|
@@ -7642,7 +7783,7 @@ function canonicalizeNodeText(s) {
|
|
|
7642
7783
|
return out;
|
|
7643
7784
|
}
|
|
7644
7785
|
function sha256Hex(s) {
|
|
7645
|
-
return (0,
|
|
7786
|
+
return (0, import_node_crypto6.createHash)("sha256").update(s, "utf8").digest("hex");
|
|
7646
7787
|
}
|
|
7647
7788
|
function nodeCacheKey(node, upstreamOutputs, provider, model) {
|
|
7648
7789
|
const canonUpstream = {};
|
|
@@ -7700,11 +7841,11 @@ function getNodeCache(cfg2, repoRoot, key, nowMs) {
|
|
|
7700
7841
|
return null;
|
|
7701
7842
|
}
|
|
7702
7843
|
}
|
|
7703
|
-
function atomicWriteJson(
|
|
7704
|
-
(0, import_node_fs8.mkdirSync)((0, import_node_path8.dirname)(
|
|
7705
|
-
const tmp = `${
|
|
7844
|
+
function atomicWriteJson(path16, payload) {
|
|
7845
|
+
(0, import_node_fs8.mkdirSync)((0, import_node_path8.dirname)(path16), { recursive: true });
|
|
7846
|
+
const tmp = `${path16}.${process.pid}.${Date.now()}.tmp`;
|
|
7706
7847
|
(0, import_node_fs8.writeFileSync)(tmp, JSON.stringify(payload), "utf8");
|
|
7707
|
-
(0, import_node_fs8.renameSync)(tmp,
|
|
7848
|
+
(0, import_node_fs8.renameSync)(tmp, path16);
|
|
7708
7849
|
}
|
|
7709
7850
|
function putNodeCache(cfg2, repoRoot, key, value) {
|
|
7710
7851
|
if (!cfg2 || cfg2.enabled === false) return;
|
|
@@ -7762,7 +7903,6 @@ var EST_TOKENS = {
|
|
|
7762
7903
|
med: [1500, 800],
|
|
7763
7904
|
high: [2500, 1500]
|
|
7764
7905
|
};
|
|
7765
|
-
var DEFERRED_OPTS2 = [];
|
|
7766
7906
|
var REACTIVE_SIGNAL_RE = /<signals>\s*(\{[\s\S]*?\})\s*<\/signals>/g;
|
|
7767
7907
|
function parseReactiveSignals(output) {
|
|
7768
7908
|
if (typeof output !== "string" || !output.includes("<signals>")) return [];
|
|
@@ -7802,17 +7942,6 @@ async function runOrchestrate(args, opts) {
|
|
|
7802
7942
|
);
|
|
7803
7943
|
if (breakerEnv) return breakerEnv;
|
|
7804
7944
|
}
|
|
7805
|
-
const needsBridge = DEFERRED_OPTS2.some((k) => Boolean(args[k]));
|
|
7806
|
-
if (needsBridge) {
|
|
7807
|
-
if (opts.bridge && opts.bridge.toolNames.has("orchestrate")) {
|
|
7808
|
-
return await deferOrchestrate(args, opts.bridge);
|
|
7809
|
-
}
|
|
7810
|
-
return errorEnvelope5(
|
|
7811
|
-
"ORCHESTRATE_OPT_NOT_NATIVE",
|
|
7812
|
-
"this orchestrate opt-in requires the Python bridge in v1",
|
|
7813
|
-
"v1 native covers the plain DAG flow + cheap_mode. reactive (mid-flight DAG updates) still defers. Set CROSSCHECK_BRIDGE_PYTHON=1 to enable."
|
|
7814
|
-
);
|
|
7815
|
-
}
|
|
7816
7945
|
const goal = typeof args["goal"] === "string" ? args["goal"] : null;
|
|
7817
7946
|
const dagIn = isObj5(args["dag"]) ? args["dag"] : null;
|
|
7818
7947
|
if (goal === null === (dagIn === null)) {
|
|
@@ -8754,21 +8883,6 @@ function resolveProviders3(names, available, allowlist) {
|
|
|
8754
8883
|
}
|
|
8755
8884
|
return out;
|
|
8756
8885
|
}
|
|
8757
|
-
async function deferOrchestrate(args, bridge) {
|
|
8758
|
-
const r = await bridge.callTool("orchestrate", args);
|
|
8759
|
-
const text = r.content[0]?.text;
|
|
8760
|
-
if (typeof text === "string") {
|
|
8761
|
-
try {
|
|
8762
|
-
return JSON.parse(text);
|
|
8763
|
-
} catch {
|
|
8764
|
-
}
|
|
8765
|
-
}
|
|
8766
|
-
return errorEnvelope5(
|
|
8767
|
-
"ORCHESTRATE_BRIDGE_BAD_ENVELOPE",
|
|
8768
|
-
"bridge returned an unparseable envelope for orchestrate",
|
|
8769
|
-
"Check that the Python child is healthy."
|
|
8770
|
-
);
|
|
8771
|
-
}
|
|
8772
8886
|
function errorEnvelope5(code, message, hint, kind = "client") {
|
|
8773
8887
|
return {
|
|
8774
8888
|
tool: "orchestrate",
|
|
@@ -8817,7 +8931,7 @@ function pyRound6(x) {
|
|
|
8817
8931
|
|
|
8818
8932
|
// src/tools/fetch.ts
|
|
8819
8933
|
init_cjs_shims();
|
|
8820
|
-
var
|
|
8934
|
+
var import_node_crypto7 = require("crypto");
|
|
8821
8935
|
var import_node_fs9 = require("fs");
|
|
8822
8936
|
var import_node_path9 = __toESM(require("path"), 1);
|
|
8823
8937
|
var DEFAULT_CONFIG = {
|
|
@@ -9031,10 +9145,10 @@ function extractHost(url) {
|
|
|
9031
9145
|
}
|
|
9032
9146
|
}
|
|
9033
9147
|
function sha256Hex2(s) {
|
|
9034
|
-
return (0,
|
|
9148
|
+
return (0, import_node_crypto7.createHash)("sha256").update(s, "utf8").digest("hex");
|
|
9035
9149
|
}
|
|
9036
9150
|
function sha256HexBytes(bytes) {
|
|
9037
|
-
return (0,
|
|
9151
|
+
return (0, import_node_crypto7.createHash)("sha256").update(bytes).digest("hex");
|
|
9038
9152
|
}
|
|
9039
9153
|
function resolveEvidenceDir(configured, repoRoot) {
|
|
9040
9154
|
if (import_node_path9.default.isAbsolute(configured)) return configured;
|
|
@@ -9088,6 +9202,16 @@ function buildCallContext(args) {
|
|
|
9088
9202
|
var CREATE_DOC_MAX_BYTES = 32 * 1024;
|
|
9089
9203
|
var CREATE_AUDIT_THRESHOLD = 0.7;
|
|
9090
9204
|
async function runCreate(args, opts) {
|
|
9205
|
+
const subEnvelopes = [];
|
|
9206
|
+
const tracked = (fn) => async (...a) => {
|
|
9207
|
+
const out = await fn(...a);
|
|
9208
|
+
subEnvelopes.push(out);
|
|
9209
|
+
return out;
|
|
9210
|
+
};
|
|
9211
|
+
const confer = tracked(runConfer);
|
|
9212
|
+
const orchestrate = tracked(runOrchestrate);
|
|
9213
|
+
const review = tracked(runReview);
|
|
9214
|
+
const audit = tracked(runAudit);
|
|
9091
9215
|
const instruction = typeof args["instruction"] === "string" ? args["instruction"] : String(args["instruction"] ?? "");
|
|
9092
9216
|
if (!instruction) {
|
|
9093
9217
|
return errorEnvelope6(
|
|
@@ -9124,7 +9248,7 @@ ${constraints}
|
|
|
9124
9248
|
|
|
9125
9249
|
` : "") + `DOCUMENTS (${okCount} of ${descriptors.length} ingested):
|
|
9126
9250
|
${documentsPayload}`;
|
|
9127
|
-
const scope = await
|
|
9251
|
+
const scope = await confer({
|
|
9128
9252
|
question: "We are about to orchestrate a full plan->build->review->audit lifecycle for this instruction. List 3-6 concrete sub-tasks (each with a one-line description and a difficulty: low|med|high), any critical assumptions, and any missing-information risks. Be concise and decisive \u2014 your output will be used to build the orchestration DAG.\n\nINSTRUCTION:\n" + instruction,
|
|
9129
9253
|
context: contextBlock,
|
|
9130
9254
|
...providers !== void 0 ? { providers } : {},
|
|
@@ -9133,7 +9257,6 @@ ${documentsPayload}`;
|
|
|
9133
9257
|
}, {
|
|
9134
9258
|
providers: opts.providers,
|
|
9135
9259
|
allowlist: opts.allowlist ?? null,
|
|
9136
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
9137
9260
|
ctx
|
|
9138
9261
|
});
|
|
9139
9262
|
const scopeAnswer = Array.isArray(scope["answers"]) ? scope["answers"].filter((a) => typeof a["response"] === "string" && a["response"]).map((a) => `[${a["provider"]}]
|
|
@@ -9152,11 +9275,10 @@ ${scopeAnswer || "(none)"}
|
|
|
9152
9275
|
};
|
|
9153
9276
|
if (providers !== void 0) orchestrateArgs["providers"] = providers;
|
|
9154
9277
|
if (planOnly) orchestrateArgs["plan_only"] = true;
|
|
9155
|
-
let orchestration = await
|
|
9278
|
+
let orchestration = await orchestrate(orchestrateArgs, {
|
|
9156
9279
|
providers: opts.providers,
|
|
9157
9280
|
allowlist: opts.allowlist ?? null,
|
|
9158
9281
|
moderator,
|
|
9159
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
9160
9282
|
ctx
|
|
9161
9283
|
});
|
|
9162
9284
|
let attempts = 1;
|
|
@@ -9182,7 +9304,7 @@ ${scopeAnswer || "(none)"}
|
|
|
9182
9304
|
}
|
|
9183
9305
|
let reviewEnvelope = null;
|
|
9184
9306
|
if (!skipReview && typeof orchestration["final"] === "string" && orchestration["final"]) {
|
|
9185
|
-
reviewEnvelope = await
|
|
9307
|
+
reviewEnvelope = await review({
|
|
9186
9308
|
snippet: orchestration["final"],
|
|
9187
9309
|
intent: `final deliverable for: ${instruction}`,
|
|
9188
9310
|
...providers !== void 0 ? { providers } : {},
|
|
@@ -9191,7 +9313,6 @@ ${scopeAnswer || "(none)"}
|
|
|
9191
9313
|
}, {
|
|
9192
9314
|
providers: opts.providers,
|
|
9193
9315
|
allowlist: opts.allowlist ?? null,
|
|
9194
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
9195
9316
|
ctx
|
|
9196
9317
|
});
|
|
9197
9318
|
}
|
|
@@ -9203,7 +9324,7 @@ ${scopeAnswer || "(none)"}
|
|
|
9203
9324
|
const panelExhausted = producingPanel.length > 0 && producingPanel.every(
|
|
9204
9325
|
(p) => p in opts.providers || Object.keys(opts.providers).includes(p.toLowerCase())
|
|
9205
9326
|
) && producingPanel.length >= Object.keys(opts.providers).length;
|
|
9206
|
-
auditEnvelope = await
|
|
9327
|
+
auditEnvelope = await audit({
|
|
9207
9328
|
output_to_audit: orchestration["final"],
|
|
9208
9329
|
producing_panelists: producingPanel,
|
|
9209
9330
|
...auditRubric !== void 0 ? { rubric: auditRubric } : {},
|
|
@@ -9214,7 +9335,6 @@ ${scopeAnswer || "(none)"}
|
|
|
9214
9335
|
}, {
|
|
9215
9336
|
providers: opts.providers,
|
|
9216
9337
|
allowlist: opts.allowlist ?? null,
|
|
9217
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
9218
9338
|
ctx
|
|
9219
9339
|
});
|
|
9220
9340
|
let overallF = toNumberOrNull(auditEnvelope["overall_score"]);
|
|
@@ -9233,13 +9353,12 @@ ${retryConstraints}
|
|
|
9233
9353
|
DOCUMENTS:
|
|
9234
9354
|
${documentsPayload}`
|
|
9235
9355
|
};
|
|
9236
|
-
const retryOrchestration = await
|
|
9356
|
+
const retryOrchestration = await orchestrate(
|
|
9237
9357
|
retryOrchestrateArgs,
|
|
9238
9358
|
{
|
|
9239
9359
|
providers: opts.providers,
|
|
9240
9360
|
allowlist: opts.allowlist ?? null,
|
|
9241
9361
|
moderator,
|
|
9242
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
9243
9362
|
ctx
|
|
9244
9363
|
}
|
|
9245
9364
|
);
|
|
@@ -9248,7 +9367,7 @@ ${documentsPayload}`
|
|
|
9248
9367
|
if (typeof retryOrchestration["final"] === "string" && retryOrchestration["final"]) {
|
|
9249
9368
|
const retryPanel = computeProducingPanel(retryOrchestration);
|
|
9250
9369
|
const retryPanelExhausted = retryPanel.length > 0 && retryPanel.length >= Object.keys(opts.providers).length;
|
|
9251
|
-
auditEnvelope = await
|
|
9370
|
+
auditEnvelope = await audit({
|
|
9252
9371
|
output_to_audit: retryOrchestration["final"],
|
|
9253
9372
|
producing_panelists: retryPanel,
|
|
9254
9373
|
...auditRubric !== void 0 ? { rubric: auditRubric } : {},
|
|
@@ -9259,7 +9378,6 @@ ${documentsPayload}`
|
|
|
9259
9378
|
}, {
|
|
9260
9379
|
providers: opts.providers,
|
|
9261
9380
|
allowlist: opts.allowlist ?? null,
|
|
9262
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
9263
9381
|
ctx
|
|
9264
9382
|
});
|
|
9265
9383
|
overallF = toNumberOrNull(auditEnvelope["overall_score"]);
|
|
@@ -9324,9 +9442,28 @@ ${documentsPayload}`
|
|
|
9324
9442
|
["auditor", "items", "overall_score", "passed", "rubric"]
|
|
9325
9443
|
),
|
|
9326
9444
|
artifacts,
|
|
9327
|
-
warnings
|
|
9445
|
+
warnings,
|
|
9446
|
+
...combinedUsage(subEnvelopes)
|
|
9328
9447
|
};
|
|
9329
9448
|
}
|
|
9449
|
+
function combinedUsage(envelopes) {
|
|
9450
|
+
const usages = [];
|
|
9451
|
+
const byCallTiming = [];
|
|
9452
|
+
let wall = 0, cpu = 0;
|
|
9453
|
+
for (const env of envelopes) {
|
|
9454
|
+
const e = env ?? {};
|
|
9455
|
+
const calls = e["usage"]?.["by_call"] ?? [];
|
|
9456
|
+
const t = e["timing"] ?? {};
|
|
9457
|
+
const timing = Array.isArray(t["by_call"]) ? t["by_call"] : [];
|
|
9458
|
+
if (!Array.isArray(calls) || calls.length === 0) continue;
|
|
9459
|
+
usages.push(...calls);
|
|
9460
|
+
if (timing.length === calls.length) byCallTiming.push(...timing);
|
|
9461
|
+
else for (const c of calls) byCallTiming.push({ provider: c.provider, model: c.model, purpose: c.purpose ?? null, wall_ms: 0, cpu_ms: 0, cache_hit: false });
|
|
9462
|
+
wall += Number(t["wall_ms"] ?? 0) || 0;
|
|
9463
|
+
cpu += Number(t["cpu_ms"] ?? 0) || 0;
|
|
9464
|
+
}
|
|
9465
|
+
return { usage: aggregateUsage(usages), timing: { wall_ms: wall, cpu_ms: cpu, by_call: byCallTiming } };
|
|
9466
|
+
}
|
|
9330
9467
|
async function ingestDocuments(documents, sessionId, opts) {
|
|
9331
9468
|
if (documents.length === 0) return [];
|
|
9332
9469
|
const out = [];
|
|
@@ -9396,7 +9533,7 @@ async function ingestDocuments(documents, sessionId, opts) {
|
|
|
9396
9533
|
source: ref,
|
|
9397
9534
|
type: "file",
|
|
9398
9535
|
status: "ok",
|
|
9399
|
-
hash: (0,
|
|
9536
|
+
hash: (0, import_node_crypto8.createHash)("sha256").update(text, "utf8").digest("hex"),
|
|
9400
9537
|
content: ""
|
|
9401
9538
|
}, text));
|
|
9402
9539
|
}
|
|
@@ -9433,7 +9570,7 @@ ${d.content}
|
|
|
9433
9570
|
function makeSessionId(opts, supplied) {
|
|
9434
9571
|
if (typeof supplied === "string" && supplied) return supplied;
|
|
9435
9572
|
const stamp = opts.nowEpochSeconds ? opts.nowEpochSeconds() : Math.floor(Date.now() / 1e3);
|
|
9436
|
-
const rnd = opts.randomBytes ? opts.randomBytes() : (0,
|
|
9573
|
+
const rnd = opts.randomBytes ? opts.randomBytes() : (0, import_node_crypto8.createHash)("sha256").update(`${stamp}-${process.pid}-${Math.random()}`).digest("hex");
|
|
9437
9574
|
const suffix = rnd.slice(0, 8);
|
|
9438
9575
|
return `${opts.toolName}-${stamp}-${suffix}`;
|
|
9439
9576
|
}
|
|
@@ -9498,11 +9635,6 @@ function errorEnvelope6(toolName, code, message, hint) {
|
|
|
9498
9635
|
// src/tools/coordinate.ts
|
|
9499
9636
|
init_cjs_shims();
|
|
9500
9637
|
var import_node_perf_hooks7 = require("perf_hooks");
|
|
9501
|
-
var DEFERRED_OPTS3 = [
|
|
9502
|
-
// empty — every coordinate opt runs natively when its deps
|
|
9503
|
-
// (storage / innerCallers) are wired. Without them the
|
|
9504
|
-
// worker_tools gate still triggers a bridge defer.
|
|
9505
|
-
];
|
|
9506
9638
|
var COORDINATE_DEFAULT_TEMP = 0.4;
|
|
9507
9639
|
var ROLE_TURN_SCHEMA = {
|
|
9508
9640
|
type: "object",
|
|
@@ -9557,23 +9689,18 @@ async function runCoordinate(args, opts) {
|
|
|
9557
9689
|
rejectedWorkerTools.push(t);
|
|
9558
9690
|
}
|
|
9559
9691
|
}
|
|
9560
|
-
|
|
9561
|
-
const needsBridge = DEFERRED_OPTS3.some((k) => Boolean(args[k])) || workerToolsNeedsBridge;
|
|
9562
|
-
if (needsBridge) {
|
|
9692
|
+
if (acceptedWorkerTools.length > 0 && !opts.innerCallers) {
|
|
9563
9693
|
if (superRequested) {
|
|
9564
9694
|
return errorEnvelope7(
|
|
9565
9695
|
"COORDINATE_SUPER_NOT_NATIVE",
|
|
9566
|
-
"super mode requested
|
|
9567
|
-
"worker_tools
|
|
9696
|
+
"super mode requested with worker_tools, but innerCallers are not wired",
|
|
9697
|
+
"worker_tools needs innerCallers wired by the host. Drop worker_tools, or wire innerCallers, to use super."
|
|
9568
9698
|
);
|
|
9569
9699
|
}
|
|
9570
|
-
if (opts.bridge && opts.bridge.toolNames.has("coordinate")) {
|
|
9571
|
-
return await deferCoordinate(args, opts.bridge);
|
|
9572
|
-
}
|
|
9573
9700
|
return errorEnvelope7(
|
|
9574
9701
|
"COORDINATE_OPT_NOT_NATIVE",
|
|
9575
9702
|
"worker_tools requested but innerCallers are not wired",
|
|
9576
|
-
"Native coordinate covers the three-role flow + untrusted_input + inject_session_memory. worker_tools needs innerCallers wired by the host
|
|
9703
|
+
"Native coordinate covers the three-role flow + untrusted_input + inject_session_memory. worker_tools needs innerCallers wired by the host."
|
|
9577
9704
|
);
|
|
9578
9705
|
}
|
|
9579
9706
|
const untrusted = Boolean(args["untrusted_input"]);
|
|
@@ -9973,21 +10100,6 @@ function unknownProviderError3(unknownNames, available) {
|
|
|
9973
10100
|
available_now: Object.keys(available).sort()
|
|
9974
10101
|
};
|
|
9975
10102
|
}
|
|
9976
|
-
async function deferCoordinate(args, bridge) {
|
|
9977
|
-
const r = await bridge.callTool("coordinate", args);
|
|
9978
|
-
const text = r.content[0]?.text;
|
|
9979
|
-
if (typeof text === "string") {
|
|
9980
|
-
try {
|
|
9981
|
-
return JSON.parse(text);
|
|
9982
|
-
} catch {
|
|
9983
|
-
}
|
|
9984
|
-
}
|
|
9985
|
-
return errorEnvelope7(
|
|
9986
|
-
"COORDINATE_BRIDGE_BAD_ENVELOPE",
|
|
9987
|
-
"bridge returned an unparseable envelope for coordinate",
|
|
9988
|
-
"Check that the Python child is healthy."
|
|
9989
|
-
);
|
|
9990
|
-
}
|
|
9991
10103
|
function errorEnvelope7(code, message, hint) {
|
|
9992
10104
|
return {
|
|
9993
10105
|
tool: "coordinate",
|
|
@@ -10320,10 +10432,6 @@ function buildModeratorTranscript(transcript) {
|
|
|
10320
10432
|
|
|
10321
10433
|
// src/tools/debate.ts
|
|
10322
10434
|
var import_node_perf_hooks9 = require("perf_hooks");
|
|
10323
|
-
var DEFERRED_OPTS4 = [
|
|
10324
|
-
// empty — every debate opt runs natively when its deps
|
|
10325
|
-
// (storage / innerCallers) are wired.
|
|
10326
|
-
];
|
|
10327
10435
|
async function runDebate(args, opts) {
|
|
10328
10436
|
const callStartedWall = import_node_perf_hooks9.performance.now();
|
|
10329
10437
|
const callStartedCpu = process.cpuUsage();
|
|
@@ -10341,23 +10449,18 @@ async function runDebate(args, opts) {
|
|
|
10341
10449
|
rejectedWorkerTools.push(t);
|
|
10342
10450
|
}
|
|
10343
10451
|
}
|
|
10344
|
-
|
|
10345
|
-
const needsBridge = DEFERRED_OPTS4.some((k) => Boolean(args[k])) || workerToolsNeedsBridge;
|
|
10346
|
-
if (needsBridge) {
|
|
10452
|
+
if (acceptedWorkerTools.length > 0 && !opts.innerCallers) {
|
|
10347
10453
|
if (superRequested) {
|
|
10348
10454
|
return errorEnvelope9(
|
|
10349
10455
|
"DEBATE_SUPER_NOT_NATIVE",
|
|
10350
|
-
"super mode requested
|
|
10351
|
-
"worker_tools
|
|
10456
|
+
"super mode requested with worker_tools, but innerCallers are not wired",
|
|
10457
|
+
"worker_tools needs innerCallers wired by the host. Drop worker_tools, or wire innerCallers, to use super."
|
|
10352
10458
|
);
|
|
10353
10459
|
}
|
|
10354
|
-
if (opts.bridge && opts.bridge.toolNames.has("debate")) {
|
|
10355
|
-
return await deferDebate(args, opts.bridge);
|
|
10356
|
-
}
|
|
10357
10460
|
return errorEnvelope9(
|
|
10358
10461
|
"DEBATE_OPT_NOT_NATIVE",
|
|
10359
10462
|
"worker_tools requested but innerCallers are not wired",
|
|
10360
|
-
"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
|
|
10463
|
+
"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."
|
|
10361
10464
|
);
|
|
10362
10465
|
}
|
|
10363
10466
|
const topic = typeof args["topic"] === "string" ? args["topic"] : String(args["topic"] ?? "");
|
|
@@ -10794,21 +10897,6 @@ function unknownProviderError5(unknownNames, available) {
|
|
|
10794
10897
|
available_now: Object.keys(available).sort()
|
|
10795
10898
|
};
|
|
10796
10899
|
}
|
|
10797
|
-
async function deferDebate(args, bridge) {
|
|
10798
|
-
const r = await bridge.callTool("debate", args);
|
|
10799
|
-
const text = r.content[0]?.text;
|
|
10800
|
-
if (typeof text === "string") {
|
|
10801
|
-
try {
|
|
10802
|
-
return JSON.parse(text);
|
|
10803
|
-
} catch {
|
|
10804
|
-
}
|
|
10805
|
-
}
|
|
10806
|
-
return errorEnvelope9(
|
|
10807
|
-
"DEBATE_BRIDGE_BAD_ENVELOPE",
|
|
10808
|
-
"bridge returned an unparseable envelope for debate",
|
|
10809
|
-
"Check that the Python child is healthy."
|
|
10810
|
-
);
|
|
10811
|
-
}
|
|
10812
10900
|
function errorEnvelope9(code, message, hint) {
|
|
10813
10901
|
return {
|
|
10814
10902
|
tool: "debate",
|
|
@@ -10829,9 +10917,6 @@ var DEFAULT_DELEGATION_LIMITS = {
|
|
|
10829
10917
|
};
|
|
10830
10918
|
async function runDelegate(args, opts) {
|
|
10831
10919
|
if (!opts.storage) {
|
|
10832
|
-
if (opts.bridge && opts.bridge.toolNames.has("delegate")) {
|
|
10833
|
-
return await deferDelegate(args, opts.bridge);
|
|
10834
|
-
}
|
|
10835
10920
|
return errorEnvelope10(
|
|
10836
10921
|
"DELEGATE_STORAGE_UNAVAILABLE",
|
|
10837
10922
|
"delegate needs the local database (for quota tracking), which isn't available",
|
|
@@ -10903,7 +10988,6 @@ async function runDelegate(args, opts) {
|
|
|
10903
10988
|
const innerOpts = {
|
|
10904
10989
|
providers: opts.providers,
|
|
10905
10990
|
allowlist: opts.allowlist ?? null,
|
|
10906
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
10907
10991
|
...opts.moderator ? { moderator: opts.moderator } : {}
|
|
10908
10992
|
};
|
|
10909
10993
|
let result;
|
|
@@ -10942,21 +11026,6 @@ async function record(storage, sessionId, requester, toolCall, via, accepted, no
|
|
|
10942
11026
|
created_at: nowEpochSeconds
|
|
10943
11027
|
});
|
|
10944
11028
|
}
|
|
10945
|
-
async function deferDelegate(args, bridge) {
|
|
10946
|
-
const r = await bridge.callTool("delegate", args);
|
|
10947
|
-
const text = r.content[0]?.text;
|
|
10948
|
-
if (typeof text === "string") {
|
|
10949
|
-
try {
|
|
10950
|
-
return JSON.parse(text);
|
|
10951
|
-
} catch {
|
|
10952
|
-
}
|
|
10953
|
-
}
|
|
10954
|
-
return errorEnvelope10(
|
|
10955
|
-
"DELEGATE_BRIDGE_BAD_ENVELOPE",
|
|
10956
|
-
"bridge returned an unparseable envelope for delegate",
|
|
10957
|
-
"Check that the Python child is healthy."
|
|
10958
|
-
);
|
|
10959
|
-
}
|
|
10960
11029
|
function errorEnvelope10(code, message, hint) {
|
|
10961
11030
|
return {
|
|
10962
11031
|
tool: "delegate",
|
|
@@ -11000,9 +11069,6 @@ async function runExplain(args, opts) {
|
|
|
11000
11069
|
);
|
|
11001
11070
|
}
|
|
11002
11071
|
if (!opts.storage) {
|
|
11003
|
-
if (opts.bridge && opts.bridge.toolNames.has("explain")) {
|
|
11004
|
-
return await deferExplain(args, opts.bridge);
|
|
11005
|
-
}
|
|
11006
11072
|
return errorEnvelope11(
|
|
11007
11073
|
"EXPLAIN_STORAGE_UNAVAILABLE",
|
|
11008
11074
|
"explain needs the local transcript/stats database, which isn't available",
|
|
@@ -11284,21 +11350,6 @@ function pyRepr5(v) {
|
|
|
11284
11350
|
}
|
|
11285
11351
|
return String(v);
|
|
11286
11352
|
}
|
|
11287
|
-
async function deferExplain(args, bridge) {
|
|
11288
|
-
const r = await bridge.callTool("explain", args);
|
|
11289
|
-
const text = r.content[0]?.text;
|
|
11290
|
-
if (typeof text === "string") {
|
|
11291
|
-
try {
|
|
11292
|
-
return JSON.parse(text);
|
|
11293
|
-
} catch {
|
|
11294
|
-
}
|
|
11295
|
-
}
|
|
11296
|
-
return errorEnvelope11(
|
|
11297
|
-
"EXPLAIN_BRIDGE_BAD_ENVELOPE",
|
|
11298
|
-
"bridge returned an unparseable envelope for explain",
|
|
11299
|
-
"Check that the Python child is healthy."
|
|
11300
|
-
);
|
|
11301
|
-
}
|
|
11302
11353
|
function errorEnvelope11(code, message, hint, kind = "client", extra = {}) {
|
|
11303
11354
|
return {
|
|
11304
11355
|
tool: "explain",
|
|
@@ -11856,9 +11907,6 @@ async function runRecall(args, opts) {
|
|
|
11856
11907
|
if (k < 1) k = 1;
|
|
11857
11908
|
if (k > 50) k = 50;
|
|
11858
11909
|
if (!opts.storage) {
|
|
11859
|
-
if (opts.bridge && opts.bridge.toolNames.has("recall")) {
|
|
11860
|
-
return await deferRecall(args, opts.bridge);
|
|
11861
|
-
}
|
|
11862
11910
|
return errorEnvelope12(
|
|
11863
11911
|
"RECALL_STORAGE_UNAVAILABLE",
|
|
11864
11912
|
"recall needs the local database, which isn't available",
|
|
@@ -11911,21 +11959,6 @@ async function runRecall(args, opts) {
|
|
|
11911
11959
|
applied_filters: applied
|
|
11912
11960
|
};
|
|
11913
11961
|
}
|
|
11914
|
-
async function deferRecall(args, bridge) {
|
|
11915
|
-
const r = await bridge.callTool("recall", args);
|
|
11916
|
-
const text = r.content[0]?.text;
|
|
11917
|
-
if (typeof text === "string") {
|
|
11918
|
-
try {
|
|
11919
|
-
return JSON.parse(text);
|
|
11920
|
-
} catch {
|
|
11921
|
-
}
|
|
11922
|
-
}
|
|
11923
|
-
return errorEnvelope12(
|
|
11924
|
-
"RECALL_BRIDGE_BAD_ENVELOPE",
|
|
11925
|
-
"bridge returned an unparseable envelope for recall",
|
|
11926
|
-
"Check that the Python child is healthy."
|
|
11927
|
-
);
|
|
11928
|
-
}
|
|
11929
11962
|
function errorEnvelope12(code, message, hint) {
|
|
11930
11963
|
return {
|
|
11931
11964
|
tool: "recall",
|
|
@@ -11949,9 +11982,6 @@ async function runRecommendPanel(args, opts) {
|
|
|
11949
11982
|
);
|
|
11950
11983
|
}
|
|
11951
11984
|
if (!opts.storage) {
|
|
11952
|
-
if (opts.bridge && opts.bridge.toolNames.has("recommend_panel")) {
|
|
11953
|
-
return await deferRecommendPanel(args, opts.bridge);
|
|
11954
|
-
}
|
|
11955
11985
|
return errorEnvelope13(
|
|
11956
11986
|
"RECOMMEND_PANEL_STORAGE_UNAVAILABLE",
|
|
11957
11987
|
"recommend_panel needs the local stats database, which isn't available",
|
|
@@ -12014,21 +12044,6 @@ async function runRecommendPanel(args, opts) {
|
|
|
12014
12044
|
meta: result.meta
|
|
12015
12045
|
};
|
|
12016
12046
|
}
|
|
12017
|
-
async function deferRecommendPanel(args, bridge) {
|
|
12018
|
-
const r = await bridge.callTool("recommend_panel", args);
|
|
12019
|
-
const text = r.content[0]?.text;
|
|
12020
|
-
if (typeof text === "string") {
|
|
12021
|
-
try {
|
|
12022
|
-
return JSON.parse(text);
|
|
12023
|
-
} catch {
|
|
12024
|
-
}
|
|
12025
|
-
}
|
|
12026
|
-
return errorEnvelope13(
|
|
12027
|
-
"RECOMMEND_PANEL_BRIDGE_BAD_ENVELOPE",
|
|
12028
|
-
"bridge returned an unparseable envelope for recommend_panel",
|
|
12029
|
-
"Check that the Python child is healthy."
|
|
12030
|
-
);
|
|
12031
|
-
}
|
|
12032
12047
|
function errorEnvelope13(code, message, hint) {
|
|
12033
12048
|
return {
|
|
12034
12049
|
tool: "recommend_panel",
|
|
@@ -12059,9 +12074,6 @@ init_cjs_shims();
|
|
|
12059
12074
|
var import_node_fs12 = require("fs");
|
|
12060
12075
|
async function runScoreboard(args, opts) {
|
|
12061
12076
|
if (!opts.storage) {
|
|
12062
|
-
if (opts.bridge && opts.bridge.toolNames.has("scoreboard")) {
|
|
12063
|
-
return await deferScoreboard(args, opts.bridge);
|
|
12064
|
-
}
|
|
12065
12077
|
return errorEnvelope14(
|
|
12066
12078
|
"SCOREBOARD_STORAGE_UNAVAILABLE",
|
|
12067
12079
|
"scoreboard needs the local stats database, which isn't available",
|
|
@@ -12184,21 +12196,6 @@ function clampInt3(raw, min, max, fallback) {
|
|
|
12184
12196
|
if (!Number.isFinite(n)) return fallback;
|
|
12185
12197
|
return Math.min(max, Math.max(min, Math.trunc(n)));
|
|
12186
12198
|
}
|
|
12187
|
-
async function deferScoreboard(args, bridge) {
|
|
12188
|
-
const r = await bridge.callTool("scoreboard", args);
|
|
12189
|
-
const text = r.content[0]?.text;
|
|
12190
|
-
if (typeof text === "string") {
|
|
12191
|
-
try {
|
|
12192
|
-
return JSON.parse(text);
|
|
12193
|
-
} catch {
|
|
12194
|
-
}
|
|
12195
|
-
}
|
|
12196
|
-
return errorEnvelope14(
|
|
12197
|
-
"SCOREBOARD_BRIDGE_BAD_ENVELOPE",
|
|
12198
|
-
"bridge returned an unparseable envelope for scoreboard",
|
|
12199
|
-
"Check that the Python child is healthy."
|
|
12200
|
-
);
|
|
12201
|
-
}
|
|
12202
12199
|
function errorEnvelope14(code, message, hint) {
|
|
12203
12200
|
return {
|
|
12204
12201
|
tool: "scoreboard",
|
|
@@ -12236,9 +12233,6 @@ async function runSessionMemory(args, opts) {
|
|
|
12236
12233
|
);
|
|
12237
12234
|
}
|
|
12238
12235
|
if (!opts.storage) {
|
|
12239
|
-
if (opts.bridge && opts.bridge.toolNames.has("session_memory")) {
|
|
12240
|
-
return await deferSessionMemory(args, opts.bridge);
|
|
12241
|
-
}
|
|
12242
12236
|
return errorEnvelope15(
|
|
12243
12237
|
"SESSION_MEMORY_STORAGE_UNAVAILABLE",
|
|
12244
12238
|
"session_memory needs the local database, which isn't available",
|
|
@@ -12343,21 +12337,6 @@ function clampInt4(raw, min, max, fallback) {
|
|
|
12343
12337
|
if (!Number.isFinite(n)) return fallback;
|
|
12344
12338
|
return Math.min(max, Math.max(min, Math.trunc(n)));
|
|
12345
12339
|
}
|
|
12346
|
-
async function deferSessionMemory(args, bridge) {
|
|
12347
|
-
const r = await bridge.callTool("session_memory", args);
|
|
12348
|
-
const text = r.content[0]?.text;
|
|
12349
|
-
if (typeof text === "string") {
|
|
12350
|
-
try {
|
|
12351
|
-
return JSON.parse(text);
|
|
12352
|
-
} catch {
|
|
12353
|
-
}
|
|
12354
|
-
}
|
|
12355
|
-
return errorEnvelope15(
|
|
12356
|
-
"SESSION_MEMORY_BRIDGE_BAD_ENVELOPE",
|
|
12357
|
-
"bridge returned an unparseable envelope for session_memory",
|
|
12358
|
-
"Check that the Python child is healthy."
|
|
12359
|
-
);
|
|
12360
|
-
}
|
|
12361
12340
|
function errorEnvelope15(code, message, hint) {
|
|
12362
12341
|
return {
|
|
12363
12342
|
tool: "session_memory",
|
|
@@ -12981,7 +12960,7 @@ var CHECK_INTERVAL_SECONDS = 3 * 24 * 60 * 60;
|
|
|
12981
12960
|
var DEFAULT_PACKAGE = "crosscheck-cli";
|
|
12982
12961
|
var FETCH_TIMEOUT_MS = 3e3;
|
|
12983
12962
|
function engineVersion() {
|
|
12984
|
-
return true ? "0.2.
|
|
12963
|
+
return true ? "0.2.29" : "0.0.0-dev";
|
|
12985
12964
|
}
|
|
12986
12965
|
function defaultUpdateCachePath() {
|
|
12987
12966
|
const base = process.env["CROSSCHECK_DATA_DIR"] || import_node_path13.default.join(import_node_os2.default.homedir() || import_node_os2.default.tmpdir(), ".crosscheck");
|
|
@@ -13755,12 +13734,11 @@ function helpTool() {
|
|
|
13755
13734
|
}
|
|
13756
13735
|
});
|
|
13757
13736
|
}
|
|
13758
|
-
function registerCoreTools(
|
|
13759
|
-
const o = opts && typeof opts === "object" && "toolNames" in opts ? { bridge: opts } : opts;
|
|
13737
|
+
function registerCoreTools(o = {}) {
|
|
13760
13738
|
const tools = /* @__PURE__ */ new Map();
|
|
13761
13739
|
const list = [
|
|
13762
13740
|
pingTool(),
|
|
13763
|
-
verifyTool(o.
|
|
13741
|
+
verifyTool(o.fetchConfig),
|
|
13764
13742
|
pickTool(
|
|
13765
13743
|
o.providers ?? {},
|
|
13766
13744
|
o.providerAllowlist ?? null,
|
|
@@ -13772,7 +13750,6 @@ function registerCoreTools(opts = {}) {
|
|
|
13772
13750
|
auditTool(
|
|
13773
13751
|
o.providers ?? {},
|
|
13774
13752
|
o.providerAllowlist ?? null,
|
|
13775
|
-
o.bridge,
|
|
13776
13753
|
o.transcriptsDir,
|
|
13777
13754
|
o.pricing,
|
|
13778
13755
|
o.storage,
|
|
@@ -13782,7 +13759,6 @@ function registerCoreTools(opts = {}) {
|
|
|
13782
13759
|
conferTool(
|
|
13783
13760
|
o.providers ?? {},
|
|
13784
13761
|
o.providerAllowlist ?? null,
|
|
13785
|
-
o.bridge,
|
|
13786
13762
|
o.moderatorDefault ?? "anthropic",
|
|
13787
13763
|
o.pricing,
|
|
13788
13764
|
o.storage,
|
|
@@ -13795,7 +13771,6 @@ function registerCoreTools(opts = {}) {
|
|
|
13795
13771
|
debateTool(
|
|
13796
13772
|
o.providers ?? {},
|
|
13797
13773
|
o.providerAllowlist ?? null,
|
|
13798
|
-
o.bridge,
|
|
13799
13774
|
buildInnerCallers(o),
|
|
13800
13775
|
o.storage,
|
|
13801
13776
|
o.pricing,
|
|
@@ -13807,7 +13782,6 @@ function registerCoreTools(opts = {}) {
|
|
|
13807
13782
|
coordinateTool(
|
|
13808
13783
|
o.providers ?? {},
|
|
13809
13784
|
o.providerAllowlist ?? null,
|
|
13810
|
-
o.bridge,
|
|
13811
13785
|
buildInnerCallers(o),
|
|
13812
13786
|
o.storage,
|
|
13813
13787
|
o.circuitBreakers,
|
|
@@ -13818,7 +13792,6 @@ function registerCoreTools(opts = {}) {
|
|
|
13818
13792
|
triangulateTool(
|
|
13819
13793
|
o.providers ?? {},
|
|
13820
13794
|
o.providerAllowlist ?? null,
|
|
13821
|
-
o.bridge,
|
|
13822
13795
|
o.storage,
|
|
13823
13796
|
o.circuitBreakers,
|
|
13824
13797
|
o.transcriptsDir,
|
|
@@ -13827,7 +13800,6 @@ function registerCoreTools(opts = {}) {
|
|
|
13827
13800
|
planTool(
|
|
13828
13801
|
o.providers ?? {},
|
|
13829
13802
|
o.providerAllowlist ?? null,
|
|
13830
|
-
o.bridge,
|
|
13831
13803
|
o.storage,
|
|
13832
13804
|
o.circuitBreakers,
|
|
13833
13805
|
o.transcriptsDir,
|
|
@@ -13836,7 +13808,6 @@ function registerCoreTools(opts = {}) {
|
|
|
13836
13808
|
critiqueTool(
|
|
13837
13809
|
o.providers ?? {},
|
|
13838
13810
|
o.providerAllowlist ?? null,
|
|
13839
|
-
o.bridge,
|
|
13840
13811
|
o.storage,
|
|
13841
13812
|
o.circuitBreakers,
|
|
13842
13813
|
o.transcriptsDir,
|
|
@@ -13845,7 +13816,6 @@ function registerCoreTools(opts = {}) {
|
|
|
13845
13816
|
reviewTool(
|
|
13846
13817
|
o.providers ?? {},
|
|
13847
13818
|
o.providerAllowlist ?? null,
|
|
13848
|
-
o.bridge,
|
|
13849
13819
|
o.storage,
|
|
13850
13820
|
o.circuitBreakers,
|
|
13851
13821
|
o.transcriptsDir,
|
|
@@ -13853,25 +13823,23 @@ function registerCoreTools(opts = {}) {
|
|
|
13853
13823
|
),
|
|
13854
13824
|
listProvidersTool(o.providers ?? {}, o.activeProviders ?? null, o.moderatorDefault ?? "anthropic"),
|
|
13855
13825
|
modelsTool(o.providers ?? {}, o.activeProviders ?? null),
|
|
13856
|
-
recallTool(o.storage
|
|
13857
|
-
sessionMemoryTool(o.storage
|
|
13858
|
-
scoreboardTool(o.storage, o.
|
|
13859
|
-
explainTool(o.storage, o.
|
|
13826
|
+
recallTool(o.storage),
|
|
13827
|
+
sessionMemoryTool(o.storage),
|
|
13828
|
+
scoreboardTool(o.storage, o.eventsPath),
|
|
13829
|
+
explainTool(o.storage, o.transcriptsDir),
|
|
13860
13830
|
delegateTool(
|
|
13861
13831
|
o.providers ?? {},
|
|
13862
13832
|
o.providerAllowlist ?? null,
|
|
13863
13833
|
o.storage,
|
|
13864
|
-
o.bridge,
|
|
13865
13834
|
o.moderatorDefault ?? "anthropic"
|
|
13866
13835
|
),
|
|
13867
13836
|
fetchTool(o.storage, o.fetchConfig, o.repoRoot),
|
|
13868
|
-
recommendPanelTool(o.providers ?? {}, o.storage
|
|
13837
|
+
recommendPanelTool(o.providers ?? {}, o.storage),
|
|
13869
13838
|
updateCrosscheckTool(o.repoRoot ?? null),
|
|
13870
13839
|
benchTool(
|
|
13871
13840
|
o.providers ?? {},
|
|
13872
13841
|
o.providerAllowlist ?? null,
|
|
13873
13842
|
o.storage,
|
|
13874
|
-
o.bridge,
|
|
13875
13843
|
o.moderatorDefault ?? "anthropic",
|
|
13876
13844
|
o.benchGoldensDir,
|
|
13877
13845
|
o.circuitBreakers,
|
|
@@ -13882,7 +13850,6 @@ function registerCoreTools(opts = {}) {
|
|
|
13882
13850
|
solveTool(
|
|
13883
13851
|
o.providers ?? {},
|
|
13884
13852
|
o.providerAllowlist ?? null,
|
|
13885
|
-
o.bridge,
|
|
13886
13853
|
o.storage,
|
|
13887
13854
|
o.circuitBreakers,
|
|
13888
13855
|
o.transcriptsDir,
|
|
@@ -13891,7 +13858,6 @@ function registerCoreTools(opts = {}) {
|
|
|
13891
13858
|
orchestrateTool(
|
|
13892
13859
|
o.providers ?? {},
|
|
13893
13860
|
o.providerAllowlist ?? null,
|
|
13894
|
-
o.bridge,
|
|
13895
13861
|
o.moderatorDefault ?? "anthropic",
|
|
13896
13862
|
o.storage,
|
|
13897
13863
|
o.pricing,
|
|
@@ -13938,7 +13904,6 @@ function createTool(o, toolName, cheapDefault) {
|
|
|
13938
13904
|
providers: o.providers ?? {},
|
|
13939
13905
|
allowlist: o.providerAllowlist ?? null,
|
|
13940
13906
|
...o.storage ? { storage: o.storage } : {},
|
|
13941
|
-
...o.bridge ? { bridge: o.bridge } : {},
|
|
13942
13907
|
...o.moderatorDefault ? { moderator: o.moderatorDefault } : {},
|
|
13943
13908
|
...o.fetchConfig ? { fetchConfig: o.fetchConfig } : {},
|
|
13944
13909
|
...o.repoRoot ? { repoRoot: o.repoRoot } : {},
|
|
@@ -13947,7 +13912,7 @@ function createTool(o, toolName, cheapDefault) {
|
|
|
13947
13912
|
})
|
|
13948
13913
|
};
|
|
13949
13914
|
}
|
|
13950
|
-
function orchestrateTool(providers, allowlist,
|
|
13915
|
+
function orchestrateTool(providers, allowlist, moderator, storage, pricing, breakers, transcriptsDir, repoRoot, nodeCache) {
|
|
13951
13916
|
return {
|
|
13952
13917
|
name: "orchestrate",
|
|
13953
13918
|
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.",
|
|
@@ -13972,7 +13937,6 @@ function orchestrateTool(providers, allowlist, bridge, moderator, storage, prici
|
|
|
13972
13937
|
providers,
|
|
13973
13938
|
allowlist,
|
|
13974
13939
|
moderator,
|
|
13975
|
-
...bridge ? { bridge } : {},
|
|
13976
13940
|
...storage ? { storage } : {},
|
|
13977
13941
|
...pricing ? { pricing } : {},
|
|
13978
13942
|
...breakers ? { breakers } : {},
|
|
@@ -13982,7 +13946,7 @@ function orchestrateTool(providers, allowlist, bridge, moderator, storage, prici
|
|
|
13982
13946
|
})
|
|
13983
13947
|
};
|
|
13984
13948
|
}
|
|
13985
|
-
function solveTool(providers, allowlist,
|
|
13949
|
+
function solveTool(providers, allowlist, storage, breakers, transcriptsDir, repoRoot) {
|
|
13986
13950
|
return {
|
|
13987
13951
|
name: "solve",
|
|
13988
13952
|
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.",
|
|
@@ -14004,7 +13968,6 @@ function solveTool(providers, allowlist, bridge, storage, breakers, transcriptsD
|
|
|
14004
13968
|
handler: (args) => runSolve(args, {
|
|
14005
13969
|
providers,
|
|
14006
13970
|
allowlist,
|
|
14007
|
-
...bridge ? { bridge } : {},
|
|
14008
13971
|
...storage ? { storage } : {},
|
|
14009
13972
|
...breakers ? { breakers } : {},
|
|
14010
13973
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -14043,7 +14006,7 @@ function configPinTool(repoRoot, config2, rejectDriftEnv) {
|
|
|
14043
14006
|
}
|
|
14044
14007
|
};
|
|
14045
14008
|
}
|
|
14046
|
-
function benchTool(providers, allowlist, storage,
|
|
14009
|
+
function benchTool(providers, allowlist, storage, moderator, defaultGoldensDir, breakers, transcriptsDir, repoRoot) {
|
|
14047
14010
|
return {
|
|
14048
14011
|
name: "bench",
|
|
14049
14012
|
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).",
|
|
@@ -14062,7 +14025,6 @@ function benchTool(providers, allowlist, storage, bridge, moderator, defaultGold
|
|
|
14062
14025
|
allowlist,
|
|
14063
14026
|
moderator,
|
|
14064
14027
|
...storage ? { storage } : {},
|
|
14065
|
-
...bridge ? { bridge } : {},
|
|
14066
14028
|
...defaultGoldensDir ? { defaultGoldensDir } : {},
|
|
14067
14029
|
...breakers ? { breakers } : {},
|
|
14068
14030
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -14089,7 +14051,7 @@ function updateCrosscheckTool(repoRoot) {
|
|
|
14089
14051
|
}
|
|
14090
14052
|
};
|
|
14091
14053
|
}
|
|
14092
|
-
function recommendPanelTool(providers, storage
|
|
14054
|
+
function recommendPanelTool(providers, storage) {
|
|
14093
14055
|
return {
|
|
14094
14056
|
name: "recommend_panel",
|
|
14095
14057
|
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.",
|
|
@@ -14107,8 +14069,7 @@ function recommendPanelTool(providers, storage, bridge) {
|
|
|
14107
14069
|
},
|
|
14108
14070
|
handler: (args) => runRecommendPanel(args, {
|
|
14109
14071
|
providers,
|
|
14110
|
-
...storage ? { storage } : {}
|
|
14111
|
-
...bridge ? { bridge } : {}
|
|
14072
|
+
...storage ? { storage } : {}
|
|
14112
14073
|
})
|
|
14113
14074
|
};
|
|
14114
14075
|
}
|
|
@@ -14133,7 +14094,7 @@ function fetchTool(storage, fetchConfig, repoRoot) {
|
|
|
14133
14094
|
})
|
|
14134
14095
|
};
|
|
14135
14096
|
}
|
|
14136
|
-
function delegateTool(providers, allowlist, storage,
|
|
14097
|
+
function delegateTool(providers, allowlist, storage, moderator) {
|
|
14137
14098
|
return {
|
|
14138
14099
|
name: "delegate",
|
|
14139
14100
|
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.",
|
|
@@ -14153,12 +14114,11 @@ function delegateTool(providers, allowlist, storage, bridge, moderator) {
|
|
|
14153
14114
|
providers,
|
|
14154
14115
|
allowlist,
|
|
14155
14116
|
moderator,
|
|
14156
|
-
...storage ? { storage } : {}
|
|
14157
|
-
...bridge ? { bridge } : {}
|
|
14117
|
+
...storage ? { storage } : {}
|
|
14158
14118
|
})
|
|
14159
14119
|
};
|
|
14160
14120
|
}
|
|
14161
|
-
function explainTool(storage,
|
|
14121
|
+
function explainTool(storage, transcriptsDir) {
|
|
14162
14122
|
return {
|
|
14163
14123
|
name: "explain",
|
|
14164
14124
|
description: "Replay a session as a navigable tree with cost/latency annotations. Reads usage_log + optionally walks the transcripts directory for per-tool summaries.",
|
|
@@ -14176,12 +14136,11 @@ function explainTool(storage, bridge, transcriptsDir) {
|
|
|
14176
14136
|
},
|
|
14177
14137
|
handler: (args) => runExplain(args, {
|
|
14178
14138
|
...storage ? { storage } : {},
|
|
14179
|
-
...bridge ? { bridge } : {},
|
|
14180
14139
|
...transcriptsDir ? { transcriptsDir } : {}
|
|
14181
14140
|
})
|
|
14182
14141
|
};
|
|
14183
14142
|
}
|
|
14184
|
-
function scoreboardTool(storage,
|
|
14143
|
+
function scoreboardTool(storage, eventsPath) {
|
|
14185
14144
|
return {
|
|
14186
14145
|
name: "scoreboard",
|
|
14187
14146
|
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).",
|
|
@@ -14195,12 +14154,11 @@ function scoreboardTool(storage, bridge, eventsPath) {
|
|
|
14195
14154
|
},
|
|
14196
14155
|
handler: (args) => runScoreboard(args, {
|
|
14197
14156
|
...storage ? { storage } : {},
|
|
14198
|
-
...bridge ? { bridge } : {},
|
|
14199
14157
|
...eventsPath ? { eventsPath } : {}
|
|
14200
14158
|
})
|
|
14201
14159
|
};
|
|
14202
14160
|
}
|
|
14203
|
-
function sessionMemoryTool(storage
|
|
14161
|
+
function sessionMemoryTool(storage) {
|
|
14204
14162
|
return {
|
|
14205
14163
|
name: "session_memory",
|
|
14206
14164
|
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).",
|
|
@@ -14223,15 +14181,14 @@ function sessionMemoryTool(storage, bridge) {
|
|
|
14223
14181
|
required: ["action", "session_id"]
|
|
14224
14182
|
},
|
|
14225
14183
|
handler: (args) => runSessionMemory(args, {
|
|
14226
|
-
...storage ? { storage } : {}
|
|
14227
|
-
...bridge ? { bridge } : {}
|
|
14184
|
+
...storage ? { storage } : {}
|
|
14228
14185
|
})
|
|
14229
14186
|
};
|
|
14230
14187
|
}
|
|
14231
|
-
function recallTool(storage
|
|
14188
|
+
function recallTool(storage) {
|
|
14232
14189
|
return {
|
|
14233
14190
|
name: "recall",
|
|
14234
|
-
description: "Full-text search across persisted transcripts via SQLite FTS5. Returns rows ordered by relevance with a windowed snippet. Requires a wired Storage adapter
|
|
14191
|
+
description: "Full-text search across persisted transcripts via SQLite FTS5. Returns rows ordered by relevance with a windowed snippet. Requires a wired Storage adapter.",
|
|
14235
14192
|
inputSchema: {
|
|
14236
14193
|
type: "object",
|
|
14237
14194
|
additionalProperties: true,
|
|
@@ -14245,8 +14202,7 @@ function recallTool(storage, bridge) {
|
|
|
14245
14202
|
required: ["query"]
|
|
14246
14203
|
},
|
|
14247
14204
|
handler: (args) => runRecall(args, {
|
|
14248
|
-
...storage ? { storage } : {}
|
|
14249
|
-
...bridge ? { bridge } : {}
|
|
14205
|
+
...storage ? { storage } : {}
|
|
14250
14206
|
})
|
|
14251
14207
|
};
|
|
14252
14208
|
}
|
|
@@ -14282,7 +14238,7 @@ function modelsTool(providers, activeProviders) {
|
|
|
14282
14238
|
handler: async (args) => runModels(args, { providers, activeProviders })
|
|
14283
14239
|
};
|
|
14284
14240
|
}
|
|
14285
|
-
function reviewTool(providers, allowlist,
|
|
14241
|
+
function reviewTool(providers, allowlist, storage, breakers, transcriptsDir, repoRoot) {
|
|
14286
14242
|
return {
|
|
14287
14243
|
name: "review",
|
|
14288
14244
|
description: "Have an LLM panel peer-review a code or proposal snippet. Returns the confer envelope (one answer per provider).",
|
|
@@ -14301,7 +14257,6 @@ function reviewTool(providers, allowlist, bridge, storage, breakers, transcripts
|
|
|
14301
14257
|
handler: (args) => runReview(args, {
|
|
14302
14258
|
providers,
|
|
14303
14259
|
allowlist,
|
|
14304
|
-
...bridge ? { bridge } : {},
|
|
14305
14260
|
...storage ? { storage } : {},
|
|
14306
14261
|
...breakers ? { breakers } : {},
|
|
14307
14262
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -14309,7 +14264,7 @@ function reviewTool(providers, allowlist, bridge, storage, breakers, transcripts
|
|
|
14309
14264
|
})
|
|
14310
14265
|
};
|
|
14311
14266
|
}
|
|
14312
|
-
function critiqueTool(providers, allowlist,
|
|
14267
|
+
function critiqueTool(providers, allowlist, storage, breakers, transcriptsDir, repoRoot) {
|
|
14313
14268
|
return {
|
|
14314
14269
|
name: "critique",
|
|
14315
14270
|
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.",
|
|
@@ -14329,7 +14284,6 @@ function critiqueTool(providers, allowlist, bridge, storage, breakers, transcrip
|
|
|
14329
14284
|
handler: (args) => runCritique(args, {
|
|
14330
14285
|
providers,
|
|
14331
14286
|
allowlist,
|
|
14332
|
-
...bridge ? { bridge } : {},
|
|
14333
14287
|
...storage ? { storage } : {},
|
|
14334
14288
|
...breakers ? { breakers } : {},
|
|
14335
14289
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -14337,7 +14291,7 @@ function critiqueTool(providers, allowlist, bridge, storage, breakers, transcrip
|
|
|
14337
14291
|
})
|
|
14338
14292
|
};
|
|
14339
14293
|
}
|
|
14340
|
-
function planTool(providers, allowlist,
|
|
14294
|
+
function planTool(providers, allowlist, storage, breakers, transcriptsDir, repoRoot) {
|
|
14341
14295
|
return {
|
|
14342
14296
|
name: "plan",
|
|
14343
14297
|
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.',
|
|
@@ -14364,7 +14318,6 @@ function planTool(providers, allowlist, bridge, storage, breakers, transcriptsDi
|
|
|
14364
14318
|
handler: (args) => runPlan(args, {
|
|
14365
14319
|
providers,
|
|
14366
14320
|
allowlist,
|
|
14367
|
-
...bridge ? { bridge } : {},
|
|
14368
14321
|
...storage ? { storage } : {},
|
|
14369
14322
|
...breakers ? { breakers } : {},
|
|
14370
14323
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -14372,7 +14325,7 @@ function planTool(providers, allowlist, bridge, storage, breakers, transcriptsDi
|
|
|
14372
14325
|
})
|
|
14373
14326
|
};
|
|
14374
14327
|
}
|
|
14375
|
-
function triangulateTool(providers, allowlist,
|
|
14328
|
+
function triangulateTool(providers, allowlist, storage, breakers, transcriptsDir, repoRoot) {
|
|
14376
14329
|
return {
|
|
14377
14330
|
name: "triangulate",
|
|
14378
14331
|
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.",
|
|
@@ -14393,7 +14346,6 @@ function triangulateTool(providers, allowlist, bridge, storage, breakers, transc
|
|
|
14393
14346
|
handler: (args) => runTriangulate(args, {
|
|
14394
14347
|
providers,
|
|
14395
14348
|
allowlist,
|
|
14396
|
-
...bridge ? { bridge } : {},
|
|
14397
14349
|
...storage ? { storage } : {},
|
|
14398
14350
|
...breakers ? { breakers } : {},
|
|
14399
14351
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -14401,7 +14353,7 @@ function triangulateTool(providers, allowlist, bridge, storage, breakers, transc
|
|
|
14401
14353
|
})
|
|
14402
14354
|
};
|
|
14403
14355
|
}
|
|
14404
|
-
function coordinateTool(providers, allowlist,
|
|
14356
|
+
function coordinateTool(providers, allowlist, innerCallers, storage, breakers, transcriptsDir, repoRoot, workerToolsCfg) {
|
|
14405
14357
|
return {
|
|
14406
14358
|
name: "coordinate",
|
|
14407
14359
|
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).",
|
|
@@ -14426,7 +14378,6 @@ function coordinateTool(providers, allowlist, bridge, innerCallers, storage, bre
|
|
|
14426
14378
|
handler: (args) => runCoordinate(args, {
|
|
14427
14379
|
providers,
|
|
14428
14380
|
allowlist,
|
|
14429
|
-
...bridge ? { bridge } : {},
|
|
14430
14381
|
innerCallers,
|
|
14431
14382
|
...storage ? { storage } : {},
|
|
14432
14383
|
...breakers ? { breakers } : {},
|
|
@@ -14436,7 +14387,7 @@ function coordinateTool(providers, allowlist, bridge, innerCallers, storage, bre
|
|
|
14436
14387
|
})
|
|
14437
14388
|
};
|
|
14438
14389
|
}
|
|
14439
|
-
function debateTool(providers, allowlist,
|
|
14390
|
+
function debateTool(providers, allowlist, innerCallers, storage, pricing, breakers, transcriptsDir, repoRoot, workerToolsCfg) {
|
|
14440
14391
|
return {
|
|
14441
14392
|
name: "debate",
|
|
14442
14393
|
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).",
|
|
@@ -14466,7 +14417,6 @@ function debateTool(providers, allowlist, bridge, innerCallers, storage, pricing
|
|
|
14466
14417
|
handler: (args) => runDebate(args, {
|
|
14467
14418
|
providers,
|
|
14468
14419
|
allowlist,
|
|
14469
|
-
...bridge ? { bridge } : {},
|
|
14470
14420
|
innerCallers,
|
|
14471
14421
|
...storage ? { storage } : {},
|
|
14472
14422
|
...pricing ? { pricing } : {},
|
|
@@ -14486,10 +14436,10 @@ function buildInnerCallers(o) {
|
|
|
14486
14436
|
...o.repoRoot ? { repoRoot: o.repoRoot } : {}
|
|
14487
14437
|
});
|
|
14488
14438
|
}
|
|
14489
|
-
out.verify = (args) => runVerify(args, o.
|
|
14439
|
+
out.verify = (args) => runVerify(args, o.fetchConfig);
|
|
14490
14440
|
return out;
|
|
14491
14441
|
}
|
|
14492
|
-
function conferTool(providers, allowlist,
|
|
14442
|
+
function conferTool(providers, allowlist, moderator, pricing, storage, innerCallers, breakers, transcriptsDir, repoRoot, workerToolsCfg) {
|
|
14493
14443
|
return {
|
|
14494
14444
|
name: "confer",
|
|
14495
14445
|
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).",
|
|
@@ -14516,7 +14466,6 @@ function conferTool(providers, allowlist, bridge, moderator, pricing, storage, i
|
|
|
14516
14466
|
handler: (args) => runConfer(args, {
|
|
14517
14467
|
providers,
|
|
14518
14468
|
allowlist,
|
|
14519
|
-
...bridge ? { bridge } : {},
|
|
14520
14469
|
moderator,
|
|
14521
14470
|
...pricing ? { pricing } : {},
|
|
14522
14471
|
...storage ? { storage } : {},
|
|
@@ -14528,7 +14477,7 @@ function conferTool(providers, allowlist, bridge, moderator, pricing, storage, i
|
|
|
14528
14477
|
})
|
|
14529
14478
|
};
|
|
14530
14479
|
}
|
|
14531
|
-
function auditTool(providers, allowlist,
|
|
14480
|
+
function auditTool(providers, allowlist, transcriptsDir, pricing, storage, breakers, repoRoot) {
|
|
14532
14481
|
return {
|
|
14533
14482
|
name: "audit",
|
|
14534
14483
|
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.",
|
|
@@ -14554,7 +14503,6 @@ function auditTool(providers, allowlist, bridge, transcriptsDir, pricing, storag
|
|
|
14554
14503
|
handler: (args) => runAudit(args, {
|
|
14555
14504
|
providers,
|
|
14556
14505
|
allowlist,
|
|
14557
|
-
...bridge ? { bridge } : {},
|
|
14558
14506
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
14559
14507
|
...pricing ? { pricing } : {},
|
|
14560
14508
|
...storage ? { storage } : {},
|
|
@@ -14618,7 +14566,7 @@ function pickTool(providers, allowlist, storage, breakers, transcriptsDir, repoR
|
|
|
14618
14566
|
})
|
|
14619
14567
|
};
|
|
14620
14568
|
}
|
|
14621
|
-
function verifyTool(
|
|
14569
|
+
function verifyTool(fetchConfig) {
|
|
14622
14570
|
return {
|
|
14623
14571
|
name: "verify",
|
|
14624
14572
|
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.",
|
|
@@ -14636,7 +14584,7 @@ function verifyTool(bridge, fetchConfig) {
|
|
|
14636
14584
|
},
|
|
14637
14585
|
required: ["checks"]
|
|
14638
14586
|
},
|
|
14639
|
-
handler: (args) => runVerify(args,
|
|
14587
|
+
handler: (args) => runVerify(args, fetchConfig)
|
|
14640
14588
|
};
|
|
14641
14589
|
}
|
|
14642
14590
|
function pingTool() {
|
|
@@ -14716,18 +14664,18 @@ function attachUpdateNotice(result, toolName, opts) {
|
|
|
14716
14664
|
|
|
14717
14665
|
// src/core/telemetry.ts
|
|
14718
14666
|
init_cjs_shims();
|
|
14719
|
-
var
|
|
14667
|
+
var import_node_crypto11 = __toESM(require("crypto"), 1);
|
|
14720
14668
|
|
|
14721
14669
|
// src/core/segments.ts
|
|
14722
14670
|
init_cjs_shims();
|
|
14723
|
-
var
|
|
14671
|
+
var import_node_crypto10 = __toESM(require("crypto"), 1);
|
|
14724
14672
|
var import_node_fs17 = require("fs");
|
|
14725
14673
|
var import_node_path16 = __toESM(require("path"), 1);
|
|
14726
14674
|
|
|
14727
14675
|
// src/core/git-context.ts
|
|
14728
14676
|
init_cjs_shims();
|
|
14729
14677
|
var import_node_child_process3 = require("child_process");
|
|
14730
|
-
var
|
|
14678
|
+
var import_node_crypto9 = __toESM(require("crypto"), 1);
|
|
14731
14679
|
var TRUNK_BRANCHES = /* @__PURE__ */ new Set([
|
|
14732
14680
|
"main",
|
|
14733
14681
|
"master",
|
|
@@ -14756,7 +14704,7 @@ function repoIdentity(cwd) {
|
|
|
14756
14704
|
return top ? `path:${top}` : null;
|
|
14757
14705
|
}
|
|
14758
14706
|
function fingerprintOf(seatKey, parts) {
|
|
14759
|
-
return
|
|
14707
|
+
return import_node_crypto9.default.createHmac("sha256", seatKey).update(parts.join("\0")).digest("hex");
|
|
14760
14708
|
}
|
|
14761
14709
|
function readGitContext(seatKey, cwd) {
|
|
14762
14710
|
try {
|
|
@@ -14809,7 +14757,7 @@ function canonicalSegmentBody(s) {
|
|
|
14809
14757
|
].join("|");
|
|
14810
14758
|
}
|
|
14811
14759
|
function signSegment(seatKey, s) {
|
|
14812
|
-
return
|
|
14760
|
+
return import_node_crypto10.default.createHmac("sha256", seatKey).update(canonicalSegmentBody(s)).digest("hex");
|
|
14813
14761
|
}
|
|
14814
14762
|
var cfgResolved = false;
|
|
14815
14763
|
var cfg = null;
|
|
@@ -14824,7 +14772,7 @@ function getConfig() {
|
|
|
14824
14772
|
const seatKey = process.env["CROSSCHECK_SEAT_HMAC_KEY"];
|
|
14825
14773
|
if (!base || !seatId || !orgId || !seatKey) return cfg = null;
|
|
14826
14774
|
if (!UUID_RE.test(seatId) || !UUID_RE.test(orgId)) return cfg = null;
|
|
14827
|
-
const sessionId = process.env["CLAUDE_SESSION_ID"] || process.env["CLAUDE_CODE_SESSION_ID"] || `engine-${
|
|
14775
|
+
const sessionId = process.env["CLAUDE_SESSION_ID"] || process.env["CLAUDE_CODE_SESSION_ID"] || `engine-${import_node_crypto10.default.randomUUID()}`;
|
|
14828
14776
|
cfg = {
|
|
14829
14777
|
url: base.replace(/\/telemetry\/?$/, "/segments"),
|
|
14830
14778
|
seatId,
|
|
@@ -14897,7 +14845,7 @@ function syncSegment(cwd) {
|
|
|
14897
14845
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
14898
14846
|
if (current) emit(c, current, now);
|
|
14899
14847
|
current = {
|
|
14900
|
-
segmentId:
|
|
14848
|
+
segmentId: import_node_crypto10.default.randomUUID(),
|
|
14901
14849
|
seq: nextSeq++,
|
|
14902
14850
|
context,
|
|
14903
14851
|
startedAt: now
|
|
@@ -14968,10 +14916,12 @@ function canonicalEventBody(e) {
|
|
|
14968
14916
|
e.status,
|
|
14969
14917
|
e.errorClass ?? ""
|
|
14970
14918
|
].join("|");
|
|
14971
|
-
|
|
14972
|
-
|
|
14973
|
-
|
|
14974
|
-
|
|
14919
|
+
const hasV2 = e.runId !== void 0 || e.purpose !== void 0 || e.fingerprint !== void 0;
|
|
14920
|
+
const hasV3 = e.sessionId !== void 0;
|
|
14921
|
+
if (!hasV2 && !hasV3) return base;
|
|
14922
|
+
const parts = [base, e.runId ?? "", e.purpose ?? "", e.fingerprint ?? ""];
|
|
14923
|
+
if (hasV3) parts.push(e.sessionId ?? "");
|
|
14924
|
+
return parts.join("|");
|
|
14975
14925
|
}
|
|
14976
14926
|
function normalizePurpose(v) {
|
|
14977
14927
|
if (typeof v !== "string") return void 0;
|
|
@@ -14979,7 +14929,7 @@ function normalizePurpose(v) {
|
|
|
14979
14929
|
return /^[a-z0-9][a-z0-9_-]*$/.test(slug) ? slug : void 0;
|
|
14980
14930
|
}
|
|
14981
14931
|
function signEvent(seatSigningKey, e) {
|
|
14982
|
-
return
|
|
14932
|
+
return import_node_crypto11.default.createHmac("sha256", seatSigningKey).update(canonicalEventBody(e)).digest("hex");
|
|
14983
14933
|
}
|
|
14984
14934
|
var configResolved = false;
|
|
14985
14935
|
var config = null;
|
|
@@ -15089,9 +15039,9 @@ function scheduleFlush() {
|
|
|
15089
15039
|
}, FLUSH_INTERVAL_MS);
|
|
15090
15040
|
if (typeof flushTimer.unref === "function") flushTimer.unref();
|
|
15091
15041
|
}
|
|
15092
|
-
function enqueue(cfg2, input, runId, fingerprint) {
|
|
15042
|
+
function enqueue(cfg2, input, runId, fingerprint, sessionId) {
|
|
15093
15043
|
const base = {
|
|
15094
|
-
eventId:
|
|
15044
|
+
eventId: import_node_crypto11.default.randomUUID(),
|
|
15095
15045
|
seatId: cfg2.seatId,
|
|
15096
15046
|
orgId: cfg2.orgId,
|
|
15097
15047
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -15108,6 +15058,7 @@ function enqueue(cfg2, input, runId, fingerprint) {
|
|
|
15108
15058
|
// omitting keeps the JSON honest about what we actually know.
|
|
15109
15059
|
...input.errorClass === void 0 ? {} : { errorClass: input.errorClass },
|
|
15110
15060
|
runId,
|
|
15061
|
+
sessionId,
|
|
15111
15062
|
// Omit entirely (not "") when unknown, so the canonical body stays
|
|
15112
15063
|
// consistent with what the server reconstructs from the JSON.
|
|
15113
15064
|
...input.purpose === void 0 ? {} : { purpose: input.purpose },
|
|
@@ -15122,15 +15073,23 @@ function enqueue(cfg2, input, runId, fingerprint) {
|
|
|
15122
15073
|
if (queue.length >= FLUSH_BATCH_AT) void flush();
|
|
15123
15074
|
else scheduleFlush();
|
|
15124
15075
|
}
|
|
15076
|
+
function sessionIdFromEnvelope(out) {
|
|
15077
|
+
if (!out || typeof out !== "object") return null;
|
|
15078
|
+
const rs = out["run_summary"];
|
|
15079
|
+
if (!rs || typeof rs !== "object") return null;
|
|
15080
|
+
const v = rs["session_id"];
|
|
15081
|
+
return typeof v === "string" && v.trim().length > 0 ? v : null;
|
|
15082
|
+
}
|
|
15125
15083
|
function recordUsage(out, toolName) {
|
|
15126
15084
|
try {
|
|
15127
15085
|
const cfg2 = getConfig2();
|
|
15128
15086
|
if (!cfg2) return;
|
|
15129
15087
|
if (toolName === "update_crosscheck") return;
|
|
15130
|
-
const runId =
|
|
15088
|
+
const runId = import_node_crypto11.default.randomUUID();
|
|
15089
|
+
const sessionId = resolveSessionId(sessionIdFromEnvelope(out));
|
|
15131
15090
|
const fingerprint = currentFingerprint();
|
|
15132
15091
|
for (const ev of usageEventsFromEnvelope(out, toolName)) {
|
|
15133
|
-
enqueue(cfg2, ev, runId, fingerprint);
|
|
15092
|
+
enqueue(cfg2, ev, runId, fingerprint, sessionId);
|
|
15134
15093
|
}
|
|
15135
15094
|
} catch {
|
|
15136
15095
|
}
|
|
@@ -15237,7 +15196,7 @@ function createServer(opts = {}) {
|
|
|
15237
15196
|
throw new Error(`unknown tool: ${name}`);
|
|
15238
15197
|
}
|
|
15239
15198
|
const args = req.params.arguments ?? {};
|
|
15240
|
-
const
|
|
15199
|
+
const startedAt2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
15241
15200
|
const startedHr = process.hrtime.bigint();
|
|
15242
15201
|
const id = nextEventId();
|
|
15243
15202
|
syncSegment(opts.repoRoot);
|
|
@@ -15251,7 +15210,7 @@ function createServer(opts = {}) {
|
|
|
15251
15210
|
event: "tool_invoke",
|
|
15252
15211
|
id,
|
|
15253
15212
|
tool: name,
|
|
15254
|
-
started_at:
|
|
15213
|
+
started_at: startedAt2,
|
|
15255
15214
|
duration_ms: 0,
|
|
15256
15215
|
status: "ok",
|
|
15257
15216
|
args_keys: topLevelKeys(args),
|
|
@@ -15285,7 +15244,7 @@ function createServer(opts = {}) {
|
|
|
15285
15244
|
event: "tool_invoke",
|
|
15286
15245
|
id,
|
|
15287
15246
|
tool: name,
|
|
15288
|
-
started_at:
|
|
15247
|
+
started_at: startedAt2,
|
|
15289
15248
|
duration_ms: durationMs,
|
|
15290
15249
|
status: "ok",
|
|
15291
15250
|
args_keys: topLevelKeys(args),
|
|
@@ -15307,7 +15266,7 @@ function createServer(opts = {}) {
|
|
|
15307
15266
|
event: "tool_invoke",
|
|
15308
15267
|
id,
|
|
15309
15268
|
tool: name,
|
|
15310
|
-
started_at:
|
|
15269
|
+
started_at: startedAt2,
|
|
15311
15270
|
duration_ms: durationMs,
|
|
15312
15271
|
status: "error",
|
|
15313
15272
|
args_keys: topLevelKeys(args),
|
|
@@ -15338,7 +15297,6 @@ async function connectAndServe(transport, opts = {}) {
|
|
|
15338
15297
|
}
|
|
15339
15298
|
function buildToolRegistry(opts) {
|
|
15340
15299
|
const registerOpts = {};
|
|
15341
|
-
if (opts.bridge) registerOpts.bridge = opts.bridge;
|
|
15342
15300
|
if (opts.providers) registerOpts.providers = opts.providers;
|
|
15343
15301
|
if (opts.providerAllowlist !== void 0)
|
|
15344
15302
|
registerOpts.providerAllowlist = opts.providerAllowlist;
|
|
@@ -15355,20 +15313,14 @@ function buildToolRegistry(opts) {
|
|
|
15355
15313
|
if (opts.moderatorDefault) registerOpts.moderatorDefault = opts.moderatorDefault;
|
|
15356
15314
|
if (opts.benchGoldensDir) registerOpts.benchGoldensDir = opts.benchGoldensDir;
|
|
15357
15315
|
if (opts.eventsPath) registerOpts.eventsPath = opts.eventsPath;
|
|
15358
|
-
|
|
15359
|
-
if (!opts.bridge) return tools;
|
|
15360
|
-
const proxies = buildPythonProxies(opts.bridge);
|
|
15361
|
-
for (const [name, proxy] of proxies) {
|
|
15362
|
-
if (!tools.has(name)) tools.set(name, proxy);
|
|
15363
|
-
}
|
|
15364
|
-
return tools;
|
|
15316
|
+
return registerCoreTools(registerOpts);
|
|
15365
15317
|
}
|
|
15366
15318
|
|
|
15367
15319
|
// src/core/config-file.ts
|
|
15368
15320
|
init_cjs_shims();
|
|
15369
15321
|
var import_node_fs18 = require("fs");
|
|
15370
15322
|
var import_node_path17 = __toESM(require("path"), 1);
|
|
15371
|
-
var
|
|
15323
|
+
var import_node_crypto12 = require("crypto");
|
|
15372
15324
|
function asObj(v) {
|
|
15373
15325
|
return v && typeof v === "object" && !Array.isArray(v) ? v : void 0;
|
|
15374
15326
|
}
|
|
@@ -15502,7 +15454,7 @@ function mapConfig(raw, sourcePath) {
|
|
|
15502
15454
|
if (extras && extras.length > 0) cfg2.patterns_extra = extras;
|
|
15503
15455
|
if (bool(red["hmac_tokens"]) === true) {
|
|
15504
15456
|
cfg2.hmac_tokens = true;
|
|
15505
|
-
cfg2.hmac_secret = (0,
|
|
15457
|
+
cfg2.hmac_secret = (0, import_node_crypto12.randomBytes)(32);
|
|
15506
15458
|
}
|
|
15507
15459
|
if (Object.keys(cfg2).length > 0) setRedactionConfig(cfg2);
|
|
15508
15460
|
}
|
|
@@ -15536,14 +15488,39 @@ function loadConfigFile(opts) {
|
|
|
15536
15488
|
return mapConfig(obj, file);
|
|
15537
15489
|
}
|
|
15538
15490
|
|
|
15491
|
+
// src/core/process-registry.ts
|
|
15492
|
+
init_cjs_shims();
|
|
15493
|
+
var import_node_fs19 = require("fs");
|
|
15494
|
+
var import_node_os3 = __toESM(require("os"), 1);
|
|
15495
|
+
var import_node_path18 = __toESM(require("path"), 1);
|
|
15496
|
+
function registryDir(env = process.env) {
|
|
15497
|
+
const base = env["CROSSCHECK_DATA_DIR"] || import_node_path18.default.join(env["HOME"] ?? env["USERPROFILE"] ?? import_node_os3.default.homedir(), ".crosscheck");
|
|
15498
|
+
return import_node_path18.default.join(base, "procs");
|
|
15499
|
+
}
|
|
15500
|
+
function registerProcess(rec, env = process.env) {
|
|
15501
|
+
try {
|
|
15502
|
+
const dir = registryDir(env);
|
|
15503
|
+
(0, import_node_fs19.mkdirSync)(dir, { recursive: true, mode: 448 });
|
|
15504
|
+
(0, import_node_fs19.writeFileSync)(import_node_path18.default.join(dir, `${rec.pid}.json`), JSON.stringify(rec), { mode: 384 });
|
|
15505
|
+
} catch {
|
|
15506
|
+
}
|
|
15507
|
+
}
|
|
15508
|
+
function unregisterProcess(pid = process.pid, env = process.env) {
|
|
15509
|
+
try {
|
|
15510
|
+
(0, import_node_fs19.rmSync)(import_node_path18.default.join(registryDir(env), `${pid}.json`), { force: true });
|
|
15511
|
+
} catch {
|
|
15512
|
+
}
|
|
15513
|
+
}
|
|
15514
|
+
|
|
15539
15515
|
// src/entrypoints/node-stdio.ts
|
|
15516
|
+
var HERE = typeof __dirname !== "undefined" ? __dirname : import_node_path19.default.dirname((0, import_node_url2.fileURLToPath)(importMetaUrl));
|
|
15540
15517
|
var SHUTDOWN_TIMEOUT_MS = 2e3;
|
|
15541
15518
|
async function main() {
|
|
15542
15519
|
enforceLicenseOrExit();
|
|
15543
|
-
const cfgDataDir = process.env["CROSSCHECK_DATA_DIR"] ||
|
|
15520
|
+
const cfgDataDir = process.env["CROSSCHECK_DATA_DIR"] || import_node_path19.default.join(process.env["HOME"] ?? process.env["USERPROFILE"] ?? "", ".crosscheck");
|
|
15544
15521
|
const configFile = loadConfigFile({
|
|
15545
15522
|
startDir: process.cwd(),
|
|
15546
|
-
repoRoot: findGitRoot(
|
|
15523
|
+
repoRoot: findGitRoot(HERE),
|
|
15547
15524
|
dataDir: cfgDataDir
|
|
15548
15525
|
});
|
|
15549
15526
|
if (configFile) {
|
|
@@ -15557,15 +15534,17 @@ async function main() {
|
|
|
15557
15534
|
`);
|
|
15558
15535
|
}
|
|
15559
15536
|
setEventEmitter(buildDefaultEmitter(process.env));
|
|
15560
|
-
if (process.env["CROSSCHECK_BRIDGE_PYTHON"] === "1") {
|
|
15561
|
-
process.stderr.write(
|
|
15562
|
-
"crosscheck-agent: CROSSCHECK_BRIDGE_PYTHON is deprecated and ignored \u2014 the engine is native-only.\n"
|
|
15563
|
-
);
|
|
15564
|
-
}
|
|
15565
15537
|
installShutdownHandlers();
|
|
15538
|
+
registerProcess({
|
|
15539
|
+
pid: process.pid,
|
|
15540
|
+
version: SERVER_VERSION,
|
|
15541
|
+
startedAt: Date.now(),
|
|
15542
|
+
ppid: process.ppid,
|
|
15543
|
+
sessionId: engineSessionId()
|
|
15544
|
+
});
|
|
15566
15545
|
const bundledPricing = (() => {
|
|
15567
15546
|
try {
|
|
15568
|
-
return
|
|
15547
|
+
return import_node_path19.default.join(import_node_path19.default.dirname((0, import_node_url2.fileURLToPath)(importMetaUrl)), "pricing.json");
|
|
15569
15548
|
} catch {
|
|
15570
15549
|
return void 0;
|
|
15571
15550
|
}
|
|
@@ -15574,7 +15553,7 @@ async function main() {
|
|
|
15574
15553
|
process.env["CROSSCHECK_PRICING_PATH"],
|
|
15575
15554
|
resolveRepoFile("config/pricing.json"),
|
|
15576
15555
|
bundledPricing
|
|
15577
|
-
].find((p) => p && (0,
|
|
15556
|
+
].find((p) => p && (0, import_node_fs20.existsSync)(p));
|
|
15578
15557
|
const pricing = pricingPath ? loadPricing(pricingPath) : {};
|
|
15579
15558
|
const providers = buildProviders({ env: process.env, pricing });
|
|
15580
15559
|
if (Object.keys(providers).length > 0) {
|
|
@@ -15592,10 +15571,10 @@ async function main() {
|
|
|
15592
15571
|
}
|
|
15593
15572
|
let storage;
|
|
15594
15573
|
if (process.env["CROSSCHECK_DB_DISABLED"] !== "1") {
|
|
15595
|
-
const dbPath = process.env["CROSSCHECK_DB_PATH"] ?? resolveRepoFile(".crosscheck/db.sqlite") ??
|
|
15574
|
+
const dbPath = process.env["CROSSCHECK_DB_PATH"] ?? resolveRepoFile(".crosscheck/db.sqlite") ?? import_node_path19.default.join(cfgDataDir, "db.sqlite");
|
|
15596
15575
|
if (dbPath) {
|
|
15597
15576
|
try {
|
|
15598
|
-
(0,
|
|
15577
|
+
(0, import_node_fs20.mkdirSync)(import_node_path19.default.dirname(dbPath), { recursive: true });
|
|
15599
15578
|
const { openBetterSqliteStorage: openBetterSqliteStorage2 } = await Promise.resolve().then(() => (init_better_sqlite3(), better_sqlite3_exports));
|
|
15600
15579
|
storage = openBetterSqliteStorage2({ path: dbPath });
|
|
15601
15580
|
await storage.migrate();
|
|
@@ -15613,7 +15592,7 @@ async function main() {
|
|
|
15613
15592
|
}
|
|
15614
15593
|
}
|
|
15615
15594
|
const transcriptsDir = configFile?.logTranscripts === false ? void 0 : process.env["CROSSCHECK_TRANSCRIPTS_DIR"] ?? configFile?.transcriptsDir ?? resolveRepoFile(".crosscheck/transcripts");
|
|
15616
|
-
const repoRoot = process.env["CROSSCHECK_REPO_ROOT"] ?? findGitRoot(
|
|
15595
|
+
const repoRoot = process.env["CROSSCHECK_REPO_ROOT"] ?? findGitRoot(HERE);
|
|
15617
15596
|
const transport = new import_stdio.StdioServerTransport();
|
|
15618
15597
|
const serverOpts = { providers };
|
|
15619
15598
|
if (storage) serverOpts.storage = storage;
|
|
@@ -15643,6 +15622,7 @@ function installShutdownHandlers() {
|
|
|
15643
15622
|
new Promise((resolve2) => setTimeout(resolve2, SHUTDOWN_TIMEOUT_MS))
|
|
15644
15623
|
]).catch(() => {
|
|
15645
15624
|
});
|
|
15625
|
+
unregisterProcess();
|
|
15646
15626
|
process.stderr.write(`crosscheck-agent: shutdown (${reason})
|
|
15647
15627
|
`);
|
|
15648
15628
|
process.exit(0);
|
|
@@ -15661,11 +15641,11 @@ function installShutdownHandlers() {
|
|
|
15661
15641
|
});
|
|
15662
15642
|
}
|
|
15663
15643
|
function resolveRepoFile(rel) {
|
|
15664
|
-
let dir =
|
|
15644
|
+
let dir = HERE;
|
|
15665
15645
|
for (let i = 0; i < 8; i++) {
|
|
15666
|
-
const candidate =
|
|
15667
|
-
if ((0,
|
|
15668
|
-
const parent =
|
|
15646
|
+
const candidate = import_node_path19.default.join(dir, rel);
|
|
15647
|
+
if ((0, import_node_fs20.existsSync)(candidate)) return candidate;
|
|
15648
|
+
const parent = import_node_path19.default.dirname(dir);
|
|
15669
15649
|
if (parent === dir) break;
|
|
15670
15650
|
dir = parent;
|
|
15671
15651
|
}
|
|
@@ -15674,8 +15654,8 @@ function resolveRepoFile(rel) {
|
|
|
15674
15654
|
function findGitRoot(startDir) {
|
|
15675
15655
|
let dir = startDir;
|
|
15676
15656
|
for (let i = 0; i < 12; i++) {
|
|
15677
|
-
if ((0,
|
|
15678
|
-
const parent =
|
|
15657
|
+
if ((0, import_node_fs20.existsSync)(import_node_path19.default.join(dir, ".git"))) return dir;
|
|
15658
|
+
const parent = import_node_path19.default.dirname(dir);
|
|
15679
15659
|
if (parent === dir) break;
|
|
15680
15660
|
dir = parent;
|
|
15681
15661
|
}
|
|
@@ -15685,7 +15665,7 @@ var isMainEntry = (() => {
|
|
|
15685
15665
|
try {
|
|
15686
15666
|
const argv1 = process.argv[1];
|
|
15687
15667
|
if (!argv1) return false;
|
|
15688
|
-
return /(?:\/|\\)node-stdio\.(?:js|cjs|mjs)$/.test(argv1);
|
|
15668
|
+
return /(?:\/|\\)node-stdio\.(?:js|cjs|mjs|ts)$/.test(argv1);
|
|
15689
15669
|
} catch {
|
|
15690
15670
|
return false;
|
|
15691
15671
|
}
|