crosscheck-mcp 0.2.27 → 0.2.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -20
- package/dist/browser-ext.cjs +289 -351
- package/dist/browser-ext.cjs.map +1 -1
- package/dist/browser-ext.js +274 -336
- package/dist/browser-ext.js.map +1 -1
- package/dist/embed.cjs +334 -370
- package/dist/embed.cjs.map +1 -1
- package/dist/embed.d.cts +58 -1
- package/dist/embed.d.ts +58 -1
- package/dist/embed.js +312 -351
- package/dist/embed.js.map +1 -1
- package/dist/node-stdio.cjs +356 -464
- package/dist/node-stdio.cjs.map +1 -1
- package/dist/node-stdio.d.cts +11 -47
- package/dist/node-stdio.d.ts +11 -47
- package/dist/node-stdio.js +327 -435
- 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/package.json +7 -2
package/dist/browser-ext.cjs
CHANGED
|
@@ -48,20 +48,24 @@ var pricing_default = {
|
|
|
48
48
|
notes: "Prices reflect public list pricing per provider. cached_per_1k applies to prompt tokens served from prompt-cache (Anthropic) or input-cache (OpenAI) when supported. Update when providers change rates. Missing models fall back to cost=0 with estimated=true. 2026-06-07: removed decommissioned gemini-2.0-flash / gemini-2.0-flash-lite (Google returns 404) and replaced the low-tier lite model with gemini-2.5-flash-lite. 2026-06-08: bumped the default Anthropic model to claude-opus-4-8. Kept gemini-2.5-pro as the Gemini default (gemini-3.1-pro-preview measured ~2.2x the cost at $2/$12 per M \u2014 output-token dominated by ~1.5k thinking tokens \u2014 so not worth it for a 1-of-4 panel voice). 2026-06-09: corrected rates verified against live provider pricing pages \u2014 gemini-2.5-pro output $5->$10/M; gemini-2.5-flash $0.15/$0.60 -> $0.30/$2.50; gpt-5 $5/$15 -> $1.25/$10 (cached $0.125); grok-4-latest input $5->$3/M (legacy grok-4 tier). Anthropic opus/sonnet/haiku rates confirmed unchanged. Older/unused models (gpt-4o, o1, o3, grok-3) not all re-verified. 2026-07-02: added claude-fable-5 as the optional reasoning-upgrade model (used only for the lead reasoning seat when the operator bumps a heavy task). 2026-07-04: set claude-fable-5 to its real pay-as-you-go API price effective 2026-07-07 \u2014 $10/M input ($0.01/1k), $50/M output ($0.05/1k), cached at 10% of input ($0.001/1k). Dropped the estimated flag. Note: Fable 5 is cheaper than opus-4-8 on both input and output. 2026-07-09: Google retired gemini-2.5-pro AND gemini-3-pro-preview (both now 404 'no longer available'). Moved the Gemini default to gemini-3.1-pro-preview ($2/M in, $12/M out, cache $0.20/M \u2014 the newest working pro; note it's a preview and may need another bump) and added gemini-3.5-flash ($1.50/M in, $9/M out, cache $0.15/M \u2014 GA) to the low/cheap tier. Removed the dead gemini-2.5-pro rate. IMPORTANT: gemini-3.x are heavy thinking models \u2014 thoughtsTokenCount (billed as output) is now folded into completion_tokens in the adapter, so cost reflects reasoning tokens. 2026-07-13: bumped the default OpenAI model to gpt-5.5 ($5/M in, $30/M out, cached $0.50/M \u2014 verified live). Note gpt-5.5 is markedly pricier than gpt-5 ($1.25/$10): ~4x input, 3x output. Kept gpt-5 in the table for cost lookups on pinned installs. 2026-07-16: added gpt-5.6 at the Sol (flagship) tier \u2014 $5/M in, $30/M out, cached $0.50/M (cache-write $6.25/M not modeled). gpt-5.6 is the second premium voice for the max-reasoning co-reasoner (runs alongside claude-fable-5 when an OpenAI key is set). Terra/Luna tiers not added (unused). 2026-07-17: added Moonshot AI (Kimi) provider with kimi-k3, base URL https://api.moonshot.ai/v1. Confirmed real rates \u2014 $3.00/M input (cache miss, $0.003/1k), $15.00/M output ($0.015/1k), $0.30/M cache-hit input ($0.0003/1k); 1M-token context. Kimi K3 is reasoning-class (temperature must be 1; uses max_completion_tokens). 2026-07-24: added claude-opus-5 ($5/M in, $25/M out, cached $0.50/M -- 10% of input, matching this table's existing cache-discount ratio) and made it the default anthropic model (was claude-opus-4-8). Fable 5 remains the reasoning-upgrade/super-mode target, unchanged. 2026-08-04: added Alibaba Cloud Qwen provider (OpenAI-compatible, DashScope international endpoint https://dashscope-intl.aliyuncs.com/compatible-mode/v1) with default model qwen3.8-max -- confirmed business pricing $2.00/M input ($0.002/1k), $6.00/M output ($0.006/1k), cache estimated at 10% of input ($0.0002/1k, not independently confirmed). Also added qwen3.7-max as a fallback tier at $1.25/M in ($0.00125/1k) / $3.75/M out ($0.00375/1k). Note: the model string initially configured (qwen-v3.8 / qwen-v3.7) does not exist on DashScope and 404s -- live-probed the real key against qwen3.8-max, qwen3.7-max, qwen3-max, qwen-max, and qwen-plus, all of which work; corrected the default and pricing keys to qwen3.8-max/qwen3.7-max and fixed QWEN_MODEL in both .env files to match. Qwen's Max tier is a standard instruct model, not reasoning-class -- normal temperature/max_tokens handling. 2026-09-06: added gpt-6-astra at published list rates ($10/$50 per Mtok, $1/Mtok cache read; the $12.50/Mtok cache-WRITE rate has no field in this schema and is not modelled). gemini-3.8-flash now carries Google's published paid-tier rates ($0.75/$3.75/$0.075 per Mtok). THESE DOUBLE ON 2027-01-01 ($1.50/$7.50/$0.15) and this schema has no effective-date support, so they must be updated by hand on that date or every Gemini cost will read half of actual. claude-fable-5-1 now carries published rates ($10/$50/$0.25 per Mtok). Note its cache-read rate is 4x cheaper than claude-fable-5's, so the two must not be assumed to track each other. No inferred rows remain. All three were previously absent, which silently recorded their cost as $0."
|
|
49
49
|
},
|
|
50
50
|
anthropic: {
|
|
51
|
+
_source: {
|
|
52
|
+
url: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
53
|
+
verified_at: "2026-09-27"
|
|
54
|
+
},
|
|
51
55
|
"claude-opus-4-5": {
|
|
52
|
-
prompt_per_1k:
|
|
53
|
-
completion_per_1k: 0.
|
|
54
|
-
cached_per_1k:
|
|
56
|
+
prompt_per_1k: 5e-3,
|
|
57
|
+
completion_per_1k: 0.025,
|
|
58
|
+
cached_per_1k: 5e-4
|
|
55
59
|
},
|
|
56
60
|
"claude-opus-4-7": {
|
|
57
|
-
prompt_per_1k:
|
|
58
|
-
completion_per_1k: 0.
|
|
59
|
-
cached_per_1k:
|
|
61
|
+
prompt_per_1k: 5e-3,
|
|
62
|
+
completion_per_1k: 0.025,
|
|
63
|
+
cached_per_1k: 5e-4
|
|
60
64
|
},
|
|
61
65
|
"claude-opus-4-8": {
|
|
62
|
-
prompt_per_1k:
|
|
63
|
-
completion_per_1k: 0.
|
|
64
|
-
cached_per_1k:
|
|
66
|
+
prompt_per_1k: 5e-3,
|
|
67
|
+
completion_per_1k: 0.025,
|
|
68
|
+
cached_per_1k: 5e-4
|
|
65
69
|
},
|
|
66
70
|
"claude-opus-5-5": {
|
|
67
71
|
prompt_per_1k: 4e-3,
|
|
@@ -110,6 +114,10 @@ var pricing_default = {
|
|
|
110
114
|
}
|
|
111
115
|
},
|
|
112
116
|
openai: {
|
|
117
|
+
_source: {
|
|
118
|
+
url: "https://developers.openai.com/api/docs/pricing",
|
|
119
|
+
verified_at: "2026-09-27"
|
|
120
|
+
},
|
|
113
121
|
"gpt-6-astra": {
|
|
114
122
|
prompt_per_1k: 0.01,
|
|
115
123
|
completion_per_1k: 0.05,
|
|
@@ -194,6 +202,36 @@ var pricing_default = {
|
|
|
194
202
|
prompt_per_1k: 11e-4,
|
|
195
203
|
completion_per_1k: 44e-4,
|
|
196
204
|
cached_per_1k: 55e-5
|
|
205
|
+
},
|
|
206
|
+
"gpt-5-pro": {
|
|
207
|
+
prompt_per_1k: 0.015,
|
|
208
|
+
completion_per_1k: 0.12,
|
|
209
|
+
cached_per_1k: 0
|
|
210
|
+
},
|
|
211
|
+
"gpt-5.2-pro": {
|
|
212
|
+
prompt_per_1k: 0.021,
|
|
213
|
+
completion_per_1k: 0.168,
|
|
214
|
+
cached_per_1k: 0
|
|
215
|
+
},
|
|
216
|
+
"gpt-5.4-pro": {
|
|
217
|
+
prompt_per_1k: 0.03,
|
|
218
|
+
completion_per_1k: 0.18,
|
|
219
|
+
cached_per_1k: 0
|
|
220
|
+
},
|
|
221
|
+
"gpt-5.5-pro": {
|
|
222
|
+
prompt_per_1k: 0.03,
|
|
223
|
+
completion_per_1k: 0.18,
|
|
224
|
+
cached_per_1k: 0
|
|
225
|
+
},
|
|
226
|
+
"o1-pro": {
|
|
227
|
+
prompt_per_1k: 0.15,
|
|
228
|
+
completion_per_1k: 0.6,
|
|
229
|
+
cached_per_1k: 0
|
|
230
|
+
},
|
|
231
|
+
"o3-pro": {
|
|
232
|
+
prompt_per_1k: 0.02,
|
|
233
|
+
completion_per_1k: 0.08,
|
|
234
|
+
cached_per_1k: 0
|
|
197
235
|
}
|
|
198
236
|
},
|
|
199
237
|
xai: {
|
|
@@ -428,20 +466,30 @@ function modelPricing(pricing, provider, model) {
|
|
|
428
466
|
const block = pricing[provider];
|
|
429
467
|
if (!block || typeof block !== "object" || Array.isArray(block)) return null;
|
|
430
468
|
const table = block;
|
|
469
|
+
if (model.startsWith("_")) return null;
|
|
431
470
|
let entry = table[model];
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
471
|
+
let match = "exact";
|
|
472
|
+
if (!isRates(entry)) {
|
|
473
|
+
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];
|
|
474
|
+
if (best !== void 0) {
|
|
475
|
+
entry = table[best];
|
|
476
|
+
match = "stamp";
|
|
477
|
+
}
|
|
435
478
|
}
|
|
436
|
-
if (!
|
|
479
|
+
if (!isRates(entry)) return null;
|
|
437
480
|
const e = entry;
|
|
438
481
|
return {
|
|
439
482
|
prompt_per_1k: numberOrZero(e["prompt_per_1k"]),
|
|
440
483
|
completion_per_1k: numberOrZero(e["completion_per_1k"]),
|
|
441
484
|
cached_per_1k: numberOrZero(e["cached_per_1k"]),
|
|
442
|
-
...e["estimated"] === true ? { estimated: true } : {}
|
|
485
|
+
...e["estimated"] === true ? { estimated: true } : {},
|
|
486
|
+
match
|
|
443
487
|
};
|
|
444
488
|
}
|
|
489
|
+
var DATE_STAMP = /^-\d{8}$/;
|
|
490
|
+
function isRates(v) {
|
|
491
|
+
return Boolean(v) && typeof v === "object" && !Array.isArray(v);
|
|
492
|
+
}
|
|
445
493
|
function numberOrZero(v) {
|
|
446
494
|
if (typeof v === "number" && Number.isFinite(v)) return v;
|
|
447
495
|
if (typeof v === "string") {
|
|
@@ -521,8 +569,20 @@ var PROVIDER_CAPS = {
|
|
|
521
569
|
gemini: {
|
|
522
570
|
family: "gemini",
|
|
523
571
|
system_role: "separate",
|
|
524
|
-
|
|
525
|
-
|
|
572
|
+
// No sampling, on any Gemini model. Ignored since 3.6 Flash and rejected
|
|
573
|
+
// by upcoming models (Google, 2026-10). "model" means "omit for reasoning
|
|
574
|
+
// models", and every Gemini model is reasoning-class (below) — so this
|
|
575
|
+
// resolves to never, through the same rule the other providers use. The
|
|
576
|
+
// adapter also never sends it; this keeps the record honest for anything
|
|
577
|
+
// else that reads it.
|
|
578
|
+
supports_temperature: "model",
|
|
579
|
+
// EVERY Gemini model is reasoning-class. The old list named three
|
|
580
|
+
// families and missed gemini-3.8-flash — the DEFAULT — so the default
|
|
581
|
+
// model got the small non-reasoning budgets (768 tokens for an audit)
|
|
582
|
+
// while spending up to ~480 tokens of each call thinking. Google's docs
|
|
583
|
+
// say thinking cannot be switched off on current models, so a list of
|
|
584
|
+
// which ones think is a list that can only ever be incomplete.
|
|
585
|
+
reasoning_prefixes: ["gemini-"]
|
|
526
586
|
},
|
|
527
587
|
// Qwen's "Max" tier (qwen-v3.8, qwen-v3.7) is a standard instruct/chat
|
|
528
588
|
// model, not a visible-reasoning model like QwQ — normal temperature and
|
|
@@ -645,6 +705,73 @@ function httpFailureToProviderError(provider, status, bodyText, retryAfterS, mod
|
|
|
645
705
|
);
|
|
646
706
|
}
|
|
647
707
|
|
|
708
|
+
// src/providers/network-errors.ts
|
|
709
|
+
function codeOf(e) {
|
|
710
|
+
if (!e || typeof e !== "object") return null;
|
|
711
|
+
const c = e.code;
|
|
712
|
+
return typeof c === "string" && c.length > 0 ? c : null;
|
|
713
|
+
}
|
|
714
|
+
function rootCause(e, depth = 0) {
|
|
715
|
+
if (depth > 5 || !e || typeof e !== "object") return e;
|
|
716
|
+
const o = e;
|
|
717
|
+
if (Array.isArray(o.errors) && o.errors.length > 0) {
|
|
718
|
+
const coded = o.errors.find((x) => codeOf(x) !== null);
|
|
719
|
+
return rootCause(coded ?? o.errors[0], depth + 1);
|
|
720
|
+
}
|
|
721
|
+
if (o.cause !== void 0 && o.cause !== null) return rootCause(o.cause, depth + 1);
|
|
722
|
+
return e;
|
|
723
|
+
}
|
|
724
|
+
var BY_CODE = {
|
|
725
|
+
ENOTFOUND: { cause: "dns", detail: "the provider's hostname did not resolve \u2014 DNS, or a typo'd base URL", transient: false, kind: "network" },
|
|
726
|
+
EAI_AGAIN: { cause: "dns", detail: "DNS lookup failed temporarily \u2014 resolver or network is flapping", transient: true, kind: "network" },
|
|
727
|
+
ECONNREFUSED: { cause: "refused", detail: "the connection was refused \u2014 nothing is listening, or a proxy blocked it", transient: false, kind: "network" },
|
|
728
|
+
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" },
|
|
729
|
+
EPIPE: { cause: "reset", detail: "the connection closed while we were still writing", transient: true, kind: "network" },
|
|
730
|
+
ETIMEDOUT: { cause: "connect_timeout", detail: "the connection timed out before it was established", transient: true, kind: "timeout" },
|
|
731
|
+
EHOSTUNREACH: { cause: "unreachable", detail: "no route to the provider \u2014 VPN, or offline", transient: true, kind: "network" },
|
|
732
|
+
ENETUNREACH: { cause: "unreachable", detail: "the network is unreachable \u2014 offline, or a routing change", transient: true, kind: "network" },
|
|
733
|
+
ENETDOWN: { cause: "unreachable", detail: "the local network is down", transient: true, kind: "network" },
|
|
734
|
+
EPROTO: { cause: "tls", detail: "the TLS handshake failed \u2014 an intercepting proxy, or a protocol mismatch", transient: false, kind: "network" },
|
|
735
|
+
ERR_TLS_CERT_ALTNAME_INVALID: { cause: "tls", detail: "the certificate did not match the hostname \u2014 traffic is being intercepted", transient: false, kind: "network" },
|
|
736
|
+
CERT_HAS_EXPIRED: { cause: "tls", detail: "the server certificate has expired, or this machine's clock is wrong", transient: false, kind: "network" },
|
|
737
|
+
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" },
|
|
738
|
+
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" },
|
|
739
|
+
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" },
|
|
740
|
+
UND_ERR_BODY_TIMEOUT: { cause: "read_timeout", detail: "the response body stalled mid-stream", transient: true, kind: "timeout" },
|
|
741
|
+
UND_ERR_SOCKET: { cause: "reset", detail: "the socket closed unexpectedly", transient: true, kind: "network" },
|
|
742
|
+
UND_ERR_ABORTED: { cause: "aborted", detail: "the request was cancelled", transient: false, kind: "network" },
|
|
743
|
+
ABORT_ERR: { cause: "aborted", detail: "the request was cancelled", transient: false, kind: "network" }
|
|
744
|
+
};
|
|
745
|
+
function diagnoseNetworkError(e) {
|
|
746
|
+
const root = rootCause(e);
|
|
747
|
+
const code = codeOf(root) ?? codeOf(e);
|
|
748
|
+
if (code && BY_CODE[code]) return { ...BY_CODE[code], code };
|
|
749
|
+
const name = root && typeof root === "object" ? root.name : void 0;
|
|
750
|
+
if (name === "AbortError" || name === "TimeoutError") {
|
|
751
|
+
return {
|
|
752
|
+
cause: name === "TimeoutError" ? "read_timeout" : "aborted",
|
|
753
|
+
code: code ?? String(name),
|
|
754
|
+
detail: name === "TimeoutError" ? "the request exceeded its timeout" : "the request was cancelled",
|
|
755
|
+
transient: name === "TimeoutError",
|
|
756
|
+
kind: name === "TimeoutError" ? "timeout" : "network"
|
|
757
|
+
};
|
|
758
|
+
}
|
|
759
|
+
return {
|
|
760
|
+
cause: "unknown",
|
|
761
|
+
code,
|
|
762
|
+
detail: code ? `the connection failed with ${code}` : "the connection failed and the underlying error carried no code",
|
|
763
|
+
transient: true,
|
|
764
|
+
kind: "network"
|
|
765
|
+
};
|
|
766
|
+
}
|
|
767
|
+
function looksLikeNetworkFailure(d) {
|
|
768
|
+
return d.code !== null || d.cause !== "unknown";
|
|
769
|
+
}
|
|
770
|
+
function networkErrorMessage(provider, d) {
|
|
771
|
+
const code = d.code ? ` [${d.code}]` : "";
|
|
772
|
+
return `${provider}: ${d.detail}${code}`;
|
|
773
|
+
}
|
|
774
|
+
|
|
648
775
|
// src/providers/retry.ts
|
|
649
776
|
var override = null;
|
|
650
777
|
function resolveRetryConfig() {
|
|
@@ -967,7 +1094,11 @@ async function sendAnthropic(args) {
|
|
|
967
1094
|
try {
|
|
968
1095
|
respLike = await doFetch(url, init);
|
|
969
1096
|
} catch (e) {
|
|
970
|
-
|
|
1097
|
+
const d = diagnoseNetworkError(e);
|
|
1098
|
+
if (!looksLikeNetworkFailure(d)) throw e;
|
|
1099
|
+
throw new ProviderError(d.kind, networkErrorMessage("anthropic", d), {
|
|
1100
|
+
transient: d.transient
|
|
1101
|
+
});
|
|
971
1102
|
}
|
|
972
1103
|
const status = respLike.status;
|
|
973
1104
|
if (status >= 200 && status < 300) {
|
|
@@ -1040,6 +1171,11 @@ function jsonSchemaToGeminiSchema(schema) {
|
|
|
1040
1171
|
}
|
|
1041
1172
|
return out;
|
|
1042
1173
|
}
|
|
1174
|
+
var GEMINI_THINKING_HEADROOM_TOKENS = 16384;
|
|
1175
|
+
function thinkingHeadroom() {
|
|
1176
|
+
const raw = Number(process.env["CROSSCHECK_GEMINI_THINKING_HEADROOM_TOKENS"]);
|
|
1177
|
+
return Number.isFinite(raw) && raw >= 0 ? Math.trunc(raw) : GEMINI_THINKING_HEADROOM_TOKENS;
|
|
1178
|
+
}
|
|
1043
1179
|
function buildGeminiRequest(opts) {
|
|
1044
1180
|
const contents = [];
|
|
1045
1181
|
let systemText = null;
|
|
@@ -1058,8 +1194,9 @@ function buildGeminiRequest(opts) {
|
|
|
1058
1194
|
const body = {
|
|
1059
1195
|
contents,
|
|
1060
1196
|
generationConfig: {
|
|
1061
|
-
|
|
1062
|
-
|
|
1197
|
+
// Answer budget + thinking headroom. No temperature / topP / topK /
|
|
1198
|
+
// thinkingBudget, on any model — see the header note.
|
|
1199
|
+
maxOutputTokens: opts.maxTokens + thinkingHeadroom()
|
|
1063
1200
|
}
|
|
1064
1201
|
};
|
|
1065
1202
|
if (systemText !== null && systemText !== "") {
|
|
@@ -1069,8 +1206,8 @@ function buildGeminiRequest(opts) {
|
|
|
1069
1206
|
body.generationConfig.responseMimeType = "application/json";
|
|
1070
1207
|
body.generationConfig.responseSchema = jsonSchemaToGeminiSchema(opts.jsonSchema);
|
|
1071
1208
|
}
|
|
1072
|
-
const url = `${GEMINI_API_URL_BASE}/${encodeURIComponent(opts.model)}:generateContent
|
|
1073
|
-
return { url, headers: {}, body };
|
|
1209
|
+
const url = `${GEMINI_API_URL_BASE}/${encodeURIComponent(opts.model)}:generateContent`;
|
|
1210
|
+
return { url, headers: { "x-goog-api-key": opts.apiKey }, body };
|
|
1074
1211
|
}
|
|
1075
1212
|
function parseGeminiResponse(opts) {
|
|
1076
1213
|
const r = opts.resp ?? {};
|
|
@@ -1100,16 +1237,19 @@ function parseGeminiResponse(opts) {
|
|
|
1100
1237
|
}
|
|
1101
1238
|
try {
|
|
1102
1239
|
const first = cands[0];
|
|
1103
|
-
const
|
|
1104
|
-
const
|
|
1240
|
+
const finishReason = typeof first["finishReason"] === "string" ? first["finishReason"] : void 0;
|
|
1241
|
+
const content = first["content"] ?? {};
|
|
1242
|
+
const parts = Array.isArray(content["parts"]) ? content["parts"] : [];
|
|
1105
1243
|
let text = "";
|
|
1106
1244
|
for (const p of parts) {
|
|
1107
1245
|
if (p && typeof p === "object") {
|
|
1108
|
-
const
|
|
1246
|
+
const part = p;
|
|
1247
|
+
if (part["thought"] === true) continue;
|
|
1248
|
+
const t = part["text"];
|
|
1109
1249
|
if (typeof t === "string") text += t;
|
|
1110
1250
|
}
|
|
1111
1251
|
}
|
|
1112
|
-
return { text, usage };
|
|
1252
|
+
return { text, usage, ...finishReason ? { finishReason } : {} };
|
|
1113
1253
|
} catch (e) {
|
|
1114
1254
|
throw new ProviderError(
|
|
1115
1255
|
"parse",
|
|
@@ -1138,7 +1278,8 @@ async function sendGemini(args) {
|
|
|
1138
1278
|
apiKey: args.apiKey,
|
|
1139
1279
|
messages: args.messages,
|
|
1140
1280
|
maxTokens: args.maxTokens,
|
|
1141
|
-
|
|
1281
|
+
// args.temperature is deliberately NOT forwarded: Gemini ignores it and
|
|
1282
|
+
// upcoming models reject it. See the header note.
|
|
1142
1283
|
...args.jsonSchema ? { jsonSchema: args.jsonSchema } : {}
|
|
1143
1284
|
});
|
|
1144
1285
|
const doFetch = args.fetchImpl ?? globalThis.fetch;
|
|
@@ -1153,7 +1294,11 @@ async function sendGemini(args) {
|
|
|
1153
1294
|
try {
|
|
1154
1295
|
respLike = await doFetch(url, init);
|
|
1155
1296
|
} catch (e) {
|
|
1156
|
-
|
|
1297
|
+
const d = diagnoseNetworkError(e);
|
|
1298
|
+
if (!looksLikeNetworkFailure(d)) throw e;
|
|
1299
|
+
throw new ProviderError(d.kind, networkErrorMessage("gemini", d), {
|
|
1300
|
+
transient: d.transient
|
|
1301
|
+
});
|
|
1157
1302
|
}
|
|
1158
1303
|
const status = respLike.status;
|
|
1159
1304
|
if (status >= 200 && status < 300) {
|
|
@@ -1163,11 +1308,18 @@ async function sendGemini(args) {
|
|
|
1163
1308
|
} catch (e) {
|
|
1164
1309
|
throw new ProviderError("parse", `gemini: response body not JSON: ${e.message}`);
|
|
1165
1310
|
}
|
|
1166
|
-
const { text, usage } = parseGeminiResponse({
|
|
1311
|
+
const { text, usage, finishReason } = parseGeminiResponse({
|
|
1167
1312
|
resp: parsed,
|
|
1168
1313
|
model: args.model,
|
|
1169
1314
|
purpose: args.purpose ?? "worker"
|
|
1170
1315
|
});
|
|
1316
|
+
if (text.trim() === "" && finishReason === "MAX_TOKENS") {
|
|
1317
|
+
throw new ProviderError(
|
|
1318
|
+
"parse",
|
|
1319
|
+
`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.`,
|
|
1320
|
+
{ transient: false }
|
|
1321
|
+
);
|
|
1322
|
+
}
|
|
1171
1323
|
return { text, attempts: 1, usage: applyPricing2(usage, args.pricing) };
|
|
1172
1324
|
}
|
|
1173
1325
|
const bodyText = await respLike.text().catch(() => "");
|
|
@@ -1334,7 +1486,11 @@ async function sendOpenAICompatible(args) {
|
|
|
1334
1486
|
try {
|
|
1335
1487
|
respLike = await doFetch(url, init);
|
|
1336
1488
|
} catch (e) {
|
|
1337
|
-
|
|
1489
|
+
const d = diagnoseNetworkError(e);
|
|
1490
|
+
if (!looksLikeNetworkFailure(d)) throw e;
|
|
1491
|
+
throw new ProviderError(d.kind, networkErrorMessage(args.provider, d), {
|
|
1492
|
+
transient: d.transient
|
|
1493
|
+
});
|
|
1338
1494
|
}
|
|
1339
1495
|
const status = respLike.status;
|
|
1340
1496
|
if (status >= 200 && status < 300) {
|
|
@@ -1508,7 +1664,7 @@ var import_zod = require("zod");
|
|
|
1508
1664
|
|
|
1509
1665
|
// src/server-meta.ts
|
|
1510
1666
|
var SERVER_NAME = "crosscheck-agent";
|
|
1511
|
-
var SERVER_VERSION = true ? "0.2.
|
|
1667
|
+
var SERVER_VERSION = true ? "0.2.28" : "0.0.0-dev";
|
|
1512
1668
|
|
|
1513
1669
|
// src/tools/audit.ts
|
|
1514
1670
|
var import_node_fs4 = require("fs");
|
|
@@ -1731,6 +1887,31 @@ function pyReprType(t) {
|
|
|
1731
1887
|
return String(t);
|
|
1732
1888
|
}
|
|
1733
1889
|
|
|
1890
|
+
// src/core/session.ts
|
|
1891
|
+
var import_node_crypto = require("crypto");
|
|
1892
|
+
var processSessionId = null;
|
|
1893
|
+
var startedAt = null;
|
|
1894
|
+
function engineSessionId() {
|
|
1895
|
+
if (processSessionId === null) {
|
|
1896
|
+
processSessionId = (0, import_node_crypto.randomUUID)();
|
|
1897
|
+
startedAt = Date.now();
|
|
1898
|
+
}
|
|
1899
|
+
return processSessionId;
|
|
1900
|
+
}
|
|
1901
|
+
function resolveSessionId(callerSupplied) {
|
|
1902
|
+
const trimmed = typeof callerSupplied === "string" ? callerSupplied.trim() : "";
|
|
1903
|
+
return trimmed.length > 0 ? trimmed : engineSessionId();
|
|
1904
|
+
}
|
|
1905
|
+
function localSessionRecordingEnabled(env = globalThis.process?.env ?? {}) {
|
|
1906
|
+
const v = (env["CROSSCHECK_RECORD_SESSIONS"] ?? "").trim().toLowerCase();
|
|
1907
|
+
return !["0", "false", "off", "no"].includes(v);
|
|
1908
|
+
}
|
|
1909
|
+
function recordingSessionId(callerSupplied) {
|
|
1910
|
+
if (localSessionRecordingEnabled()) return resolveSessionId(callerSupplied);
|
|
1911
|
+
const trimmed = typeof callerSupplied === "string" ? callerSupplied.trim() : "";
|
|
1912
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
1913
|
+
}
|
|
1914
|
+
|
|
1734
1915
|
// src/core/usage.ts
|
|
1735
1916
|
function emptyUsage(provider, model, purpose = "worker") {
|
|
1736
1917
|
return {
|
|
@@ -1836,11 +2017,11 @@ function withCommas(n) {
|
|
|
1836
2017
|
function renderRunSummary(opts) {
|
|
1837
2018
|
const endedAt = opts.endedAtS ?? Math.trunc(Date.now() / 1e3);
|
|
1838
2019
|
let scope = "call";
|
|
1839
|
-
let
|
|
2020
|
+
let startedAt2 = null;
|
|
1840
2021
|
let rows = [];
|
|
1841
2022
|
if (opts.sessionScope && opts.sessionScope.rows.length > 0) {
|
|
1842
2023
|
scope = "session";
|
|
1843
|
-
|
|
2024
|
+
startedAt2 = opts.sessionScope.startedAt;
|
|
1844
2025
|
rows = opts.sessionScope.rows.map((r) => ({ ...r }));
|
|
1845
2026
|
} else {
|
|
1846
2027
|
const byPurpose = /* @__PURE__ */ new Map();
|
|
@@ -1871,6 +2052,7 @@ function renderRunSummary(opts) {
|
|
|
1871
2052
|
row.cpu_ms += a.cpu_ms ?? 0;
|
|
1872
2053
|
if (a.cache_hit) row.cache_hits += 1;
|
|
1873
2054
|
if (a.error) row.errors += 1;
|
|
2055
|
+
if (a.usage?.estimated) row.estimated = true;
|
|
1874
2056
|
}
|
|
1875
2057
|
rows = Array.from(byPurpose.values());
|
|
1876
2058
|
}
|
|
@@ -1883,16 +2065,18 @@ function renderRunSummary(opts) {
|
|
|
1883
2065
|
wall_ms: rows.reduce((s, r) => s + r.wall_ms, 0),
|
|
1884
2066
|
cpu_ms: rows.reduce((s, r) => s + r.cpu_ms, 0),
|
|
1885
2067
|
cache_hits: rows.reduce((s, r) => s + r.cache_hits, 0),
|
|
1886
|
-
errors: rows.reduce((s, r) => s + r.errors, 0)
|
|
2068
|
+
errors: rows.reduce((s, r) => s + r.errors, 0),
|
|
2069
|
+
...rows.some((r) => r.estimated) ? { estimated: true } : {}
|
|
1887
2070
|
};
|
|
1888
2071
|
const titleLeft = scope === "session" ? `session: ${opts.sessionId ?? ""}` : `call: ${opts.toolName}`;
|
|
1889
|
-
const
|
|
2072
|
+
const costText = totals.estimated ? `$${totals.cost_usd.toFixed(4)}+ (some calls unpriced)` : `$${totals.cost_usd.toFixed(4)}`;
|
|
2073
|
+
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)`;
|
|
1890
2074
|
const bodyLines = [];
|
|
1891
2075
|
for (let i = 0; i < rows.length; i++) {
|
|
1892
2076
|
const r = rows[i];
|
|
1893
2077
|
const glyph = i === rows.length - 1 ? "`-" : "|-";
|
|
1894
2078
|
bodyLines.push(
|
|
1895
|
-
`${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)`
|
|
2079
|
+
`${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)`
|
|
1896
2080
|
);
|
|
1897
2081
|
}
|
|
1898
2082
|
const callByModel = rollupSpendByModel(
|
|
@@ -1940,7 +2124,7 @@ function renderRunSummary(opts) {
|
|
|
1940
2124
|
tool: opts.toolName,
|
|
1941
2125
|
scope,
|
|
1942
2126
|
currency: "USD",
|
|
1943
|
-
started_at:
|
|
2127
|
+
started_at: startedAt2,
|
|
1944
2128
|
ended_at: endedAt,
|
|
1945
2129
|
rows,
|
|
1946
2130
|
totals,
|
|
@@ -2065,14 +2249,15 @@ async function attachUsageBlock(result, answers, opts) {
|
|
|
2065
2249
|
delete result["_suppress_run_summary"];
|
|
2066
2250
|
}
|
|
2067
2251
|
async function appendUsageLog(storage, sessionId, toolName, answers, nowS) {
|
|
2068
|
-
|
|
2252
|
+
const sid = recordingSessionId(sessionId);
|
|
2253
|
+
if (!sid || answers.length === 0) return;
|
|
2069
2254
|
const now = nowS ?? Math.trunc(Date.now() / 1e3);
|
|
2070
2255
|
const rows = [];
|
|
2071
2256
|
for (const a of answers) {
|
|
2072
2257
|
const u = a.usage;
|
|
2073
2258
|
if (!u || typeof u.provider !== "string" || u.provider === "") continue;
|
|
2074
2259
|
rows.push({
|
|
2075
|
-
session_id:
|
|
2260
|
+
session_id: sid,
|
|
2076
2261
|
ts: now,
|
|
2077
2262
|
tool: toolName,
|
|
2078
2263
|
purpose: u.purpose ?? "worker",
|
|
@@ -2095,13 +2280,14 @@ async function appendUsageLog(storage, sessionId, toolName, answers, nowS) {
|
|
|
2095
2280
|
}
|
|
2096
2281
|
}
|
|
2097
2282
|
async function recordSessionCall(storage, sessionId, answers, wallMs, cpuMs, nowS) {
|
|
2098
|
-
|
|
2283
|
+
const sid = recordingSessionId(sessionId);
|
|
2284
|
+
if (!sid) return;
|
|
2099
2285
|
const now = nowS ?? Math.trunc(Date.now() / 1e3);
|
|
2100
2286
|
try {
|
|
2101
|
-
let existing = await storage.getSession(
|
|
2287
|
+
let existing = await storage.getSession(sid);
|
|
2102
2288
|
if (!existing) {
|
|
2103
2289
|
await storage.upsertSession({
|
|
2104
|
-
session_id:
|
|
2290
|
+
session_id: sid,
|
|
2105
2291
|
started_at: now,
|
|
2106
2292
|
last_at: now,
|
|
2107
2293
|
calls: 0,
|
|
@@ -2114,7 +2300,7 @@ async function recordSessionCall(storage, sessionId, answers, wallMs, cpuMs, now
|
|
|
2114
2300
|
total_cost_usd: 0,
|
|
2115
2301
|
total_cpu_ms: 0
|
|
2116
2302
|
});
|
|
2117
|
-
existing = await storage.getSession(
|
|
2303
|
+
existing = await storage.getSession(sid);
|
|
2118
2304
|
}
|
|
2119
2305
|
if (!existing) return;
|
|
2120
2306
|
let promptDelta = 0;
|
|
@@ -2134,7 +2320,7 @@ async function recordSessionCall(storage, sessionId, answers, wallMs, cpuMs, now
|
|
|
2134
2320
|
}
|
|
2135
2321
|
if (a.cache_hit) cacheHitDelta += 1;
|
|
2136
2322
|
}
|
|
2137
|
-
await storage.accumulateSessionTotals(
|
|
2323
|
+
await storage.accumulateSessionTotals(sid, {
|
|
2138
2324
|
calls: answers.length,
|
|
2139
2325
|
wall_ms: wallMs,
|
|
2140
2326
|
cache_hits: cacheHitDelta,
|
|
@@ -2516,7 +2702,7 @@ function buildPersonaInjection(opts) {
|
|
|
2516
2702
|
}
|
|
2517
2703
|
|
|
2518
2704
|
// src/core/canary.ts
|
|
2519
|
-
var
|
|
2705
|
+
var import_node_crypto2 = require("crypto");
|
|
2520
2706
|
|
|
2521
2707
|
// src/core/injection.ts
|
|
2522
2708
|
var INJECTION_PHRASES_RE = new RegExp(
|
|
@@ -2534,8 +2720,8 @@ var UNTRUSTED_SYSTEM_NOTE = "Some inputs in this conversation are wrapped in <un
|
|
|
2534
2720
|
function mintCanary() {
|
|
2535
2721
|
const t = process.hrtime.bigint().toString();
|
|
2536
2722
|
const pid = String(process.pid);
|
|
2537
|
-
const r = (0,
|
|
2538
|
-
const hex = (0,
|
|
2723
|
+
const r = (0, import_node_crypto2.randomBytes)(16).toString("hex");
|
|
2724
|
+
const hex = (0, import_node_crypto2.createHash)("sha256").update(`${t}-${pid}-${r}`).digest("hex").slice(0, 16).toUpperCase();
|
|
2539
2725
|
return `CC_CANARY_${hex}`;
|
|
2540
2726
|
}
|
|
2541
2727
|
function wrapUntrusted(content, canary) {
|
|
@@ -2722,7 +2908,7 @@ var import_node_fs3 = require("fs");
|
|
|
2722
2908
|
var import_node_path2 = __toESM(require("path"), 1);
|
|
2723
2909
|
|
|
2724
2910
|
// src/core/redact.ts
|
|
2725
|
-
var
|
|
2911
|
+
var import_node_crypto3 = require("crypto");
|
|
2726
2912
|
function builtinRedactionRules() {
|
|
2727
2913
|
return [
|
|
2728
2914
|
{ pattern: /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g, label: "EMAIL", prefix_group: false },
|
|
@@ -2749,7 +2935,7 @@ function hmacSuffix(cfg, label, value) {
|
|
|
2749
2935
|
const sid = cfg.session_id ?? "";
|
|
2750
2936
|
const sidBytes = Buffer.from(sid, "utf8");
|
|
2751
2937
|
const key = Buffer.concat([Buffer.from(secret), sidBytes]);
|
|
2752
|
-
const digest = (0,
|
|
2938
|
+
const digest = (0, import_node_crypto3.createHmac)("sha256", key).update(`${label}:${value}`, "utf8").digest("hex");
|
|
2753
2939
|
return digest.slice(0, 8);
|
|
2754
2940
|
}
|
|
2755
2941
|
function redactText(s, cfg) {
|
|
@@ -5066,10 +5252,6 @@ If you need supporting evidence, you may emit ONE \`<tool_call>...</tool_call>\`
|
|
|
5066
5252
|
}
|
|
5067
5253
|
|
|
5068
5254
|
// src/tools/confer.ts
|
|
5069
|
-
var DEFERRED_OPTS = [
|
|
5070
|
-
// empty — every confer opt runs natively except worker_tools, which
|
|
5071
|
-
// is gated below (non-empty list → defer).
|
|
5072
|
-
];
|
|
5073
5255
|
async function runConfer(args, opts) {
|
|
5074
5256
|
const callStartedWall = import_node_perf_hooks2.performance.now();
|
|
5075
5257
|
const callStartedCpu = process.cpuUsage();
|
|
@@ -5085,16 +5267,11 @@ async function runConfer(args, opts) {
|
|
|
5085
5267
|
rejectedWorkerTools.push(t);
|
|
5086
5268
|
}
|
|
5087
5269
|
}
|
|
5088
|
-
|
|
5089
|
-
const needsBridge = DEFERRED_OPTS.some((k) => Boolean(args[k])) || workerToolsNeedsBridge;
|
|
5090
|
-
if (needsBridge) {
|
|
5091
|
-
if (opts.bridge && opts.bridge.toolNames.has("confer")) {
|
|
5092
|
-
return await deferConfer(args, opts.bridge);
|
|
5093
|
-
}
|
|
5270
|
+
if (acceptedWorkerTools.length > 0 && !opts.innerCallers) {
|
|
5094
5271
|
return errorEnvelope2(
|
|
5095
5272
|
"CONFER_OPT_NOT_NATIVE",
|
|
5096
5273
|
"worker_tools requested but innerCallers are not wired",
|
|
5097
|
-
"Native confer covers untrusted_input + early_stop + extract_claims + inject_session_memory + auto_panel. worker_tools needs innerCallers wired by the host
|
|
5274
|
+
"Native confer covers untrusted_input + early_stop + extract_claims + inject_session_memory + auto_panel. worker_tools needs innerCallers wired by the host."
|
|
5098
5275
|
);
|
|
5099
5276
|
}
|
|
5100
5277
|
const question = typeof args["question"] === "string" ? args["question"] : String(args["question"] ?? "");
|
|
@@ -5445,21 +5622,6 @@ function unknownProviderError(unknownNames, available) {
|
|
|
5445
5622
|
available_now: Object.keys(available).sort()
|
|
5446
5623
|
};
|
|
5447
5624
|
}
|
|
5448
|
-
async function deferConfer(args, bridge) {
|
|
5449
|
-
const r = await bridge.callTool("confer", args);
|
|
5450
|
-
const text = r.content[0]?.text;
|
|
5451
|
-
if (typeof text === "string") {
|
|
5452
|
-
try {
|
|
5453
|
-
return JSON.parse(text);
|
|
5454
|
-
} catch {
|
|
5455
|
-
}
|
|
5456
|
-
}
|
|
5457
|
-
return errorEnvelope2(
|
|
5458
|
-
"CONFER_BRIDGE_BAD_ENVELOPE",
|
|
5459
|
-
"bridge returned an unparseable envelope for confer",
|
|
5460
|
-
"Check that the Python child is healthy."
|
|
5461
|
-
);
|
|
5462
|
-
}
|
|
5463
5625
|
function errorEnvelope2(code, message, hint) {
|
|
5464
5626
|
return {
|
|
5465
5627
|
tool: "confer",
|
|
@@ -5831,7 +5993,7 @@ function errorEnvelope3(code, message, hint) {
|
|
|
5831
5993
|
transient: false
|
|
5832
5994
|
};
|
|
5833
5995
|
}
|
|
5834
|
-
async function runVerify(args,
|
|
5996
|
+
async function runVerify(args, fetchConfig) {
|
|
5835
5997
|
const checks = args["checks"];
|
|
5836
5998
|
if (!Array.isArray(checks) || checks.length === 0) {
|
|
5837
5999
|
return {
|
|
@@ -5843,7 +6005,6 @@ async function runVerify(args, bridge, fetchConfig) {
|
|
|
5843
6005
|
)
|
|
5844
6006
|
};
|
|
5845
6007
|
}
|
|
5846
|
-
void bridge;
|
|
5847
6008
|
const allowShell = Boolean(args["allow_shell"] ?? false);
|
|
5848
6009
|
const wallStart = import_node_perf_hooks3.performance.now();
|
|
5849
6010
|
const cpuStart = process.cpuUsage();
|
|
@@ -6145,7 +6306,6 @@ async function runBench(args, opts) {
|
|
|
6145
6306
|
const innerOpts = {
|
|
6146
6307
|
providers: opts.providers,
|
|
6147
6308
|
allowlist: opts.allowlist ?? null,
|
|
6148
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
6149
6309
|
...opts.moderator ? { moderator: opts.moderator } : {}
|
|
6150
6310
|
};
|
|
6151
6311
|
let inner;
|
|
@@ -6357,7 +6517,7 @@ function isObj4(v) {
|
|
|
6357
6517
|
}
|
|
6358
6518
|
|
|
6359
6519
|
// src/tools/config-pin.ts
|
|
6360
|
-
var
|
|
6520
|
+
var import_node_crypto4 = require("crypto");
|
|
6361
6521
|
var import_node_fs6 = require("fs");
|
|
6362
6522
|
var import_node_path6 = __toESM(require("path"), 1);
|
|
6363
6523
|
var DEFAULT_PIN_PATH = ".crosscheck/config_pins.json";
|
|
@@ -6512,7 +6672,7 @@ function hashFile(abs) {
|
|
|
6512
6672
|
return "";
|
|
6513
6673
|
}
|
|
6514
6674
|
const normalized = stripCrBeforeLf(raw);
|
|
6515
|
-
return "sha256:" + (0,
|
|
6675
|
+
return "sha256:" + (0, import_node_crypto4.createHash)("sha256").update(normalized).digest("hex");
|
|
6516
6676
|
}
|
|
6517
6677
|
function stripCrBeforeLf(buf) {
|
|
6518
6678
|
const out = [];
|
|
@@ -6589,7 +6749,7 @@ function pyRepr2(v) {
|
|
|
6589
6749
|
}
|
|
6590
6750
|
|
|
6591
6751
|
// src/tools/create.ts
|
|
6592
|
-
var
|
|
6752
|
+
var import_node_crypto7 = require("crypto");
|
|
6593
6753
|
var import_node_fs9 = require("fs");
|
|
6594
6754
|
var import_node_path9 = __toESM(require("path"), 1);
|
|
6595
6755
|
|
|
@@ -6675,7 +6835,7 @@ function isDeadModelError(err) {
|
|
|
6675
6835
|
}
|
|
6676
6836
|
|
|
6677
6837
|
// src/core/node-cache.ts
|
|
6678
|
-
var
|
|
6838
|
+
var import_node_crypto5 = require("crypto");
|
|
6679
6839
|
var import_node_fs7 = require("fs");
|
|
6680
6840
|
var import_node_path7 = require("path");
|
|
6681
6841
|
var NODE_CACHE_KEY_VERSION = "v2";
|
|
@@ -6702,7 +6862,7 @@ function canonicalizeNodeText(s) {
|
|
|
6702
6862
|
return out;
|
|
6703
6863
|
}
|
|
6704
6864
|
function sha256Hex(s) {
|
|
6705
|
-
return (0,
|
|
6865
|
+
return (0, import_node_crypto5.createHash)("sha256").update(s, "utf8").digest("hex");
|
|
6706
6866
|
}
|
|
6707
6867
|
function nodeCacheKey(node, upstreamOutputs, provider, model) {
|
|
6708
6868
|
const canonUpstream = {};
|
|
@@ -6822,7 +6982,6 @@ var EST_TOKENS = {
|
|
|
6822
6982
|
med: [1500, 800],
|
|
6823
6983
|
high: [2500, 1500]
|
|
6824
6984
|
};
|
|
6825
|
-
var DEFERRED_OPTS2 = [];
|
|
6826
6985
|
var REACTIVE_SIGNAL_RE = /<signals>\s*(\{[\s\S]*?\})\s*<\/signals>/g;
|
|
6827
6986
|
function parseReactiveSignals(output) {
|
|
6828
6987
|
if (typeof output !== "string" || !output.includes("<signals>")) return [];
|
|
@@ -6862,17 +7021,6 @@ async function runOrchestrate(args, opts) {
|
|
|
6862
7021
|
);
|
|
6863
7022
|
if (breakerEnv) return breakerEnv;
|
|
6864
7023
|
}
|
|
6865
|
-
const needsBridge = DEFERRED_OPTS2.some((k) => Boolean(args[k]));
|
|
6866
|
-
if (needsBridge) {
|
|
6867
|
-
if (opts.bridge && opts.bridge.toolNames.has("orchestrate")) {
|
|
6868
|
-
return await deferOrchestrate(args, opts.bridge);
|
|
6869
|
-
}
|
|
6870
|
-
return errorEnvelope5(
|
|
6871
|
-
"ORCHESTRATE_OPT_NOT_NATIVE",
|
|
6872
|
-
"this orchestrate opt-in requires the Python bridge in v1",
|
|
6873
|
-
"v1 native covers the plain DAG flow + cheap_mode. reactive (mid-flight DAG updates) still defers. Set CROSSCHECK_BRIDGE_PYTHON=1 to enable."
|
|
6874
|
-
);
|
|
6875
|
-
}
|
|
6876
7024
|
const goal = typeof args["goal"] === "string" ? args["goal"] : null;
|
|
6877
7025
|
const dagIn = isObj5(args["dag"]) ? args["dag"] : null;
|
|
6878
7026
|
if (goal === null === (dagIn === null)) {
|
|
@@ -7814,21 +7962,6 @@ function resolveProviders3(names, available, allowlist) {
|
|
|
7814
7962
|
}
|
|
7815
7963
|
return out;
|
|
7816
7964
|
}
|
|
7817
|
-
async function deferOrchestrate(args, bridge) {
|
|
7818
|
-
const r = await bridge.callTool("orchestrate", args);
|
|
7819
|
-
const text = r.content[0]?.text;
|
|
7820
|
-
if (typeof text === "string") {
|
|
7821
|
-
try {
|
|
7822
|
-
return JSON.parse(text);
|
|
7823
|
-
} catch {
|
|
7824
|
-
}
|
|
7825
|
-
}
|
|
7826
|
-
return errorEnvelope5(
|
|
7827
|
-
"ORCHESTRATE_BRIDGE_BAD_ENVELOPE",
|
|
7828
|
-
"bridge returned an unparseable envelope for orchestrate",
|
|
7829
|
-
"Check that the Python child is healthy."
|
|
7830
|
-
);
|
|
7831
|
-
}
|
|
7832
7965
|
function errorEnvelope5(code, message, hint, kind = "client") {
|
|
7833
7966
|
return {
|
|
7834
7967
|
tool: "orchestrate",
|
|
@@ -7876,7 +8009,7 @@ function pyRound6(x) {
|
|
|
7876
8009
|
}
|
|
7877
8010
|
|
|
7878
8011
|
// src/tools/fetch.ts
|
|
7879
|
-
var
|
|
8012
|
+
var import_node_crypto6 = require("crypto");
|
|
7880
8013
|
var import_node_fs8 = require("fs");
|
|
7881
8014
|
var import_node_path8 = __toESM(require("path"), 1);
|
|
7882
8015
|
var DEFAULT_CONFIG = {
|
|
@@ -8090,10 +8223,10 @@ function extractHost(url) {
|
|
|
8090
8223
|
}
|
|
8091
8224
|
}
|
|
8092
8225
|
function sha256Hex2(s) {
|
|
8093
|
-
return (0,
|
|
8226
|
+
return (0, import_node_crypto6.createHash)("sha256").update(s, "utf8").digest("hex");
|
|
8094
8227
|
}
|
|
8095
8228
|
function sha256HexBytes(bytes) {
|
|
8096
|
-
return (0,
|
|
8229
|
+
return (0, import_node_crypto6.createHash)("sha256").update(bytes).digest("hex");
|
|
8097
8230
|
}
|
|
8098
8231
|
function resolveEvidenceDir(configured, repoRoot) {
|
|
8099
8232
|
if (import_node_path8.default.isAbsolute(configured)) return configured;
|
|
@@ -8191,7 +8324,6 @@ ${documentsPayload}`;
|
|
|
8191
8324
|
}, {
|
|
8192
8325
|
providers: opts.providers,
|
|
8193
8326
|
allowlist: opts.allowlist ?? null,
|
|
8194
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
8195
8327
|
ctx
|
|
8196
8328
|
});
|
|
8197
8329
|
const scopeAnswer = Array.isArray(scope["answers"]) ? scope["answers"].filter((a) => typeof a["response"] === "string" && a["response"]).map((a) => `[${a["provider"]}]
|
|
@@ -8214,7 +8346,6 @@ ${scopeAnswer || "(none)"}
|
|
|
8214
8346
|
providers: opts.providers,
|
|
8215
8347
|
allowlist: opts.allowlist ?? null,
|
|
8216
8348
|
moderator,
|
|
8217
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
8218
8349
|
ctx
|
|
8219
8350
|
});
|
|
8220
8351
|
let attempts = 1;
|
|
@@ -8249,7 +8380,6 @@ ${scopeAnswer || "(none)"}
|
|
|
8249
8380
|
}, {
|
|
8250
8381
|
providers: opts.providers,
|
|
8251
8382
|
allowlist: opts.allowlist ?? null,
|
|
8252
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
8253
8383
|
ctx
|
|
8254
8384
|
});
|
|
8255
8385
|
}
|
|
@@ -8272,7 +8402,6 @@ ${scopeAnswer || "(none)"}
|
|
|
8272
8402
|
}, {
|
|
8273
8403
|
providers: opts.providers,
|
|
8274
8404
|
allowlist: opts.allowlist ?? null,
|
|
8275
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
8276
8405
|
ctx
|
|
8277
8406
|
});
|
|
8278
8407
|
let overallF = toNumberOrNull(auditEnvelope["overall_score"]);
|
|
@@ -8297,7 +8426,6 @@ ${documentsPayload}`
|
|
|
8297
8426
|
providers: opts.providers,
|
|
8298
8427
|
allowlist: opts.allowlist ?? null,
|
|
8299
8428
|
moderator,
|
|
8300
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
8301
8429
|
ctx
|
|
8302
8430
|
}
|
|
8303
8431
|
);
|
|
@@ -8317,7 +8445,6 @@ ${documentsPayload}`
|
|
|
8317
8445
|
}, {
|
|
8318
8446
|
providers: opts.providers,
|
|
8319
8447
|
allowlist: opts.allowlist ?? null,
|
|
8320
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
8321
8448
|
ctx
|
|
8322
8449
|
});
|
|
8323
8450
|
overallF = toNumberOrNull(auditEnvelope["overall_score"]);
|
|
@@ -8454,7 +8581,7 @@ async function ingestDocuments(documents, sessionId, opts) {
|
|
|
8454
8581
|
source: ref,
|
|
8455
8582
|
type: "file",
|
|
8456
8583
|
status: "ok",
|
|
8457
|
-
hash: (0,
|
|
8584
|
+
hash: (0, import_node_crypto7.createHash)("sha256").update(text, "utf8").digest("hex"),
|
|
8458
8585
|
content: ""
|
|
8459
8586
|
}, text));
|
|
8460
8587
|
}
|
|
@@ -8491,7 +8618,7 @@ ${d.content}
|
|
|
8491
8618
|
function makeSessionId(opts, supplied) {
|
|
8492
8619
|
if (typeof supplied === "string" && supplied) return supplied;
|
|
8493
8620
|
const stamp = opts.nowEpochSeconds ? opts.nowEpochSeconds() : Math.floor(Date.now() / 1e3);
|
|
8494
|
-
const rnd = opts.randomBytes ? opts.randomBytes() : (0,
|
|
8621
|
+
const rnd = opts.randomBytes ? opts.randomBytes() : (0, import_node_crypto7.createHash)("sha256").update(`${stamp}-${process.pid}-${Math.random()}`).digest("hex");
|
|
8495
8622
|
const suffix = rnd.slice(0, 8);
|
|
8496
8623
|
return `${opts.toolName}-${stamp}-${suffix}`;
|
|
8497
8624
|
}
|
|
@@ -8555,11 +8682,6 @@ function errorEnvelope6(toolName, code, message, hint) {
|
|
|
8555
8682
|
|
|
8556
8683
|
// src/tools/coordinate.ts
|
|
8557
8684
|
var import_node_perf_hooks7 = require("perf_hooks");
|
|
8558
|
-
var DEFERRED_OPTS3 = [
|
|
8559
|
-
// empty — every coordinate opt runs natively when its deps
|
|
8560
|
-
// (storage / innerCallers) are wired. Without them the
|
|
8561
|
-
// worker_tools gate still triggers a bridge defer.
|
|
8562
|
-
];
|
|
8563
8685
|
var COORDINATE_DEFAULT_TEMP = 0.4;
|
|
8564
8686
|
var ROLE_TURN_SCHEMA = {
|
|
8565
8687
|
type: "object",
|
|
@@ -8614,23 +8736,18 @@ async function runCoordinate(args, opts) {
|
|
|
8614
8736
|
rejectedWorkerTools.push(t);
|
|
8615
8737
|
}
|
|
8616
8738
|
}
|
|
8617
|
-
|
|
8618
|
-
const needsBridge = DEFERRED_OPTS3.some((k) => Boolean(args[k])) || workerToolsNeedsBridge;
|
|
8619
|
-
if (needsBridge) {
|
|
8739
|
+
if (acceptedWorkerTools.length > 0 && !opts.innerCallers) {
|
|
8620
8740
|
if (superRequested) {
|
|
8621
8741
|
return errorEnvelope7(
|
|
8622
8742
|
"COORDINATE_SUPER_NOT_NATIVE",
|
|
8623
|
-
"super mode requested
|
|
8624
|
-
"worker_tools
|
|
8743
|
+
"super mode requested with worker_tools, but innerCallers are not wired",
|
|
8744
|
+
"worker_tools needs innerCallers wired by the host. Drop worker_tools, or wire innerCallers, to use super."
|
|
8625
8745
|
);
|
|
8626
8746
|
}
|
|
8627
|
-
if (opts.bridge && opts.bridge.toolNames.has("coordinate")) {
|
|
8628
|
-
return await deferCoordinate(args, opts.bridge);
|
|
8629
|
-
}
|
|
8630
8747
|
return errorEnvelope7(
|
|
8631
8748
|
"COORDINATE_OPT_NOT_NATIVE",
|
|
8632
8749
|
"worker_tools requested but innerCallers are not wired",
|
|
8633
|
-
"Native coordinate covers the three-role flow + untrusted_input + inject_session_memory. worker_tools needs innerCallers wired by the host
|
|
8750
|
+
"Native coordinate covers the three-role flow + untrusted_input + inject_session_memory. worker_tools needs innerCallers wired by the host."
|
|
8634
8751
|
);
|
|
8635
8752
|
}
|
|
8636
8753
|
const untrusted = Boolean(args["untrusted_input"]);
|
|
@@ -9030,21 +9147,6 @@ function unknownProviderError3(unknownNames, available) {
|
|
|
9030
9147
|
available_now: Object.keys(available).sort()
|
|
9031
9148
|
};
|
|
9032
9149
|
}
|
|
9033
|
-
async function deferCoordinate(args, bridge) {
|
|
9034
|
-
const r = await bridge.callTool("coordinate", args);
|
|
9035
|
-
const text = r.content[0]?.text;
|
|
9036
|
-
if (typeof text === "string") {
|
|
9037
|
-
try {
|
|
9038
|
-
return JSON.parse(text);
|
|
9039
|
-
} catch {
|
|
9040
|
-
}
|
|
9041
|
-
}
|
|
9042
|
-
return errorEnvelope7(
|
|
9043
|
-
"COORDINATE_BRIDGE_BAD_ENVELOPE",
|
|
9044
|
-
"bridge returned an unparseable envelope for coordinate",
|
|
9045
|
-
"Check that the Python child is healthy."
|
|
9046
|
-
);
|
|
9047
|
-
}
|
|
9048
9150
|
function errorEnvelope7(code, message, hint) {
|
|
9049
9151
|
return {
|
|
9050
9152
|
tool: "coordinate",
|
|
@@ -9372,10 +9474,6 @@ function buildModeratorTranscript(transcript) {
|
|
|
9372
9474
|
|
|
9373
9475
|
// src/tools/debate.ts
|
|
9374
9476
|
var import_node_perf_hooks9 = require("perf_hooks");
|
|
9375
|
-
var DEFERRED_OPTS4 = [
|
|
9376
|
-
// empty — every debate opt runs natively when its deps
|
|
9377
|
-
// (storage / innerCallers) are wired.
|
|
9378
|
-
];
|
|
9379
9477
|
async function runDebate(args, opts) {
|
|
9380
9478
|
const callStartedWall = import_node_perf_hooks9.performance.now();
|
|
9381
9479
|
const callStartedCpu = process.cpuUsage();
|
|
@@ -9393,23 +9491,18 @@ async function runDebate(args, opts) {
|
|
|
9393
9491
|
rejectedWorkerTools.push(t);
|
|
9394
9492
|
}
|
|
9395
9493
|
}
|
|
9396
|
-
|
|
9397
|
-
const needsBridge = DEFERRED_OPTS4.some((k) => Boolean(args[k])) || workerToolsNeedsBridge;
|
|
9398
|
-
if (needsBridge) {
|
|
9494
|
+
if (acceptedWorkerTools.length > 0 && !opts.innerCallers) {
|
|
9399
9495
|
if (superRequested) {
|
|
9400
9496
|
return errorEnvelope9(
|
|
9401
9497
|
"DEBATE_SUPER_NOT_NATIVE",
|
|
9402
|
-
"super mode requested
|
|
9403
|
-
"worker_tools
|
|
9498
|
+
"super mode requested with worker_tools, but innerCallers are not wired",
|
|
9499
|
+
"worker_tools needs innerCallers wired by the host. Drop worker_tools, or wire innerCallers, to use super."
|
|
9404
9500
|
);
|
|
9405
9501
|
}
|
|
9406
|
-
if (opts.bridge && opts.bridge.toolNames.has("debate")) {
|
|
9407
|
-
return await deferDebate(args, opts.bridge);
|
|
9408
|
-
}
|
|
9409
9502
|
return errorEnvelope9(
|
|
9410
9503
|
"DEBATE_OPT_NOT_NATIVE",
|
|
9411
9504
|
"worker_tools requested but innerCallers are not wired",
|
|
9412
|
-
"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
|
|
9505
|
+
"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."
|
|
9413
9506
|
);
|
|
9414
9507
|
}
|
|
9415
9508
|
const topic = typeof args["topic"] === "string" ? args["topic"] : String(args["topic"] ?? "");
|
|
@@ -9846,21 +9939,6 @@ function unknownProviderError5(unknownNames, available) {
|
|
|
9846
9939
|
available_now: Object.keys(available).sort()
|
|
9847
9940
|
};
|
|
9848
9941
|
}
|
|
9849
|
-
async function deferDebate(args, bridge) {
|
|
9850
|
-
const r = await bridge.callTool("debate", args);
|
|
9851
|
-
const text = r.content[0]?.text;
|
|
9852
|
-
if (typeof text === "string") {
|
|
9853
|
-
try {
|
|
9854
|
-
return JSON.parse(text);
|
|
9855
|
-
} catch {
|
|
9856
|
-
}
|
|
9857
|
-
}
|
|
9858
|
-
return errorEnvelope9(
|
|
9859
|
-
"DEBATE_BRIDGE_BAD_ENVELOPE",
|
|
9860
|
-
"bridge returned an unparseable envelope for debate",
|
|
9861
|
-
"Check that the Python child is healthy."
|
|
9862
|
-
);
|
|
9863
|
-
}
|
|
9864
9942
|
function errorEnvelope9(code, message, hint) {
|
|
9865
9943
|
return {
|
|
9866
9944
|
tool: "debate",
|
|
@@ -9880,9 +9958,6 @@ var DEFAULT_DELEGATION_LIMITS = {
|
|
|
9880
9958
|
};
|
|
9881
9959
|
async function runDelegate(args, opts) {
|
|
9882
9960
|
if (!opts.storage) {
|
|
9883
|
-
if (opts.bridge && opts.bridge.toolNames.has("delegate")) {
|
|
9884
|
-
return await deferDelegate(args, opts.bridge);
|
|
9885
|
-
}
|
|
9886
9961
|
return errorEnvelope10(
|
|
9887
9962
|
"DELEGATE_STORAGE_UNAVAILABLE",
|
|
9888
9963
|
"delegate needs the local database (for quota tracking), which isn't available",
|
|
@@ -9954,7 +10029,6 @@ async function runDelegate(args, opts) {
|
|
|
9954
10029
|
const innerOpts = {
|
|
9955
10030
|
providers: opts.providers,
|
|
9956
10031
|
allowlist: opts.allowlist ?? null,
|
|
9957
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
9958
10032
|
...opts.moderator ? { moderator: opts.moderator } : {}
|
|
9959
10033
|
};
|
|
9960
10034
|
let result;
|
|
@@ -9993,21 +10067,6 @@ async function record(storage, sessionId, requester, toolCall, via, accepted, no
|
|
|
9993
10067
|
created_at: nowEpochSeconds
|
|
9994
10068
|
});
|
|
9995
10069
|
}
|
|
9996
|
-
async function deferDelegate(args, bridge) {
|
|
9997
|
-
const r = await bridge.callTool("delegate", args);
|
|
9998
|
-
const text = r.content[0]?.text;
|
|
9999
|
-
if (typeof text === "string") {
|
|
10000
|
-
try {
|
|
10001
|
-
return JSON.parse(text);
|
|
10002
|
-
} catch {
|
|
10003
|
-
}
|
|
10004
|
-
}
|
|
10005
|
-
return errorEnvelope10(
|
|
10006
|
-
"DELEGATE_BRIDGE_BAD_ENVELOPE",
|
|
10007
|
-
"bridge returned an unparseable envelope for delegate",
|
|
10008
|
-
"Check that the Python child is healthy."
|
|
10009
|
-
);
|
|
10010
|
-
}
|
|
10011
10070
|
function errorEnvelope10(code, message, hint) {
|
|
10012
10071
|
return {
|
|
10013
10072
|
tool: "delegate",
|
|
@@ -10050,9 +10109,6 @@ async function runExplain(args, opts) {
|
|
|
10050
10109
|
);
|
|
10051
10110
|
}
|
|
10052
10111
|
if (!opts.storage) {
|
|
10053
|
-
if (opts.bridge && opts.bridge.toolNames.has("explain")) {
|
|
10054
|
-
return await deferExplain(args, opts.bridge);
|
|
10055
|
-
}
|
|
10056
10112
|
return errorEnvelope11(
|
|
10057
10113
|
"EXPLAIN_STORAGE_UNAVAILABLE",
|
|
10058
10114
|
"explain needs the local transcript/stats database, which isn't available",
|
|
@@ -10334,21 +10390,6 @@ function pyRepr5(v) {
|
|
|
10334
10390
|
}
|
|
10335
10391
|
return String(v);
|
|
10336
10392
|
}
|
|
10337
|
-
async function deferExplain(args, bridge) {
|
|
10338
|
-
const r = await bridge.callTool("explain", args);
|
|
10339
|
-
const text = r.content[0]?.text;
|
|
10340
|
-
if (typeof text === "string") {
|
|
10341
|
-
try {
|
|
10342
|
-
return JSON.parse(text);
|
|
10343
|
-
} catch {
|
|
10344
|
-
}
|
|
10345
|
-
}
|
|
10346
|
-
return errorEnvelope11(
|
|
10347
|
-
"EXPLAIN_BRIDGE_BAD_ENVELOPE",
|
|
10348
|
-
"bridge returned an unparseable envelope for explain",
|
|
10349
|
-
"Check that the Python child is healthy."
|
|
10350
|
-
);
|
|
10351
|
-
}
|
|
10352
10393
|
function errorEnvelope11(code, message, hint, kind = "client", extra = {}) {
|
|
10353
10394
|
return {
|
|
10354
10395
|
tool: "explain",
|
|
@@ -10901,9 +10942,6 @@ async function runRecall(args, opts) {
|
|
|
10901
10942
|
if (k < 1) k = 1;
|
|
10902
10943
|
if (k > 50) k = 50;
|
|
10903
10944
|
if (!opts.storage) {
|
|
10904
|
-
if (opts.bridge && opts.bridge.toolNames.has("recall")) {
|
|
10905
|
-
return await deferRecall(args, opts.bridge);
|
|
10906
|
-
}
|
|
10907
10945
|
return errorEnvelope12(
|
|
10908
10946
|
"RECALL_STORAGE_UNAVAILABLE",
|
|
10909
10947
|
"recall needs the local database, which isn't available",
|
|
@@ -10956,21 +10994,6 @@ async function runRecall(args, opts) {
|
|
|
10956
10994
|
applied_filters: applied
|
|
10957
10995
|
};
|
|
10958
10996
|
}
|
|
10959
|
-
async function deferRecall(args, bridge) {
|
|
10960
|
-
const r = await bridge.callTool("recall", args);
|
|
10961
|
-
const text = r.content[0]?.text;
|
|
10962
|
-
if (typeof text === "string") {
|
|
10963
|
-
try {
|
|
10964
|
-
return JSON.parse(text);
|
|
10965
|
-
} catch {
|
|
10966
|
-
}
|
|
10967
|
-
}
|
|
10968
|
-
return errorEnvelope12(
|
|
10969
|
-
"RECALL_BRIDGE_BAD_ENVELOPE",
|
|
10970
|
-
"bridge returned an unparseable envelope for recall",
|
|
10971
|
-
"Check that the Python child is healthy."
|
|
10972
|
-
);
|
|
10973
|
-
}
|
|
10974
10997
|
function errorEnvelope12(code, message, hint) {
|
|
10975
10998
|
return {
|
|
10976
10999
|
tool: "recall",
|
|
@@ -10993,9 +11016,6 @@ async function runRecommendPanel(args, opts) {
|
|
|
10993
11016
|
);
|
|
10994
11017
|
}
|
|
10995
11018
|
if (!opts.storage) {
|
|
10996
|
-
if (opts.bridge && opts.bridge.toolNames.has("recommend_panel")) {
|
|
10997
|
-
return await deferRecommendPanel(args, opts.bridge);
|
|
10998
|
-
}
|
|
10999
11019
|
return errorEnvelope13(
|
|
11000
11020
|
"RECOMMEND_PANEL_STORAGE_UNAVAILABLE",
|
|
11001
11021
|
"recommend_panel needs the local stats database, which isn't available",
|
|
@@ -11058,21 +11078,6 @@ async function runRecommendPanel(args, opts) {
|
|
|
11058
11078
|
meta: result.meta
|
|
11059
11079
|
};
|
|
11060
11080
|
}
|
|
11061
|
-
async function deferRecommendPanel(args, bridge) {
|
|
11062
|
-
const r = await bridge.callTool("recommend_panel", args);
|
|
11063
|
-
const text = r.content[0]?.text;
|
|
11064
|
-
if (typeof text === "string") {
|
|
11065
|
-
try {
|
|
11066
|
-
return JSON.parse(text);
|
|
11067
|
-
} catch {
|
|
11068
|
-
}
|
|
11069
|
-
}
|
|
11070
|
-
return errorEnvelope13(
|
|
11071
|
-
"RECOMMEND_PANEL_BRIDGE_BAD_ENVELOPE",
|
|
11072
|
-
"bridge returned an unparseable envelope for recommend_panel",
|
|
11073
|
-
"Check that the Python child is healthy."
|
|
11074
|
-
);
|
|
11075
|
-
}
|
|
11076
11081
|
function errorEnvelope13(code, message, hint) {
|
|
11077
11082
|
return {
|
|
11078
11083
|
tool: "recommend_panel",
|
|
@@ -11102,9 +11107,6 @@ function toStringArray3(v) {
|
|
|
11102
11107
|
var import_node_fs11 = require("fs");
|
|
11103
11108
|
async function runScoreboard(args, opts) {
|
|
11104
11109
|
if (!opts.storage) {
|
|
11105
|
-
if (opts.bridge && opts.bridge.toolNames.has("scoreboard")) {
|
|
11106
|
-
return await deferScoreboard(args, opts.bridge);
|
|
11107
|
-
}
|
|
11108
11110
|
return errorEnvelope14(
|
|
11109
11111
|
"SCOREBOARD_STORAGE_UNAVAILABLE",
|
|
11110
11112
|
"scoreboard needs the local stats database, which isn't available",
|
|
@@ -11227,21 +11229,6 @@ function clampInt3(raw, min, max, fallback) {
|
|
|
11227
11229
|
if (!Number.isFinite(n)) return fallback;
|
|
11228
11230
|
return Math.min(max, Math.max(min, Math.trunc(n)));
|
|
11229
11231
|
}
|
|
11230
|
-
async function deferScoreboard(args, bridge) {
|
|
11231
|
-
const r = await bridge.callTool("scoreboard", args);
|
|
11232
|
-
const text = r.content[0]?.text;
|
|
11233
|
-
if (typeof text === "string") {
|
|
11234
|
-
try {
|
|
11235
|
-
return JSON.parse(text);
|
|
11236
|
-
} catch {
|
|
11237
|
-
}
|
|
11238
|
-
}
|
|
11239
|
-
return errorEnvelope14(
|
|
11240
|
-
"SCOREBOARD_BRIDGE_BAD_ENVELOPE",
|
|
11241
|
-
"bridge returned an unparseable envelope for scoreboard",
|
|
11242
|
-
"Check that the Python child is healthy."
|
|
11243
|
-
);
|
|
11244
|
-
}
|
|
11245
11232
|
function errorEnvelope14(code, message, hint) {
|
|
11246
11233
|
return {
|
|
11247
11234
|
tool: "scoreboard",
|
|
@@ -11278,9 +11265,6 @@ async function runSessionMemory(args, opts) {
|
|
|
11278
11265
|
);
|
|
11279
11266
|
}
|
|
11280
11267
|
if (!opts.storage) {
|
|
11281
|
-
if (opts.bridge && opts.bridge.toolNames.has("session_memory")) {
|
|
11282
|
-
return await deferSessionMemory(args, opts.bridge);
|
|
11283
|
-
}
|
|
11284
11268
|
return errorEnvelope15(
|
|
11285
11269
|
"SESSION_MEMORY_STORAGE_UNAVAILABLE",
|
|
11286
11270
|
"session_memory needs the local database, which isn't available",
|
|
@@ -11385,21 +11369,6 @@ function clampInt4(raw, min, max, fallback) {
|
|
|
11385
11369
|
if (!Number.isFinite(n)) return fallback;
|
|
11386
11370
|
return Math.min(max, Math.max(min, Math.trunc(n)));
|
|
11387
11371
|
}
|
|
11388
|
-
async function deferSessionMemory(args, bridge) {
|
|
11389
|
-
const r = await bridge.callTool("session_memory", args);
|
|
11390
|
-
const text = r.content[0]?.text;
|
|
11391
|
-
if (typeof text === "string") {
|
|
11392
|
-
try {
|
|
11393
|
-
return JSON.parse(text);
|
|
11394
|
-
} catch {
|
|
11395
|
-
}
|
|
11396
|
-
}
|
|
11397
|
-
return errorEnvelope15(
|
|
11398
|
-
"SESSION_MEMORY_BRIDGE_BAD_ENVELOPE",
|
|
11399
|
-
"bridge returned an unparseable envelope for session_memory",
|
|
11400
|
-
"Check that the Python child is healthy."
|
|
11401
|
-
);
|
|
11402
|
-
}
|
|
11403
11372
|
function errorEnvelope15(code, message, hint) {
|
|
11404
11373
|
return {
|
|
11405
11374
|
tool: "session_memory",
|
|
@@ -12019,7 +11988,7 @@ var CHECK_INTERVAL_SECONDS = 3 * 24 * 60 * 60;
|
|
|
12019
11988
|
var DEFAULT_PACKAGE = "crosscheck-cli";
|
|
12020
11989
|
var FETCH_TIMEOUT_MS = 3e3;
|
|
12021
11990
|
function engineVersion() {
|
|
12022
|
-
return true ? "0.2.
|
|
11991
|
+
return true ? "0.2.28" : "0.0.0-dev";
|
|
12023
11992
|
}
|
|
12024
11993
|
function defaultUpdateCachePath() {
|
|
12025
11994
|
const base = process.env["CROSSCHECK_DATA_DIR"] || import_node_path12.default.join(import_node_os2.default.homedir() || import_node_os2.default.tmpdir(), ".crosscheck");
|
|
@@ -12791,12 +12760,11 @@ function helpTool() {
|
|
|
12791
12760
|
}
|
|
12792
12761
|
});
|
|
12793
12762
|
}
|
|
12794
|
-
function registerCoreTools(
|
|
12795
|
-
const o = opts && typeof opts === "object" && "toolNames" in opts ? { bridge: opts } : opts;
|
|
12763
|
+
function registerCoreTools(o = {}) {
|
|
12796
12764
|
const tools = /* @__PURE__ */ new Map();
|
|
12797
12765
|
const list = [
|
|
12798
12766
|
pingTool(),
|
|
12799
|
-
verifyTool(o.
|
|
12767
|
+
verifyTool(o.fetchConfig),
|
|
12800
12768
|
pickTool(
|
|
12801
12769
|
o.providers ?? {},
|
|
12802
12770
|
o.providerAllowlist ?? null,
|
|
@@ -12808,7 +12776,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12808
12776
|
auditTool(
|
|
12809
12777
|
o.providers ?? {},
|
|
12810
12778
|
o.providerAllowlist ?? null,
|
|
12811
|
-
o.bridge,
|
|
12812
12779
|
o.transcriptsDir,
|
|
12813
12780
|
o.pricing,
|
|
12814
12781
|
o.storage,
|
|
@@ -12818,7 +12785,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12818
12785
|
conferTool(
|
|
12819
12786
|
o.providers ?? {},
|
|
12820
12787
|
o.providerAllowlist ?? null,
|
|
12821
|
-
o.bridge,
|
|
12822
12788
|
o.moderatorDefault ?? "anthropic",
|
|
12823
12789
|
o.pricing,
|
|
12824
12790
|
o.storage,
|
|
@@ -12831,7 +12797,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12831
12797
|
debateTool(
|
|
12832
12798
|
o.providers ?? {},
|
|
12833
12799
|
o.providerAllowlist ?? null,
|
|
12834
|
-
o.bridge,
|
|
12835
12800
|
buildInnerCallers(o),
|
|
12836
12801
|
o.storage,
|
|
12837
12802
|
o.pricing,
|
|
@@ -12843,7 +12808,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12843
12808
|
coordinateTool(
|
|
12844
12809
|
o.providers ?? {},
|
|
12845
12810
|
o.providerAllowlist ?? null,
|
|
12846
|
-
o.bridge,
|
|
12847
12811
|
buildInnerCallers(o),
|
|
12848
12812
|
o.storage,
|
|
12849
12813
|
o.circuitBreakers,
|
|
@@ -12854,7 +12818,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12854
12818
|
triangulateTool(
|
|
12855
12819
|
o.providers ?? {},
|
|
12856
12820
|
o.providerAllowlist ?? null,
|
|
12857
|
-
o.bridge,
|
|
12858
12821
|
o.storage,
|
|
12859
12822
|
o.circuitBreakers,
|
|
12860
12823
|
o.transcriptsDir,
|
|
@@ -12863,7 +12826,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12863
12826
|
planTool(
|
|
12864
12827
|
o.providers ?? {},
|
|
12865
12828
|
o.providerAllowlist ?? null,
|
|
12866
|
-
o.bridge,
|
|
12867
12829
|
o.storage,
|
|
12868
12830
|
o.circuitBreakers,
|
|
12869
12831
|
o.transcriptsDir,
|
|
@@ -12872,7 +12834,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12872
12834
|
critiqueTool(
|
|
12873
12835
|
o.providers ?? {},
|
|
12874
12836
|
o.providerAllowlist ?? null,
|
|
12875
|
-
o.bridge,
|
|
12876
12837
|
o.storage,
|
|
12877
12838
|
o.circuitBreakers,
|
|
12878
12839
|
o.transcriptsDir,
|
|
@@ -12881,7 +12842,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12881
12842
|
reviewTool(
|
|
12882
12843
|
o.providers ?? {},
|
|
12883
12844
|
o.providerAllowlist ?? null,
|
|
12884
|
-
o.bridge,
|
|
12885
12845
|
o.storage,
|
|
12886
12846
|
o.circuitBreakers,
|
|
12887
12847
|
o.transcriptsDir,
|
|
@@ -12889,25 +12849,23 @@ function registerCoreTools(opts = {}) {
|
|
|
12889
12849
|
),
|
|
12890
12850
|
listProvidersTool(o.providers ?? {}, o.activeProviders ?? null, o.moderatorDefault ?? "anthropic"),
|
|
12891
12851
|
modelsTool(o.providers ?? {}, o.activeProviders ?? null),
|
|
12892
|
-
recallTool(o.storage
|
|
12893
|
-
sessionMemoryTool(o.storage
|
|
12894
|
-
scoreboardTool(o.storage, o.
|
|
12895
|
-
explainTool(o.storage, o.
|
|
12852
|
+
recallTool(o.storage),
|
|
12853
|
+
sessionMemoryTool(o.storage),
|
|
12854
|
+
scoreboardTool(o.storage, o.eventsPath),
|
|
12855
|
+
explainTool(o.storage, o.transcriptsDir),
|
|
12896
12856
|
delegateTool(
|
|
12897
12857
|
o.providers ?? {},
|
|
12898
12858
|
o.providerAllowlist ?? null,
|
|
12899
12859
|
o.storage,
|
|
12900
|
-
o.bridge,
|
|
12901
12860
|
o.moderatorDefault ?? "anthropic"
|
|
12902
12861
|
),
|
|
12903
12862
|
fetchTool(o.storage, o.fetchConfig, o.repoRoot),
|
|
12904
|
-
recommendPanelTool(o.providers ?? {}, o.storage
|
|
12863
|
+
recommendPanelTool(o.providers ?? {}, o.storage),
|
|
12905
12864
|
updateCrosscheckTool(o.repoRoot ?? null),
|
|
12906
12865
|
benchTool(
|
|
12907
12866
|
o.providers ?? {},
|
|
12908
12867
|
o.providerAllowlist ?? null,
|
|
12909
12868
|
o.storage,
|
|
12910
|
-
o.bridge,
|
|
12911
12869
|
o.moderatorDefault ?? "anthropic",
|
|
12912
12870
|
o.benchGoldensDir,
|
|
12913
12871
|
o.circuitBreakers,
|
|
@@ -12918,7 +12876,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12918
12876
|
solveTool(
|
|
12919
12877
|
o.providers ?? {},
|
|
12920
12878
|
o.providerAllowlist ?? null,
|
|
12921
|
-
o.bridge,
|
|
12922
12879
|
o.storage,
|
|
12923
12880
|
o.circuitBreakers,
|
|
12924
12881
|
o.transcriptsDir,
|
|
@@ -12927,7 +12884,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12927
12884
|
orchestrateTool(
|
|
12928
12885
|
o.providers ?? {},
|
|
12929
12886
|
o.providerAllowlist ?? null,
|
|
12930
|
-
o.bridge,
|
|
12931
12887
|
o.moderatorDefault ?? "anthropic",
|
|
12932
12888
|
o.storage,
|
|
12933
12889
|
o.pricing,
|
|
@@ -12974,7 +12930,6 @@ function createTool(o, toolName, cheapDefault) {
|
|
|
12974
12930
|
providers: o.providers ?? {},
|
|
12975
12931
|
allowlist: o.providerAllowlist ?? null,
|
|
12976
12932
|
...o.storage ? { storage: o.storage } : {},
|
|
12977
|
-
...o.bridge ? { bridge: o.bridge } : {},
|
|
12978
12933
|
...o.moderatorDefault ? { moderator: o.moderatorDefault } : {},
|
|
12979
12934
|
...o.fetchConfig ? { fetchConfig: o.fetchConfig } : {},
|
|
12980
12935
|
...o.repoRoot ? { repoRoot: o.repoRoot } : {},
|
|
@@ -12983,7 +12938,7 @@ function createTool(o, toolName, cheapDefault) {
|
|
|
12983
12938
|
})
|
|
12984
12939
|
};
|
|
12985
12940
|
}
|
|
12986
|
-
function orchestrateTool(providers, allowlist,
|
|
12941
|
+
function orchestrateTool(providers, allowlist, moderator, storage, pricing, breakers, transcriptsDir, repoRoot, nodeCache) {
|
|
12987
12942
|
return {
|
|
12988
12943
|
name: "orchestrate",
|
|
12989
12944
|
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.",
|
|
@@ -13008,7 +12963,6 @@ function orchestrateTool(providers, allowlist, bridge, moderator, storage, prici
|
|
|
13008
12963
|
providers,
|
|
13009
12964
|
allowlist,
|
|
13010
12965
|
moderator,
|
|
13011
|
-
...bridge ? { bridge } : {},
|
|
13012
12966
|
...storage ? { storage } : {},
|
|
13013
12967
|
...pricing ? { pricing } : {},
|
|
13014
12968
|
...breakers ? { breakers } : {},
|
|
@@ -13018,7 +12972,7 @@ function orchestrateTool(providers, allowlist, bridge, moderator, storage, prici
|
|
|
13018
12972
|
})
|
|
13019
12973
|
};
|
|
13020
12974
|
}
|
|
13021
|
-
function solveTool(providers, allowlist,
|
|
12975
|
+
function solveTool(providers, allowlist, storage, breakers, transcriptsDir, repoRoot) {
|
|
13022
12976
|
return {
|
|
13023
12977
|
name: "solve",
|
|
13024
12978
|
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.",
|
|
@@ -13040,7 +12994,6 @@ function solveTool(providers, allowlist, bridge, storage, breakers, transcriptsD
|
|
|
13040
12994
|
handler: (args) => runSolve(args, {
|
|
13041
12995
|
providers,
|
|
13042
12996
|
allowlist,
|
|
13043
|
-
...bridge ? { bridge } : {},
|
|
13044
12997
|
...storage ? { storage } : {},
|
|
13045
12998
|
...breakers ? { breakers } : {},
|
|
13046
12999
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -13079,7 +13032,7 @@ function configPinTool(repoRoot, config, rejectDriftEnv) {
|
|
|
13079
13032
|
}
|
|
13080
13033
|
};
|
|
13081
13034
|
}
|
|
13082
|
-
function benchTool(providers, allowlist, storage,
|
|
13035
|
+
function benchTool(providers, allowlist, storage, moderator, defaultGoldensDir, breakers, transcriptsDir, repoRoot) {
|
|
13083
13036
|
return {
|
|
13084
13037
|
name: "bench",
|
|
13085
13038
|
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).",
|
|
@@ -13098,7 +13051,6 @@ function benchTool(providers, allowlist, storage, bridge, moderator, defaultGold
|
|
|
13098
13051
|
allowlist,
|
|
13099
13052
|
moderator,
|
|
13100
13053
|
...storage ? { storage } : {},
|
|
13101
|
-
...bridge ? { bridge } : {},
|
|
13102
13054
|
...defaultGoldensDir ? { defaultGoldensDir } : {},
|
|
13103
13055
|
...breakers ? { breakers } : {},
|
|
13104
13056
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -13125,7 +13077,7 @@ function updateCrosscheckTool(repoRoot) {
|
|
|
13125
13077
|
}
|
|
13126
13078
|
};
|
|
13127
13079
|
}
|
|
13128
|
-
function recommendPanelTool(providers, storage
|
|
13080
|
+
function recommendPanelTool(providers, storage) {
|
|
13129
13081
|
return {
|
|
13130
13082
|
name: "recommend_panel",
|
|
13131
13083
|
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.",
|
|
@@ -13143,8 +13095,7 @@ function recommendPanelTool(providers, storage, bridge) {
|
|
|
13143
13095
|
},
|
|
13144
13096
|
handler: (args) => runRecommendPanel(args, {
|
|
13145
13097
|
providers,
|
|
13146
|
-
...storage ? { storage } : {}
|
|
13147
|
-
...bridge ? { bridge } : {}
|
|
13098
|
+
...storage ? { storage } : {}
|
|
13148
13099
|
})
|
|
13149
13100
|
};
|
|
13150
13101
|
}
|
|
@@ -13169,7 +13120,7 @@ function fetchTool(storage, fetchConfig, repoRoot) {
|
|
|
13169
13120
|
})
|
|
13170
13121
|
};
|
|
13171
13122
|
}
|
|
13172
|
-
function delegateTool(providers, allowlist, storage,
|
|
13123
|
+
function delegateTool(providers, allowlist, storage, moderator) {
|
|
13173
13124
|
return {
|
|
13174
13125
|
name: "delegate",
|
|
13175
13126
|
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.",
|
|
@@ -13189,12 +13140,11 @@ function delegateTool(providers, allowlist, storage, bridge, moderator) {
|
|
|
13189
13140
|
providers,
|
|
13190
13141
|
allowlist,
|
|
13191
13142
|
moderator,
|
|
13192
|
-
...storage ? { storage } : {}
|
|
13193
|
-
...bridge ? { bridge } : {}
|
|
13143
|
+
...storage ? { storage } : {}
|
|
13194
13144
|
})
|
|
13195
13145
|
};
|
|
13196
13146
|
}
|
|
13197
|
-
function explainTool(storage,
|
|
13147
|
+
function explainTool(storage, transcriptsDir) {
|
|
13198
13148
|
return {
|
|
13199
13149
|
name: "explain",
|
|
13200
13150
|
description: "Replay a session as a navigable tree with cost/latency annotations. Reads usage_log + optionally walks the transcripts directory for per-tool summaries.",
|
|
@@ -13212,12 +13162,11 @@ function explainTool(storage, bridge, transcriptsDir) {
|
|
|
13212
13162
|
},
|
|
13213
13163
|
handler: (args) => runExplain(args, {
|
|
13214
13164
|
...storage ? { storage } : {},
|
|
13215
|
-
...bridge ? { bridge } : {},
|
|
13216
13165
|
...transcriptsDir ? { transcriptsDir } : {}
|
|
13217
13166
|
})
|
|
13218
13167
|
};
|
|
13219
13168
|
}
|
|
13220
|
-
function scoreboardTool(storage,
|
|
13169
|
+
function scoreboardTool(storage, eventsPath) {
|
|
13221
13170
|
return {
|
|
13222
13171
|
name: "scoreboard",
|
|
13223
13172
|
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).",
|
|
@@ -13231,12 +13180,11 @@ function scoreboardTool(storage, bridge, eventsPath) {
|
|
|
13231
13180
|
},
|
|
13232
13181
|
handler: (args) => runScoreboard(args, {
|
|
13233
13182
|
...storage ? { storage } : {},
|
|
13234
|
-
...bridge ? { bridge } : {},
|
|
13235
13183
|
...eventsPath ? { eventsPath } : {}
|
|
13236
13184
|
})
|
|
13237
13185
|
};
|
|
13238
13186
|
}
|
|
13239
|
-
function sessionMemoryTool(storage
|
|
13187
|
+
function sessionMemoryTool(storage) {
|
|
13240
13188
|
return {
|
|
13241
13189
|
name: "session_memory",
|
|
13242
13190
|
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).",
|
|
@@ -13259,15 +13207,14 @@ function sessionMemoryTool(storage, bridge) {
|
|
|
13259
13207
|
required: ["action", "session_id"]
|
|
13260
13208
|
},
|
|
13261
13209
|
handler: (args) => runSessionMemory(args, {
|
|
13262
|
-
...storage ? { storage } : {}
|
|
13263
|
-
...bridge ? { bridge } : {}
|
|
13210
|
+
...storage ? { storage } : {}
|
|
13264
13211
|
})
|
|
13265
13212
|
};
|
|
13266
13213
|
}
|
|
13267
|
-
function recallTool(storage
|
|
13214
|
+
function recallTool(storage) {
|
|
13268
13215
|
return {
|
|
13269
13216
|
name: "recall",
|
|
13270
|
-
description: "Full-text search across persisted transcripts via SQLite FTS5. Returns rows ordered by relevance with a windowed snippet. Requires a wired Storage adapter
|
|
13217
|
+
description: "Full-text search across persisted transcripts via SQLite FTS5. Returns rows ordered by relevance with a windowed snippet. Requires a wired Storage adapter.",
|
|
13271
13218
|
inputSchema: {
|
|
13272
13219
|
type: "object",
|
|
13273
13220
|
additionalProperties: true,
|
|
@@ -13281,8 +13228,7 @@ function recallTool(storage, bridge) {
|
|
|
13281
13228
|
required: ["query"]
|
|
13282
13229
|
},
|
|
13283
13230
|
handler: (args) => runRecall(args, {
|
|
13284
|
-
...storage ? { storage } : {}
|
|
13285
|
-
...bridge ? { bridge } : {}
|
|
13231
|
+
...storage ? { storage } : {}
|
|
13286
13232
|
})
|
|
13287
13233
|
};
|
|
13288
13234
|
}
|
|
@@ -13318,7 +13264,7 @@ function modelsTool(providers, activeProviders) {
|
|
|
13318
13264
|
handler: async (args) => runModels(args, { providers, activeProviders })
|
|
13319
13265
|
};
|
|
13320
13266
|
}
|
|
13321
|
-
function reviewTool(providers, allowlist,
|
|
13267
|
+
function reviewTool(providers, allowlist, storage, breakers, transcriptsDir, repoRoot) {
|
|
13322
13268
|
return {
|
|
13323
13269
|
name: "review",
|
|
13324
13270
|
description: "Have an LLM panel peer-review a code or proposal snippet. Returns the confer envelope (one answer per provider).",
|
|
@@ -13337,7 +13283,6 @@ function reviewTool(providers, allowlist, bridge, storage, breakers, transcripts
|
|
|
13337
13283
|
handler: (args) => runReview(args, {
|
|
13338
13284
|
providers,
|
|
13339
13285
|
allowlist,
|
|
13340
|
-
...bridge ? { bridge } : {},
|
|
13341
13286
|
...storage ? { storage } : {},
|
|
13342
13287
|
...breakers ? { breakers } : {},
|
|
13343
13288
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -13345,7 +13290,7 @@ function reviewTool(providers, allowlist, bridge, storage, breakers, transcripts
|
|
|
13345
13290
|
})
|
|
13346
13291
|
};
|
|
13347
13292
|
}
|
|
13348
|
-
function critiqueTool(providers, allowlist,
|
|
13293
|
+
function critiqueTool(providers, allowlist, storage, breakers, transcriptsDir, repoRoot) {
|
|
13349
13294
|
return {
|
|
13350
13295
|
name: "critique",
|
|
13351
13296
|
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.",
|
|
@@ -13365,7 +13310,6 @@ function critiqueTool(providers, allowlist, bridge, storage, breakers, transcrip
|
|
|
13365
13310
|
handler: (args) => runCritique(args, {
|
|
13366
13311
|
providers,
|
|
13367
13312
|
allowlist,
|
|
13368
|
-
...bridge ? { bridge } : {},
|
|
13369
13313
|
...storage ? { storage } : {},
|
|
13370
13314
|
...breakers ? { breakers } : {},
|
|
13371
13315
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -13373,7 +13317,7 @@ function critiqueTool(providers, allowlist, bridge, storage, breakers, transcrip
|
|
|
13373
13317
|
})
|
|
13374
13318
|
};
|
|
13375
13319
|
}
|
|
13376
|
-
function planTool(providers, allowlist,
|
|
13320
|
+
function planTool(providers, allowlist, storage, breakers, transcriptsDir, repoRoot) {
|
|
13377
13321
|
return {
|
|
13378
13322
|
name: "plan",
|
|
13379
13323
|
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.',
|
|
@@ -13400,7 +13344,6 @@ function planTool(providers, allowlist, bridge, storage, breakers, transcriptsDi
|
|
|
13400
13344
|
handler: (args) => runPlan(args, {
|
|
13401
13345
|
providers,
|
|
13402
13346
|
allowlist,
|
|
13403
|
-
...bridge ? { bridge } : {},
|
|
13404
13347
|
...storage ? { storage } : {},
|
|
13405
13348
|
...breakers ? { breakers } : {},
|
|
13406
13349
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -13408,7 +13351,7 @@ function planTool(providers, allowlist, bridge, storage, breakers, transcriptsDi
|
|
|
13408
13351
|
})
|
|
13409
13352
|
};
|
|
13410
13353
|
}
|
|
13411
|
-
function triangulateTool(providers, allowlist,
|
|
13354
|
+
function triangulateTool(providers, allowlist, storage, breakers, transcriptsDir, repoRoot) {
|
|
13412
13355
|
return {
|
|
13413
13356
|
name: "triangulate",
|
|
13414
13357
|
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.",
|
|
@@ -13429,7 +13372,6 @@ function triangulateTool(providers, allowlist, bridge, storage, breakers, transc
|
|
|
13429
13372
|
handler: (args) => runTriangulate(args, {
|
|
13430
13373
|
providers,
|
|
13431
13374
|
allowlist,
|
|
13432
|
-
...bridge ? { bridge } : {},
|
|
13433
13375
|
...storage ? { storage } : {},
|
|
13434
13376
|
...breakers ? { breakers } : {},
|
|
13435
13377
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -13437,7 +13379,7 @@ function triangulateTool(providers, allowlist, bridge, storage, breakers, transc
|
|
|
13437
13379
|
})
|
|
13438
13380
|
};
|
|
13439
13381
|
}
|
|
13440
|
-
function coordinateTool(providers, allowlist,
|
|
13382
|
+
function coordinateTool(providers, allowlist, innerCallers, storage, breakers, transcriptsDir, repoRoot, workerToolsCfg) {
|
|
13441
13383
|
return {
|
|
13442
13384
|
name: "coordinate",
|
|
13443
13385
|
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).",
|
|
@@ -13462,7 +13404,6 @@ function coordinateTool(providers, allowlist, bridge, innerCallers, storage, bre
|
|
|
13462
13404
|
handler: (args) => runCoordinate(args, {
|
|
13463
13405
|
providers,
|
|
13464
13406
|
allowlist,
|
|
13465
|
-
...bridge ? { bridge } : {},
|
|
13466
13407
|
innerCallers,
|
|
13467
13408
|
...storage ? { storage } : {},
|
|
13468
13409
|
...breakers ? { breakers } : {},
|
|
@@ -13472,7 +13413,7 @@ function coordinateTool(providers, allowlist, bridge, innerCallers, storage, bre
|
|
|
13472
13413
|
})
|
|
13473
13414
|
};
|
|
13474
13415
|
}
|
|
13475
|
-
function debateTool(providers, allowlist,
|
|
13416
|
+
function debateTool(providers, allowlist, innerCallers, storage, pricing, breakers, transcriptsDir, repoRoot, workerToolsCfg) {
|
|
13476
13417
|
return {
|
|
13477
13418
|
name: "debate",
|
|
13478
13419
|
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).",
|
|
@@ -13502,7 +13443,6 @@ function debateTool(providers, allowlist, bridge, innerCallers, storage, pricing
|
|
|
13502
13443
|
handler: (args) => runDebate(args, {
|
|
13503
13444
|
providers,
|
|
13504
13445
|
allowlist,
|
|
13505
|
-
...bridge ? { bridge } : {},
|
|
13506
13446
|
innerCallers,
|
|
13507
13447
|
...storage ? { storage } : {},
|
|
13508
13448
|
...pricing ? { pricing } : {},
|
|
@@ -13522,10 +13462,10 @@ function buildInnerCallers(o) {
|
|
|
13522
13462
|
...o.repoRoot ? { repoRoot: o.repoRoot } : {}
|
|
13523
13463
|
});
|
|
13524
13464
|
}
|
|
13525
|
-
out.verify = (args) => runVerify(args, o.
|
|
13465
|
+
out.verify = (args) => runVerify(args, o.fetchConfig);
|
|
13526
13466
|
return out;
|
|
13527
13467
|
}
|
|
13528
|
-
function conferTool(providers, allowlist,
|
|
13468
|
+
function conferTool(providers, allowlist, moderator, pricing, storage, innerCallers, breakers, transcriptsDir, repoRoot, workerToolsCfg) {
|
|
13529
13469
|
return {
|
|
13530
13470
|
name: "confer",
|
|
13531
13471
|
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).",
|
|
@@ -13552,7 +13492,6 @@ function conferTool(providers, allowlist, bridge, moderator, pricing, storage, i
|
|
|
13552
13492
|
handler: (args) => runConfer(args, {
|
|
13553
13493
|
providers,
|
|
13554
13494
|
allowlist,
|
|
13555
|
-
...bridge ? { bridge } : {},
|
|
13556
13495
|
moderator,
|
|
13557
13496
|
...pricing ? { pricing } : {},
|
|
13558
13497
|
...storage ? { storage } : {},
|
|
@@ -13564,7 +13503,7 @@ function conferTool(providers, allowlist, bridge, moderator, pricing, storage, i
|
|
|
13564
13503
|
})
|
|
13565
13504
|
};
|
|
13566
13505
|
}
|
|
13567
|
-
function auditTool(providers, allowlist,
|
|
13506
|
+
function auditTool(providers, allowlist, transcriptsDir, pricing, storage, breakers, repoRoot) {
|
|
13568
13507
|
return {
|
|
13569
13508
|
name: "audit",
|
|
13570
13509
|
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.",
|
|
@@ -13590,7 +13529,6 @@ function auditTool(providers, allowlist, bridge, transcriptsDir, pricing, storag
|
|
|
13590
13529
|
handler: (args) => runAudit(args, {
|
|
13591
13530
|
providers,
|
|
13592
13531
|
allowlist,
|
|
13593
|
-
...bridge ? { bridge } : {},
|
|
13594
13532
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
13595
13533
|
...pricing ? { pricing } : {},
|
|
13596
13534
|
...storage ? { storage } : {},
|
|
@@ -13654,7 +13592,7 @@ function pickTool(providers, allowlist, storage, breakers, transcriptsDir, repoR
|
|
|
13654
13592
|
})
|
|
13655
13593
|
};
|
|
13656
13594
|
}
|
|
13657
|
-
function verifyTool(
|
|
13595
|
+
function verifyTool(fetchConfig) {
|
|
13658
13596
|
return {
|
|
13659
13597
|
name: "verify",
|
|
13660
13598
|
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.",
|
|
@@ -13672,7 +13610,7 @@ function verifyTool(bridge, fetchConfig) {
|
|
|
13672
13610
|
},
|
|
13673
13611
|
required: ["checks"]
|
|
13674
13612
|
},
|
|
13675
|
-
handler: (args) => runVerify(args,
|
|
13613
|
+
handler: (args) => runVerify(args, fetchConfig)
|
|
13676
13614
|
};
|
|
13677
13615
|
}
|
|
13678
13616
|
function pingTool() {
|
|
@@ -13722,7 +13660,7 @@ function createCrosscheck(opts) {
|
|
|
13722
13660
|
// Direct runConfer call with a streaming hook — bypasses the tool
|
|
13723
13661
|
// registry (whose handler signature can't carry a callback). Uses the
|
|
13724
13662
|
// same opts the registry wires for confer in a browser build: providers
|
|
13725
|
-
// + pricing + default moderator; storage/
|
|
13663
|
+
// + pricing + default moderator; storage/innerCallers aren't
|
|
13726
13664
|
// available here, matching the non-streaming path.
|
|
13727
13665
|
conferStream: (args, onAnswer) => runConfer(args, { providers, pricing: pricingDoc, moderator: "anthropic", onAnswer }),
|
|
13728
13666
|
debateStream: (args, { onTurn, onSynthesis } = {}) => runDebate(args, {
|