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/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() {
|
|
@@ -797,6 +924,52 @@ function rejectsDisabledThinking(model) {
|
|
|
797
924
|
const m = model.toLowerCase();
|
|
798
925
|
return ADAPTIVE_THINKING_PREFIXES.some((p) => m.startsWith(p));
|
|
799
926
|
}
|
|
927
|
+
var NO_FORCED_TOOL_PREFIXES = [
|
|
928
|
+
"claude-fable-5-1",
|
|
929
|
+
"claude-mythos-5-1",
|
|
930
|
+
"claude-opus-5-5",
|
|
931
|
+
"claude-sonnet-5-5"
|
|
932
|
+
];
|
|
933
|
+
function rejectsForcedToolUse(model) {
|
|
934
|
+
const m = model.toLowerCase();
|
|
935
|
+
return NO_FORCED_TOOL_PREFIXES.some((p) => m.startsWith(p));
|
|
936
|
+
}
|
|
937
|
+
var UNSUPPORTED_SCHEMA_KEYS = /* @__PURE__ */ new Set([
|
|
938
|
+
"minimum",
|
|
939
|
+
"maximum",
|
|
940
|
+
"exclusiveMinimum",
|
|
941
|
+
"exclusiveMaximum",
|
|
942
|
+
"multipleOf",
|
|
943
|
+
"minLength",
|
|
944
|
+
"maxLength",
|
|
945
|
+
"pattern",
|
|
946
|
+
"minItems",
|
|
947
|
+
"maxItems",
|
|
948
|
+
"uniqueItems",
|
|
949
|
+
"minProperties",
|
|
950
|
+
"maxProperties",
|
|
951
|
+
"$schema"
|
|
952
|
+
]);
|
|
953
|
+
function toStructuredOutputSchema(schema) {
|
|
954
|
+
const walk = (node) => {
|
|
955
|
+
if (Array.isArray(node)) return node.map(walk);
|
|
956
|
+
if (!node || typeof node !== "object") return node;
|
|
957
|
+
const out = {};
|
|
958
|
+
for (const [k, v] of Object.entries(node)) {
|
|
959
|
+
if (UNSUPPORTED_SCHEMA_KEYS.has(k)) continue;
|
|
960
|
+
if (k === "properties" && v && typeof v === "object") {
|
|
961
|
+
out[k] = Object.fromEntries(Object.entries(v).map(([pk, pv]) => [pk, walk(pv)]));
|
|
962
|
+
} else if (["items", "anyOf", "allOf", "oneOf", "not", "$defs", "definitions"].includes(k)) {
|
|
963
|
+
out[k] = k === "$defs" || k === "definitions" ? Object.fromEntries(Object.entries(v ?? {}).map(([dk, dv]) => [dk, walk(dv)])) : walk(v);
|
|
964
|
+
} else {
|
|
965
|
+
out[k] = v;
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
if (out["type"] === "object" || "properties" in out) out["additionalProperties"] = false;
|
|
969
|
+
return out;
|
|
970
|
+
};
|
|
971
|
+
return walk(schema);
|
|
972
|
+
}
|
|
800
973
|
var ANTHROPIC_STRUCTURED_TOOL_NAME = "structured_output";
|
|
801
974
|
function applyPromptCaching(body, env = process.env) {
|
|
802
975
|
const flag = (env["CROSSCHECK_ANTHROPIC_PROMPT_CACHE"] ?? "").trim();
|
|
@@ -848,7 +1021,12 @@ function buildAnthropicRequest(opts) {
|
|
|
848
1021
|
body.thinking = { type: "disabled" };
|
|
849
1022
|
}
|
|
850
1023
|
}
|
|
851
|
-
if (opts.jsonSchema) {
|
|
1024
|
+
if (opts.jsonSchema && rejectsForcedToolUse(opts.model)) {
|
|
1025
|
+
body.output_config = {
|
|
1026
|
+
...body.output_config ?? {},
|
|
1027
|
+
format: { type: "json_schema", schema: toStructuredOutputSchema(opts.jsonSchema) }
|
|
1028
|
+
};
|
|
1029
|
+
} else if (opts.jsonSchema) {
|
|
852
1030
|
body.tools = [{
|
|
853
1031
|
name: ANTHROPIC_STRUCTURED_TOOL_NAME,
|
|
854
1032
|
description: "Emit a single JSON object matching the requested schema.",
|
|
@@ -967,7 +1145,11 @@ async function sendAnthropic(args) {
|
|
|
967
1145
|
try {
|
|
968
1146
|
respLike = await doFetch(url, init);
|
|
969
1147
|
} catch (e) {
|
|
970
|
-
|
|
1148
|
+
const d = diagnoseNetworkError(e);
|
|
1149
|
+
if (!looksLikeNetworkFailure(d)) throw e;
|
|
1150
|
+
throw new ProviderError(d.kind, networkErrorMessage("anthropic", d), {
|
|
1151
|
+
transient: d.transient
|
|
1152
|
+
});
|
|
971
1153
|
}
|
|
972
1154
|
const status = respLike.status;
|
|
973
1155
|
if (status >= 200 && status < 300) {
|
|
@@ -1040,6 +1222,11 @@ function jsonSchemaToGeminiSchema(schema) {
|
|
|
1040
1222
|
}
|
|
1041
1223
|
return out;
|
|
1042
1224
|
}
|
|
1225
|
+
var GEMINI_THINKING_HEADROOM_TOKENS = 16384;
|
|
1226
|
+
function thinkingHeadroom() {
|
|
1227
|
+
const raw = Number(process.env["CROSSCHECK_GEMINI_THINKING_HEADROOM_TOKENS"]);
|
|
1228
|
+
return Number.isFinite(raw) && raw >= 0 ? Math.trunc(raw) : GEMINI_THINKING_HEADROOM_TOKENS;
|
|
1229
|
+
}
|
|
1043
1230
|
function buildGeminiRequest(opts) {
|
|
1044
1231
|
const contents = [];
|
|
1045
1232
|
let systemText = null;
|
|
@@ -1058,8 +1245,9 @@ function buildGeminiRequest(opts) {
|
|
|
1058
1245
|
const body = {
|
|
1059
1246
|
contents,
|
|
1060
1247
|
generationConfig: {
|
|
1061
|
-
|
|
1062
|
-
|
|
1248
|
+
// Answer budget + thinking headroom. No temperature / topP / topK /
|
|
1249
|
+
// thinkingBudget, on any model — see the header note.
|
|
1250
|
+
maxOutputTokens: opts.maxTokens + thinkingHeadroom()
|
|
1063
1251
|
}
|
|
1064
1252
|
};
|
|
1065
1253
|
if (systemText !== null && systemText !== "") {
|
|
@@ -1069,8 +1257,8 @@ function buildGeminiRequest(opts) {
|
|
|
1069
1257
|
body.generationConfig.responseMimeType = "application/json";
|
|
1070
1258
|
body.generationConfig.responseSchema = jsonSchemaToGeminiSchema(opts.jsonSchema);
|
|
1071
1259
|
}
|
|
1072
|
-
const url = `${GEMINI_API_URL_BASE}/${encodeURIComponent(opts.model)}:generateContent
|
|
1073
|
-
return { url, headers: {}, body };
|
|
1260
|
+
const url = `${GEMINI_API_URL_BASE}/${encodeURIComponent(opts.model)}:generateContent`;
|
|
1261
|
+
return { url, headers: { "x-goog-api-key": opts.apiKey }, body };
|
|
1074
1262
|
}
|
|
1075
1263
|
function parseGeminiResponse(opts) {
|
|
1076
1264
|
const r = opts.resp ?? {};
|
|
@@ -1100,16 +1288,19 @@ function parseGeminiResponse(opts) {
|
|
|
1100
1288
|
}
|
|
1101
1289
|
try {
|
|
1102
1290
|
const first = cands[0];
|
|
1103
|
-
const
|
|
1104
|
-
const
|
|
1291
|
+
const finishReason = typeof first["finishReason"] === "string" ? first["finishReason"] : void 0;
|
|
1292
|
+
const content = first["content"] ?? {};
|
|
1293
|
+
const parts = Array.isArray(content["parts"]) ? content["parts"] : [];
|
|
1105
1294
|
let text = "";
|
|
1106
1295
|
for (const p of parts) {
|
|
1107
1296
|
if (p && typeof p === "object") {
|
|
1108
|
-
const
|
|
1297
|
+
const part = p;
|
|
1298
|
+
if (part["thought"] === true) continue;
|
|
1299
|
+
const t = part["text"];
|
|
1109
1300
|
if (typeof t === "string") text += t;
|
|
1110
1301
|
}
|
|
1111
1302
|
}
|
|
1112
|
-
return { text, usage };
|
|
1303
|
+
return { text, usage, ...finishReason ? { finishReason } : {} };
|
|
1113
1304
|
} catch (e) {
|
|
1114
1305
|
throw new ProviderError(
|
|
1115
1306
|
"parse",
|
|
@@ -1138,7 +1329,8 @@ async function sendGemini(args) {
|
|
|
1138
1329
|
apiKey: args.apiKey,
|
|
1139
1330
|
messages: args.messages,
|
|
1140
1331
|
maxTokens: args.maxTokens,
|
|
1141
|
-
|
|
1332
|
+
// args.temperature is deliberately NOT forwarded: Gemini ignores it and
|
|
1333
|
+
// upcoming models reject it. See the header note.
|
|
1142
1334
|
...args.jsonSchema ? { jsonSchema: args.jsonSchema } : {}
|
|
1143
1335
|
});
|
|
1144
1336
|
const doFetch = args.fetchImpl ?? globalThis.fetch;
|
|
@@ -1153,7 +1345,11 @@ async function sendGemini(args) {
|
|
|
1153
1345
|
try {
|
|
1154
1346
|
respLike = await doFetch(url, init);
|
|
1155
1347
|
} catch (e) {
|
|
1156
|
-
|
|
1348
|
+
const d = diagnoseNetworkError(e);
|
|
1349
|
+
if (!looksLikeNetworkFailure(d)) throw e;
|
|
1350
|
+
throw new ProviderError(d.kind, networkErrorMessage("gemini", d), {
|
|
1351
|
+
transient: d.transient
|
|
1352
|
+
});
|
|
1157
1353
|
}
|
|
1158
1354
|
const status = respLike.status;
|
|
1159
1355
|
if (status >= 200 && status < 300) {
|
|
@@ -1163,11 +1359,18 @@ async function sendGemini(args) {
|
|
|
1163
1359
|
} catch (e) {
|
|
1164
1360
|
throw new ProviderError("parse", `gemini: response body not JSON: ${e.message}`);
|
|
1165
1361
|
}
|
|
1166
|
-
const { text, usage } = parseGeminiResponse({
|
|
1362
|
+
const { text, usage, finishReason } = parseGeminiResponse({
|
|
1167
1363
|
resp: parsed,
|
|
1168
1364
|
model: args.model,
|
|
1169
1365
|
purpose: args.purpose ?? "worker"
|
|
1170
1366
|
});
|
|
1367
|
+
if (text.trim() === "" && finishReason === "MAX_TOKENS") {
|
|
1368
|
+
throw new ProviderError(
|
|
1369
|
+
"parse",
|
|
1370
|
+
`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.`,
|
|
1371
|
+
{ transient: false }
|
|
1372
|
+
);
|
|
1373
|
+
}
|
|
1171
1374
|
return { text, attempts: 1, usage: applyPricing2(usage, args.pricing) };
|
|
1172
1375
|
}
|
|
1173
1376
|
const bodyText = await respLike.text().catch(() => "");
|
|
@@ -1224,7 +1427,15 @@ function buildOpenAICompatibleRequest(opts) {
|
|
|
1224
1427
|
json_schema: {
|
|
1225
1428
|
name: "structured_output",
|
|
1226
1429
|
schema: opts.jsonSchema,
|
|
1227
|
-
strict:
|
|
1430
|
+
// NOT strict. Strict mode requires `additionalProperties: false` on
|
|
1431
|
+
// every object and every property listed in `required` — the
|
|
1432
|
+
// engine's schemas don't meet that, so every structured OpenAI call
|
|
1433
|
+
// (planner, judges, synthesis) was a 400, unnoticed until the canary
|
|
1434
|
+
// grew a structured check (2026-10-11). Non-strict still shapes the
|
|
1435
|
+
// reply to the schema, and structured.ts validates it against the
|
|
1436
|
+
// full schema regardless, so strictness added a failure mode and no
|
|
1437
|
+
// safety.
|
|
1438
|
+
strict: false
|
|
1228
1439
|
}
|
|
1229
1440
|
};
|
|
1230
1441
|
}
|
|
@@ -1334,7 +1545,11 @@ async function sendOpenAICompatible(args) {
|
|
|
1334
1545
|
try {
|
|
1335
1546
|
respLike = await doFetch(url, init);
|
|
1336
1547
|
} catch (e) {
|
|
1337
|
-
|
|
1548
|
+
const d = diagnoseNetworkError(e);
|
|
1549
|
+
if (!looksLikeNetworkFailure(d)) throw e;
|
|
1550
|
+
throw new ProviderError(d.kind, networkErrorMessage(args.provider, d), {
|
|
1551
|
+
transient: d.transient
|
|
1552
|
+
});
|
|
1338
1553
|
}
|
|
1339
1554
|
const status = respLike.status;
|
|
1340
1555
|
if (status >= 200 && status < 300) {
|
|
@@ -1508,7 +1723,7 @@ var import_zod = require("zod");
|
|
|
1508
1723
|
|
|
1509
1724
|
// src/server-meta.ts
|
|
1510
1725
|
var SERVER_NAME = "crosscheck-agent";
|
|
1511
|
-
var SERVER_VERSION = true ? "0.2.
|
|
1726
|
+
var SERVER_VERSION = true ? "0.2.29" : "0.0.0-dev";
|
|
1512
1727
|
|
|
1513
1728
|
// src/tools/audit.ts
|
|
1514
1729
|
var import_node_fs4 = require("fs");
|
|
@@ -1731,6 +1946,31 @@ function pyReprType(t) {
|
|
|
1731
1946
|
return String(t);
|
|
1732
1947
|
}
|
|
1733
1948
|
|
|
1949
|
+
// src/core/session.ts
|
|
1950
|
+
var import_node_crypto = require("crypto");
|
|
1951
|
+
var processSessionId = null;
|
|
1952
|
+
var startedAt = null;
|
|
1953
|
+
function engineSessionId() {
|
|
1954
|
+
if (processSessionId === null) {
|
|
1955
|
+
processSessionId = (0, import_node_crypto.randomUUID)();
|
|
1956
|
+
startedAt = Date.now();
|
|
1957
|
+
}
|
|
1958
|
+
return processSessionId;
|
|
1959
|
+
}
|
|
1960
|
+
function resolveSessionId(callerSupplied) {
|
|
1961
|
+
const trimmed = typeof callerSupplied === "string" ? callerSupplied.trim() : "";
|
|
1962
|
+
return trimmed.length > 0 ? trimmed : engineSessionId();
|
|
1963
|
+
}
|
|
1964
|
+
function localSessionRecordingEnabled(env = globalThis.process?.env ?? {}) {
|
|
1965
|
+
const v = (env["CROSSCHECK_RECORD_SESSIONS"] ?? "").trim().toLowerCase();
|
|
1966
|
+
return !["0", "false", "off", "no"].includes(v);
|
|
1967
|
+
}
|
|
1968
|
+
function recordingSessionId(callerSupplied) {
|
|
1969
|
+
if (localSessionRecordingEnabled()) return resolveSessionId(callerSupplied);
|
|
1970
|
+
const trimmed = typeof callerSupplied === "string" ? callerSupplied.trim() : "";
|
|
1971
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
1972
|
+
}
|
|
1973
|
+
|
|
1734
1974
|
// src/core/usage.ts
|
|
1735
1975
|
function emptyUsage(provider, model, purpose = "worker") {
|
|
1736
1976
|
return {
|
|
@@ -1836,11 +2076,11 @@ function withCommas(n) {
|
|
|
1836
2076
|
function renderRunSummary(opts) {
|
|
1837
2077
|
const endedAt = opts.endedAtS ?? Math.trunc(Date.now() / 1e3);
|
|
1838
2078
|
let scope = "call";
|
|
1839
|
-
let
|
|
2079
|
+
let startedAt2 = null;
|
|
1840
2080
|
let rows = [];
|
|
1841
2081
|
if (opts.sessionScope && opts.sessionScope.rows.length > 0) {
|
|
1842
2082
|
scope = "session";
|
|
1843
|
-
|
|
2083
|
+
startedAt2 = opts.sessionScope.startedAt;
|
|
1844
2084
|
rows = opts.sessionScope.rows.map((r) => ({ ...r }));
|
|
1845
2085
|
} else {
|
|
1846
2086
|
const byPurpose = /* @__PURE__ */ new Map();
|
|
@@ -1871,6 +2111,7 @@ function renderRunSummary(opts) {
|
|
|
1871
2111
|
row.cpu_ms += a.cpu_ms ?? 0;
|
|
1872
2112
|
if (a.cache_hit) row.cache_hits += 1;
|
|
1873
2113
|
if (a.error) row.errors += 1;
|
|
2114
|
+
if (a.usage?.estimated) row.estimated = true;
|
|
1874
2115
|
}
|
|
1875
2116
|
rows = Array.from(byPurpose.values());
|
|
1876
2117
|
}
|
|
@@ -1883,16 +2124,18 @@ function renderRunSummary(opts) {
|
|
|
1883
2124
|
wall_ms: rows.reduce((s, r) => s + r.wall_ms, 0),
|
|
1884
2125
|
cpu_ms: rows.reduce((s, r) => s + r.cpu_ms, 0),
|
|
1885
2126
|
cache_hits: rows.reduce((s, r) => s + r.cache_hits, 0),
|
|
1886
|
-
errors: rows.reduce((s, r) => s + r.errors, 0)
|
|
2127
|
+
errors: rows.reduce((s, r) => s + r.errors, 0),
|
|
2128
|
+
...rows.some((r) => r.estimated) ? { estimated: true } : {}
|
|
1887
2129
|
};
|
|
1888
2130
|
const titleLeft = scope === "session" ? `session: ${opts.sessionId ?? ""}` : `call: ${opts.toolName}`;
|
|
1889
|
-
const
|
|
2131
|
+
const costText = totals.estimated ? `$${totals.cost_usd.toFixed(4)}+ (some calls unpriced)` : `$${totals.cost_usd.toFixed(4)}`;
|
|
2132
|
+
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
2133
|
const bodyLines = [];
|
|
1891
2134
|
for (let i = 0; i < rows.length; i++) {
|
|
1892
2135
|
const r = rows[i];
|
|
1893
2136
|
const glyph = i === rows.length - 1 ? "`-" : "|-";
|
|
1894
2137
|
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)`
|
|
2138
|
+
`${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
2139
|
);
|
|
1897
2140
|
}
|
|
1898
2141
|
const callByModel = rollupSpendByModel(
|
|
@@ -1940,7 +2183,7 @@ function renderRunSummary(opts) {
|
|
|
1940
2183
|
tool: opts.toolName,
|
|
1941
2184
|
scope,
|
|
1942
2185
|
currency: "USD",
|
|
1943
|
-
started_at:
|
|
2186
|
+
started_at: startedAt2,
|
|
1944
2187
|
ended_at: endedAt,
|
|
1945
2188
|
rows,
|
|
1946
2189
|
totals,
|
|
@@ -2065,14 +2308,15 @@ async function attachUsageBlock(result, answers, opts) {
|
|
|
2065
2308
|
delete result["_suppress_run_summary"];
|
|
2066
2309
|
}
|
|
2067
2310
|
async function appendUsageLog(storage, sessionId, toolName, answers, nowS) {
|
|
2068
|
-
|
|
2311
|
+
const sid = recordingSessionId(sessionId);
|
|
2312
|
+
if (!sid || answers.length === 0) return;
|
|
2069
2313
|
const now = nowS ?? Math.trunc(Date.now() / 1e3);
|
|
2070
2314
|
const rows = [];
|
|
2071
2315
|
for (const a of answers) {
|
|
2072
2316
|
const u = a.usage;
|
|
2073
2317
|
if (!u || typeof u.provider !== "string" || u.provider === "") continue;
|
|
2074
2318
|
rows.push({
|
|
2075
|
-
session_id:
|
|
2319
|
+
session_id: sid,
|
|
2076
2320
|
ts: now,
|
|
2077
2321
|
tool: toolName,
|
|
2078
2322
|
purpose: u.purpose ?? "worker",
|
|
@@ -2095,13 +2339,14 @@ async function appendUsageLog(storage, sessionId, toolName, answers, nowS) {
|
|
|
2095
2339
|
}
|
|
2096
2340
|
}
|
|
2097
2341
|
async function recordSessionCall(storage, sessionId, answers, wallMs, cpuMs, nowS) {
|
|
2098
|
-
|
|
2342
|
+
const sid = recordingSessionId(sessionId);
|
|
2343
|
+
if (!sid) return;
|
|
2099
2344
|
const now = nowS ?? Math.trunc(Date.now() / 1e3);
|
|
2100
2345
|
try {
|
|
2101
|
-
let existing = await storage.getSession(
|
|
2346
|
+
let existing = await storage.getSession(sid);
|
|
2102
2347
|
if (!existing) {
|
|
2103
2348
|
await storage.upsertSession({
|
|
2104
|
-
session_id:
|
|
2349
|
+
session_id: sid,
|
|
2105
2350
|
started_at: now,
|
|
2106
2351
|
last_at: now,
|
|
2107
2352
|
calls: 0,
|
|
@@ -2114,7 +2359,7 @@ async function recordSessionCall(storage, sessionId, answers, wallMs, cpuMs, now
|
|
|
2114
2359
|
total_cost_usd: 0,
|
|
2115
2360
|
total_cpu_ms: 0
|
|
2116
2361
|
});
|
|
2117
|
-
existing = await storage.getSession(
|
|
2362
|
+
existing = await storage.getSession(sid);
|
|
2118
2363
|
}
|
|
2119
2364
|
if (!existing) return;
|
|
2120
2365
|
let promptDelta = 0;
|
|
@@ -2134,7 +2379,7 @@ async function recordSessionCall(storage, sessionId, answers, wallMs, cpuMs, now
|
|
|
2134
2379
|
}
|
|
2135
2380
|
if (a.cache_hit) cacheHitDelta += 1;
|
|
2136
2381
|
}
|
|
2137
|
-
await storage.accumulateSessionTotals(
|
|
2382
|
+
await storage.accumulateSessionTotals(sid, {
|
|
2138
2383
|
calls: answers.length,
|
|
2139
2384
|
wall_ms: wallMs,
|
|
2140
2385
|
cache_hits: cacheHitDelta,
|
|
@@ -2516,7 +2761,7 @@ function buildPersonaInjection(opts) {
|
|
|
2516
2761
|
}
|
|
2517
2762
|
|
|
2518
2763
|
// src/core/canary.ts
|
|
2519
|
-
var
|
|
2764
|
+
var import_node_crypto2 = require("crypto");
|
|
2520
2765
|
|
|
2521
2766
|
// src/core/injection.ts
|
|
2522
2767
|
var INJECTION_PHRASES_RE = new RegExp(
|
|
@@ -2534,8 +2779,8 @@ var UNTRUSTED_SYSTEM_NOTE = "Some inputs in this conversation are wrapped in <un
|
|
|
2534
2779
|
function mintCanary() {
|
|
2535
2780
|
const t = process.hrtime.bigint().toString();
|
|
2536
2781
|
const pid = String(process.pid);
|
|
2537
|
-
const r = (0,
|
|
2538
|
-
const hex = (0,
|
|
2782
|
+
const r = (0, import_node_crypto2.randomBytes)(16).toString("hex");
|
|
2783
|
+
const hex = (0, import_node_crypto2.createHash)("sha256").update(`${t}-${pid}-${r}`).digest("hex").slice(0, 16).toUpperCase();
|
|
2539
2784
|
return `CC_CANARY_${hex}`;
|
|
2540
2785
|
}
|
|
2541
2786
|
function wrapUntrusted(content, canary) {
|
|
@@ -2722,7 +2967,7 @@ var import_node_fs3 = require("fs");
|
|
|
2722
2967
|
var import_node_path2 = __toESM(require("path"), 1);
|
|
2723
2968
|
|
|
2724
2969
|
// src/core/redact.ts
|
|
2725
|
-
var
|
|
2970
|
+
var import_node_crypto3 = require("crypto");
|
|
2726
2971
|
function builtinRedactionRules() {
|
|
2727
2972
|
return [
|
|
2728
2973
|
{ pattern: /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g, label: "EMAIL", prefix_group: false },
|
|
@@ -2749,7 +2994,7 @@ function hmacSuffix(cfg, label, value) {
|
|
|
2749
2994
|
const sid = cfg.session_id ?? "";
|
|
2750
2995
|
const sidBytes = Buffer.from(sid, "utf8");
|
|
2751
2996
|
const key = Buffer.concat([Buffer.from(secret), sidBytes]);
|
|
2752
|
-
const digest = (0,
|
|
2997
|
+
const digest = (0, import_node_crypto3.createHmac)("sha256", key).update(`${label}:${value}`, "utf8").digest("hex");
|
|
2753
2998
|
return digest.slice(0, 8);
|
|
2754
2999
|
}
|
|
2755
3000
|
function redactText(s, cfg) {
|
|
@@ -5066,10 +5311,6 @@ If you need supporting evidence, you may emit ONE \`<tool_call>...</tool_call>\`
|
|
|
5066
5311
|
}
|
|
5067
5312
|
|
|
5068
5313
|
// 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
5314
|
async function runConfer(args, opts) {
|
|
5074
5315
|
const callStartedWall = import_node_perf_hooks2.performance.now();
|
|
5075
5316
|
const callStartedCpu = process.cpuUsage();
|
|
@@ -5085,16 +5326,11 @@ async function runConfer(args, opts) {
|
|
|
5085
5326
|
rejectedWorkerTools.push(t);
|
|
5086
5327
|
}
|
|
5087
5328
|
}
|
|
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
|
-
}
|
|
5329
|
+
if (acceptedWorkerTools.length > 0 && !opts.innerCallers) {
|
|
5094
5330
|
return errorEnvelope2(
|
|
5095
5331
|
"CONFER_OPT_NOT_NATIVE",
|
|
5096
5332
|
"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
|
|
5333
|
+
"Native confer covers untrusted_input + early_stop + extract_claims + inject_session_memory + auto_panel. worker_tools needs innerCallers wired by the host."
|
|
5098
5334
|
);
|
|
5099
5335
|
}
|
|
5100
5336
|
const question = typeof args["question"] === "string" ? args["question"] : String(args["question"] ?? "");
|
|
@@ -5445,21 +5681,6 @@ function unknownProviderError(unknownNames, available) {
|
|
|
5445
5681
|
available_now: Object.keys(available).sort()
|
|
5446
5682
|
};
|
|
5447
5683
|
}
|
|
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
5684
|
function errorEnvelope2(code, message, hint) {
|
|
5464
5685
|
return {
|
|
5465
5686
|
tool: "confer",
|
|
@@ -5831,7 +6052,7 @@ function errorEnvelope3(code, message, hint) {
|
|
|
5831
6052
|
transient: false
|
|
5832
6053
|
};
|
|
5833
6054
|
}
|
|
5834
|
-
async function runVerify(args,
|
|
6055
|
+
async function runVerify(args, fetchConfig) {
|
|
5835
6056
|
const checks = args["checks"];
|
|
5836
6057
|
if (!Array.isArray(checks) || checks.length === 0) {
|
|
5837
6058
|
return {
|
|
@@ -5843,7 +6064,6 @@ async function runVerify(args, bridge, fetchConfig) {
|
|
|
5843
6064
|
)
|
|
5844
6065
|
};
|
|
5845
6066
|
}
|
|
5846
|
-
void bridge;
|
|
5847
6067
|
const allowShell = Boolean(args["allow_shell"] ?? false);
|
|
5848
6068
|
const wallStart = import_node_perf_hooks3.performance.now();
|
|
5849
6069
|
const cpuStart = process.cpuUsage();
|
|
@@ -6145,7 +6365,6 @@ async function runBench(args, opts) {
|
|
|
6145
6365
|
const innerOpts = {
|
|
6146
6366
|
providers: opts.providers,
|
|
6147
6367
|
allowlist: opts.allowlist ?? null,
|
|
6148
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
6149
6368
|
...opts.moderator ? { moderator: opts.moderator } : {}
|
|
6150
6369
|
};
|
|
6151
6370
|
let inner;
|
|
@@ -6357,7 +6576,7 @@ function isObj4(v) {
|
|
|
6357
6576
|
}
|
|
6358
6577
|
|
|
6359
6578
|
// src/tools/config-pin.ts
|
|
6360
|
-
var
|
|
6579
|
+
var import_node_crypto4 = require("crypto");
|
|
6361
6580
|
var import_node_fs6 = require("fs");
|
|
6362
6581
|
var import_node_path6 = __toESM(require("path"), 1);
|
|
6363
6582
|
var DEFAULT_PIN_PATH = ".crosscheck/config_pins.json";
|
|
@@ -6512,7 +6731,7 @@ function hashFile(abs) {
|
|
|
6512
6731
|
return "";
|
|
6513
6732
|
}
|
|
6514
6733
|
const normalized = stripCrBeforeLf(raw);
|
|
6515
|
-
return "sha256:" + (0,
|
|
6734
|
+
return "sha256:" + (0, import_node_crypto4.createHash)("sha256").update(normalized).digest("hex");
|
|
6516
6735
|
}
|
|
6517
6736
|
function stripCrBeforeLf(buf) {
|
|
6518
6737
|
const out = [];
|
|
@@ -6589,7 +6808,7 @@ function pyRepr2(v) {
|
|
|
6589
6808
|
}
|
|
6590
6809
|
|
|
6591
6810
|
// src/tools/create.ts
|
|
6592
|
-
var
|
|
6811
|
+
var import_node_crypto7 = require("crypto");
|
|
6593
6812
|
var import_node_fs9 = require("fs");
|
|
6594
6813
|
var import_node_path9 = __toESM(require("path"), 1);
|
|
6595
6814
|
|
|
@@ -6675,7 +6894,7 @@ function isDeadModelError(err) {
|
|
|
6675
6894
|
}
|
|
6676
6895
|
|
|
6677
6896
|
// src/core/node-cache.ts
|
|
6678
|
-
var
|
|
6897
|
+
var import_node_crypto5 = require("crypto");
|
|
6679
6898
|
var import_node_fs7 = require("fs");
|
|
6680
6899
|
var import_node_path7 = require("path");
|
|
6681
6900
|
var NODE_CACHE_KEY_VERSION = "v2";
|
|
@@ -6702,7 +6921,7 @@ function canonicalizeNodeText(s) {
|
|
|
6702
6921
|
return out;
|
|
6703
6922
|
}
|
|
6704
6923
|
function sha256Hex(s) {
|
|
6705
|
-
return (0,
|
|
6924
|
+
return (0, import_node_crypto5.createHash)("sha256").update(s, "utf8").digest("hex");
|
|
6706
6925
|
}
|
|
6707
6926
|
function nodeCacheKey(node, upstreamOutputs, provider, model) {
|
|
6708
6927
|
const canonUpstream = {};
|
|
@@ -6822,7 +7041,6 @@ var EST_TOKENS = {
|
|
|
6822
7041
|
med: [1500, 800],
|
|
6823
7042
|
high: [2500, 1500]
|
|
6824
7043
|
};
|
|
6825
|
-
var DEFERRED_OPTS2 = [];
|
|
6826
7044
|
var REACTIVE_SIGNAL_RE = /<signals>\s*(\{[\s\S]*?\})\s*<\/signals>/g;
|
|
6827
7045
|
function parseReactiveSignals(output) {
|
|
6828
7046
|
if (typeof output !== "string" || !output.includes("<signals>")) return [];
|
|
@@ -6862,17 +7080,6 @@ async function runOrchestrate(args, opts) {
|
|
|
6862
7080
|
);
|
|
6863
7081
|
if (breakerEnv) return breakerEnv;
|
|
6864
7082
|
}
|
|
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
7083
|
const goal = typeof args["goal"] === "string" ? args["goal"] : null;
|
|
6877
7084
|
const dagIn = isObj5(args["dag"]) ? args["dag"] : null;
|
|
6878
7085
|
if (goal === null === (dagIn === null)) {
|
|
@@ -7814,21 +8021,6 @@ function resolveProviders3(names, available, allowlist) {
|
|
|
7814
8021
|
}
|
|
7815
8022
|
return out;
|
|
7816
8023
|
}
|
|
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
8024
|
function errorEnvelope5(code, message, hint, kind = "client") {
|
|
7833
8025
|
return {
|
|
7834
8026
|
tool: "orchestrate",
|
|
@@ -7876,7 +8068,7 @@ function pyRound6(x) {
|
|
|
7876
8068
|
}
|
|
7877
8069
|
|
|
7878
8070
|
// src/tools/fetch.ts
|
|
7879
|
-
var
|
|
8071
|
+
var import_node_crypto6 = require("crypto");
|
|
7880
8072
|
var import_node_fs8 = require("fs");
|
|
7881
8073
|
var import_node_path8 = __toESM(require("path"), 1);
|
|
7882
8074
|
var DEFAULT_CONFIG = {
|
|
@@ -8090,10 +8282,10 @@ function extractHost(url) {
|
|
|
8090
8282
|
}
|
|
8091
8283
|
}
|
|
8092
8284
|
function sha256Hex2(s) {
|
|
8093
|
-
return (0,
|
|
8285
|
+
return (0, import_node_crypto6.createHash)("sha256").update(s, "utf8").digest("hex");
|
|
8094
8286
|
}
|
|
8095
8287
|
function sha256HexBytes(bytes) {
|
|
8096
|
-
return (0,
|
|
8288
|
+
return (0, import_node_crypto6.createHash)("sha256").update(bytes).digest("hex");
|
|
8097
8289
|
}
|
|
8098
8290
|
function resolveEvidenceDir(configured, repoRoot) {
|
|
8099
8291
|
if (import_node_path8.default.isAbsolute(configured)) return configured;
|
|
@@ -8146,6 +8338,16 @@ function buildCallContext(args) {
|
|
|
8146
8338
|
var CREATE_DOC_MAX_BYTES = 32 * 1024;
|
|
8147
8339
|
var CREATE_AUDIT_THRESHOLD = 0.7;
|
|
8148
8340
|
async function runCreate(args, opts) {
|
|
8341
|
+
const subEnvelopes = [];
|
|
8342
|
+
const tracked = (fn) => async (...a) => {
|
|
8343
|
+
const out = await fn(...a);
|
|
8344
|
+
subEnvelopes.push(out);
|
|
8345
|
+
return out;
|
|
8346
|
+
};
|
|
8347
|
+
const confer = tracked(runConfer);
|
|
8348
|
+
const orchestrate = tracked(runOrchestrate);
|
|
8349
|
+
const review = tracked(runReview);
|
|
8350
|
+
const audit = tracked(runAudit);
|
|
8149
8351
|
const instruction = typeof args["instruction"] === "string" ? args["instruction"] : String(args["instruction"] ?? "");
|
|
8150
8352
|
if (!instruction) {
|
|
8151
8353
|
return errorEnvelope6(
|
|
@@ -8182,7 +8384,7 @@ ${constraints}
|
|
|
8182
8384
|
|
|
8183
8385
|
` : "") + `DOCUMENTS (${okCount} of ${descriptors.length} ingested):
|
|
8184
8386
|
${documentsPayload}`;
|
|
8185
|
-
const scope = await
|
|
8387
|
+
const scope = await confer({
|
|
8186
8388
|
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,
|
|
8187
8389
|
context: contextBlock,
|
|
8188
8390
|
...providers !== void 0 ? { providers } : {},
|
|
@@ -8191,7 +8393,6 @@ ${documentsPayload}`;
|
|
|
8191
8393
|
}, {
|
|
8192
8394
|
providers: opts.providers,
|
|
8193
8395
|
allowlist: opts.allowlist ?? null,
|
|
8194
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
8195
8396
|
ctx
|
|
8196
8397
|
});
|
|
8197
8398
|
const scopeAnswer = Array.isArray(scope["answers"]) ? scope["answers"].filter((a) => typeof a["response"] === "string" && a["response"]).map((a) => `[${a["provider"]}]
|
|
@@ -8210,11 +8411,10 @@ ${scopeAnswer || "(none)"}
|
|
|
8210
8411
|
};
|
|
8211
8412
|
if (providers !== void 0) orchestrateArgs["providers"] = providers;
|
|
8212
8413
|
if (planOnly) orchestrateArgs["plan_only"] = true;
|
|
8213
|
-
let orchestration = await
|
|
8414
|
+
let orchestration = await orchestrate(orchestrateArgs, {
|
|
8214
8415
|
providers: opts.providers,
|
|
8215
8416
|
allowlist: opts.allowlist ?? null,
|
|
8216
8417
|
moderator,
|
|
8217
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
8218
8418
|
ctx
|
|
8219
8419
|
});
|
|
8220
8420
|
let attempts = 1;
|
|
@@ -8240,7 +8440,7 @@ ${scopeAnswer || "(none)"}
|
|
|
8240
8440
|
}
|
|
8241
8441
|
let reviewEnvelope = null;
|
|
8242
8442
|
if (!skipReview && typeof orchestration["final"] === "string" && orchestration["final"]) {
|
|
8243
|
-
reviewEnvelope = await
|
|
8443
|
+
reviewEnvelope = await review({
|
|
8244
8444
|
snippet: orchestration["final"],
|
|
8245
8445
|
intent: `final deliverable for: ${instruction}`,
|
|
8246
8446
|
...providers !== void 0 ? { providers } : {},
|
|
@@ -8249,7 +8449,6 @@ ${scopeAnswer || "(none)"}
|
|
|
8249
8449
|
}, {
|
|
8250
8450
|
providers: opts.providers,
|
|
8251
8451
|
allowlist: opts.allowlist ?? null,
|
|
8252
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
8253
8452
|
ctx
|
|
8254
8453
|
});
|
|
8255
8454
|
}
|
|
@@ -8261,7 +8460,7 @@ ${scopeAnswer || "(none)"}
|
|
|
8261
8460
|
const panelExhausted = producingPanel.length > 0 && producingPanel.every(
|
|
8262
8461
|
(p) => p in opts.providers || Object.keys(opts.providers).includes(p.toLowerCase())
|
|
8263
8462
|
) && producingPanel.length >= Object.keys(opts.providers).length;
|
|
8264
|
-
auditEnvelope = await
|
|
8463
|
+
auditEnvelope = await audit({
|
|
8265
8464
|
output_to_audit: orchestration["final"],
|
|
8266
8465
|
producing_panelists: producingPanel,
|
|
8267
8466
|
...auditRubric !== void 0 ? { rubric: auditRubric } : {},
|
|
@@ -8272,7 +8471,6 @@ ${scopeAnswer || "(none)"}
|
|
|
8272
8471
|
}, {
|
|
8273
8472
|
providers: opts.providers,
|
|
8274
8473
|
allowlist: opts.allowlist ?? null,
|
|
8275
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
8276
8474
|
ctx
|
|
8277
8475
|
});
|
|
8278
8476
|
let overallF = toNumberOrNull(auditEnvelope["overall_score"]);
|
|
@@ -8291,13 +8489,12 @@ ${retryConstraints}
|
|
|
8291
8489
|
DOCUMENTS:
|
|
8292
8490
|
${documentsPayload}`
|
|
8293
8491
|
};
|
|
8294
|
-
const retryOrchestration = await
|
|
8492
|
+
const retryOrchestration = await orchestrate(
|
|
8295
8493
|
retryOrchestrateArgs,
|
|
8296
8494
|
{
|
|
8297
8495
|
providers: opts.providers,
|
|
8298
8496
|
allowlist: opts.allowlist ?? null,
|
|
8299
8497
|
moderator,
|
|
8300
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
8301
8498
|
ctx
|
|
8302
8499
|
}
|
|
8303
8500
|
);
|
|
@@ -8306,7 +8503,7 @@ ${documentsPayload}`
|
|
|
8306
8503
|
if (typeof retryOrchestration["final"] === "string" && retryOrchestration["final"]) {
|
|
8307
8504
|
const retryPanel = computeProducingPanel(retryOrchestration);
|
|
8308
8505
|
const retryPanelExhausted = retryPanel.length > 0 && retryPanel.length >= Object.keys(opts.providers).length;
|
|
8309
|
-
auditEnvelope = await
|
|
8506
|
+
auditEnvelope = await audit({
|
|
8310
8507
|
output_to_audit: retryOrchestration["final"],
|
|
8311
8508
|
producing_panelists: retryPanel,
|
|
8312
8509
|
...auditRubric !== void 0 ? { rubric: auditRubric } : {},
|
|
@@ -8317,7 +8514,6 @@ ${documentsPayload}`
|
|
|
8317
8514
|
}, {
|
|
8318
8515
|
providers: opts.providers,
|
|
8319
8516
|
allowlist: opts.allowlist ?? null,
|
|
8320
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
8321
8517
|
ctx
|
|
8322
8518
|
});
|
|
8323
8519
|
overallF = toNumberOrNull(auditEnvelope["overall_score"]);
|
|
@@ -8382,9 +8578,28 @@ ${documentsPayload}`
|
|
|
8382
8578
|
["auditor", "items", "overall_score", "passed", "rubric"]
|
|
8383
8579
|
),
|
|
8384
8580
|
artifacts,
|
|
8385
|
-
warnings
|
|
8581
|
+
warnings,
|
|
8582
|
+
...combinedUsage(subEnvelopes)
|
|
8386
8583
|
};
|
|
8387
8584
|
}
|
|
8585
|
+
function combinedUsage(envelopes) {
|
|
8586
|
+
const usages = [];
|
|
8587
|
+
const byCallTiming = [];
|
|
8588
|
+
let wall = 0, cpu = 0;
|
|
8589
|
+
for (const env of envelopes) {
|
|
8590
|
+
const e = env ?? {};
|
|
8591
|
+
const calls = e["usage"]?.["by_call"] ?? [];
|
|
8592
|
+
const t = e["timing"] ?? {};
|
|
8593
|
+
const timing = Array.isArray(t["by_call"]) ? t["by_call"] : [];
|
|
8594
|
+
if (!Array.isArray(calls) || calls.length === 0) continue;
|
|
8595
|
+
usages.push(...calls);
|
|
8596
|
+
if (timing.length === calls.length) byCallTiming.push(...timing);
|
|
8597
|
+
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 });
|
|
8598
|
+
wall += Number(t["wall_ms"] ?? 0) || 0;
|
|
8599
|
+
cpu += Number(t["cpu_ms"] ?? 0) || 0;
|
|
8600
|
+
}
|
|
8601
|
+
return { usage: aggregateUsage(usages), timing: { wall_ms: wall, cpu_ms: cpu, by_call: byCallTiming } };
|
|
8602
|
+
}
|
|
8388
8603
|
async function ingestDocuments(documents, sessionId, opts) {
|
|
8389
8604
|
if (documents.length === 0) return [];
|
|
8390
8605
|
const out = [];
|
|
@@ -8454,7 +8669,7 @@ async function ingestDocuments(documents, sessionId, opts) {
|
|
|
8454
8669
|
source: ref,
|
|
8455
8670
|
type: "file",
|
|
8456
8671
|
status: "ok",
|
|
8457
|
-
hash: (0,
|
|
8672
|
+
hash: (0, import_node_crypto7.createHash)("sha256").update(text, "utf8").digest("hex"),
|
|
8458
8673
|
content: ""
|
|
8459
8674
|
}, text));
|
|
8460
8675
|
}
|
|
@@ -8491,7 +8706,7 @@ ${d.content}
|
|
|
8491
8706
|
function makeSessionId(opts, supplied) {
|
|
8492
8707
|
if (typeof supplied === "string" && supplied) return supplied;
|
|
8493
8708
|
const stamp = opts.nowEpochSeconds ? opts.nowEpochSeconds() : Math.floor(Date.now() / 1e3);
|
|
8494
|
-
const rnd = opts.randomBytes ? opts.randomBytes() : (0,
|
|
8709
|
+
const rnd = opts.randomBytes ? opts.randomBytes() : (0, import_node_crypto7.createHash)("sha256").update(`${stamp}-${process.pid}-${Math.random()}`).digest("hex");
|
|
8495
8710
|
const suffix = rnd.slice(0, 8);
|
|
8496
8711
|
return `${opts.toolName}-${stamp}-${suffix}`;
|
|
8497
8712
|
}
|
|
@@ -8555,11 +8770,6 @@ function errorEnvelope6(toolName, code, message, hint) {
|
|
|
8555
8770
|
|
|
8556
8771
|
// src/tools/coordinate.ts
|
|
8557
8772
|
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
8773
|
var COORDINATE_DEFAULT_TEMP = 0.4;
|
|
8564
8774
|
var ROLE_TURN_SCHEMA = {
|
|
8565
8775
|
type: "object",
|
|
@@ -8614,23 +8824,18 @@ async function runCoordinate(args, opts) {
|
|
|
8614
8824
|
rejectedWorkerTools.push(t);
|
|
8615
8825
|
}
|
|
8616
8826
|
}
|
|
8617
|
-
|
|
8618
|
-
const needsBridge = DEFERRED_OPTS3.some((k) => Boolean(args[k])) || workerToolsNeedsBridge;
|
|
8619
|
-
if (needsBridge) {
|
|
8827
|
+
if (acceptedWorkerTools.length > 0 && !opts.innerCallers) {
|
|
8620
8828
|
if (superRequested) {
|
|
8621
8829
|
return errorEnvelope7(
|
|
8622
8830
|
"COORDINATE_SUPER_NOT_NATIVE",
|
|
8623
|
-
"super mode requested
|
|
8624
|
-
"worker_tools
|
|
8831
|
+
"super mode requested with worker_tools, but innerCallers are not wired",
|
|
8832
|
+
"worker_tools needs innerCallers wired by the host. Drop worker_tools, or wire innerCallers, to use super."
|
|
8625
8833
|
);
|
|
8626
8834
|
}
|
|
8627
|
-
if (opts.bridge && opts.bridge.toolNames.has("coordinate")) {
|
|
8628
|
-
return await deferCoordinate(args, opts.bridge);
|
|
8629
|
-
}
|
|
8630
8835
|
return errorEnvelope7(
|
|
8631
8836
|
"COORDINATE_OPT_NOT_NATIVE",
|
|
8632
8837
|
"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
|
|
8838
|
+
"Native coordinate covers the three-role flow + untrusted_input + inject_session_memory. worker_tools needs innerCallers wired by the host."
|
|
8634
8839
|
);
|
|
8635
8840
|
}
|
|
8636
8841
|
const untrusted = Boolean(args["untrusted_input"]);
|
|
@@ -9030,21 +9235,6 @@ function unknownProviderError3(unknownNames, available) {
|
|
|
9030
9235
|
available_now: Object.keys(available).sort()
|
|
9031
9236
|
};
|
|
9032
9237
|
}
|
|
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
9238
|
function errorEnvelope7(code, message, hint) {
|
|
9049
9239
|
return {
|
|
9050
9240
|
tool: "coordinate",
|
|
@@ -9372,10 +9562,6 @@ function buildModeratorTranscript(transcript) {
|
|
|
9372
9562
|
|
|
9373
9563
|
// src/tools/debate.ts
|
|
9374
9564
|
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
9565
|
async function runDebate(args, opts) {
|
|
9380
9566
|
const callStartedWall = import_node_perf_hooks9.performance.now();
|
|
9381
9567
|
const callStartedCpu = process.cpuUsage();
|
|
@@ -9393,23 +9579,18 @@ async function runDebate(args, opts) {
|
|
|
9393
9579
|
rejectedWorkerTools.push(t);
|
|
9394
9580
|
}
|
|
9395
9581
|
}
|
|
9396
|
-
|
|
9397
|
-
const needsBridge = DEFERRED_OPTS4.some((k) => Boolean(args[k])) || workerToolsNeedsBridge;
|
|
9398
|
-
if (needsBridge) {
|
|
9582
|
+
if (acceptedWorkerTools.length > 0 && !opts.innerCallers) {
|
|
9399
9583
|
if (superRequested) {
|
|
9400
9584
|
return errorEnvelope9(
|
|
9401
9585
|
"DEBATE_SUPER_NOT_NATIVE",
|
|
9402
|
-
"super mode requested
|
|
9403
|
-
"worker_tools
|
|
9586
|
+
"super mode requested with worker_tools, but innerCallers are not wired",
|
|
9587
|
+
"worker_tools needs innerCallers wired by the host. Drop worker_tools, or wire innerCallers, to use super."
|
|
9404
9588
|
);
|
|
9405
9589
|
}
|
|
9406
|
-
if (opts.bridge && opts.bridge.toolNames.has("debate")) {
|
|
9407
|
-
return await deferDebate(args, opts.bridge);
|
|
9408
|
-
}
|
|
9409
9590
|
return errorEnvelope9(
|
|
9410
9591
|
"DEBATE_OPT_NOT_NATIVE",
|
|
9411
9592
|
"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
|
|
9593
|
+
"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
9594
|
);
|
|
9414
9595
|
}
|
|
9415
9596
|
const topic = typeof args["topic"] === "string" ? args["topic"] : String(args["topic"] ?? "");
|
|
@@ -9846,21 +10027,6 @@ function unknownProviderError5(unknownNames, available) {
|
|
|
9846
10027
|
available_now: Object.keys(available).sort()
|
|
9847
10028
|
};
|
|
9848
10029
|
}
|
|
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
10030
|
function errorEnvelope9(code, message, hint) {
|
|
9865
10031
|
return {
|
|
9866
10032
|
tool: "debate",
|
|
@@ -9880,9 +10046,6 @@ var DEFAULT_DELEGATION_LIMITS = {
|
|
|
9880
10046
|
};
|
|
9881
10047
|
async function runDelegate(args, opts) {
|
|
9882
10048
|
if (!opts.storage) {
|
|
9883
|
-
if (opts.bridge && opts.bridge.toolNames.has("delegate")) {
|
|
9884
|
-
return await deferDelegate(args, opts.bridge);
|
|
9885
|
-
}
|
|
9886
10049
|
return errorEnvelope10(
|
|
9887
10050
|
"DELEGATE_STORAGE_UNAVAILABLE",
|
|
9888
10051
|
"delegate needs the local database (for quota tracking), which isn't available",
|
|
@@ -9954,7 +10117,6 @@ async function runDelegate(args, opts) {
|
|
|
9954
10117
|
const innerOpts = {
|
|
9955
10118
|
providers: opts.providers,
|
|
9956
10119
|
allowlist: opts.allowlist ?? null,
|
|
9957
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
9958
10120
|
...opts.moderator ? { moderator: opts.moderator } : {}
|
|
9959
10121
|
};
|
|
9960
10122
|
let result;
|
|
@@ -9993,21 +10155,6 @@ async function record(storage, sessionId, requester, toolCall, via, accepted, no
|
|
|
9993
10155
|
created_at: nowEpochSeconds
|
|
9994
10156
|
});
|
|
9995
10157
|
}
|
|
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
10158
|
function errorEnvelope10(code, message, hint) {
|
|
10012
10159
|
return {
|
|
10013
10160
|
tool: "delegate",
|
|
@@ -10050,9 +10197,6 @@ async function runExplain(args, opts) {
|
|
|
10050
10197
|
);
|
|
10051
10198
|
}
|
|
10052
10199
|
if (!opts.storage) {
|
|
10053
|
-
if (opts.bridge && opts.bridge.toolNames.has("explain")) {
|
|
10054
|
-
return await deferExplain(args, opts.bridge);
|
|
10055
|
-
}
|
|
10056
10200
|
return errorEnvelope11(
|
|
10057
10201
|
"EXPLAIN_STORAGE_UNAVAILABLE",
|
|
10058
10202
|
"explain needs the local transcript/stats database, which isn't available",
|
|
@@ -10334,21 +10478,6 @@ function pyRepr5(v) {
|
|
|
10334
10478
|
}
|
|
10335
10479
|
return String(v);
|
|
10336
10480
|
}
|
|
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
10481
|
function errorEnvelope11(code, message, hint, kind = "client", extra = {}) {
|
|
10353
10482
|
return {
|
|
10354
10483
|
tool: "explain",
|
|
@@ -10901,9 +11030,6 @@ async function runRecall(args, opts) {
|
|
|
10901
11030
|
if (k < 1) k = 1;
|
|
10902
11031
|
if (k > 50) k = 50;
|
|
10903
11032
|
if (!opts.storage) {
|
|
10904
|
-
if (opts.bridge && opts.bridge.toolNames.has("recall")) {
|
|
10905
|
-
return await deferRecall(args, opts.bridge);
|
|
10906
|
-
}
|
|
10907
11033
|
return errorEnvelope12(
|
|
10908
11034
|
"RECALL_STORAGE_UNAVAILABLE",
|
|
10909
11035
|
"recall needs the local database, which isn't available",
|
|
@@ -10956,21 +11082,6 @@ async function runRecall(args, opts) {
|
|
|
10956
11082
|
applied_filters: applied
|
|
10957
11083
|
};
|
|
10958
11084
|
}
|
|
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
11085
|
function errorEnvelope12(code, message, hint) {
|
|
10975
11086
|
return {
|
|
10976
11087
|
tool: "recall",
|
|
@@ -10993,9 +11104,6 @@ async function runRecommendPanel(args, opts) {
|
|
|
10993
11104
|
);
|
|
10994
11105
|
}
|
|
10995
11106
|
if (!opts.storage) {
|
|
10996
|
-
if (opts.bridge && opts.bridge.toolNames.has("recommend_panel")) {
|
|
10997
|
-
return await deferRecommendPanel(args, opts.bridge);
|
|
10998
|
-
}
|
|
10999
11107
|
return errorEnvelope13(
|
|
11000
11108
|
"RECOMMEND_PANEL_STORAGE_UNAVAILABLE",
|
|
11001
11109
|
"recommend_panel needs the local stats database, which isn't available",
|
|
@@ -11058,21 +11166,6 @@ async function runRecommendPanel(args, opts) {
|
|
|
11058
11166
|
meta: result.meta
|
|
11059
11167
|
};
|
|
11060
11168
|
}
|
|
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
11169
|
function errorEnvelope13(code, message, hint) {
|
|
11077
11170
|
return {
|
|
11078
11171
|
tool: "recommend_panel",
|
|
@@ -11102,9 +11195,6 @@ function toStringArray3(v) {
|
|
|
11102
11195
|
var import_node_fs11 = require("fs");
|
|
11103
11196
|
async function runScoreboard(args, opts) {
|
|
11104
11197
|
if (!opts.storage) {
|
|
11105
|
-
if (opts.bridge && opts.bridge.toolNames.has("scoreboard")) {
|
|
11106
|
-
return await deferScoreboard(args, opts.bridge);
|
|
11107
|
-
}
|
|
11108
11198
|
return errorEnvelope14(
|
|
11109
11199
|
"SCOREBOARD_STORAGE_UNAVAILABLE",
|
|
11110
11200
|
"scoreboard needs the local stats database, which isn't available",
|
|
@@ -11227,21 +11317,6 @@ function clampInt3(raw, min, max, fallback) {
|
|
|
11227
11317
|
if (!Number.isFinite(n)) return fallback;
|
|
11228
11318
|
return Math.min(max, Math.max(min, Math.trunc(n)));
|
|
11229
11319
|
}
|
|
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
11320
|
function errorEnvelope14(code, message, hint) {
|
|
11246
11321
|
return {
|
|
11247
11322
|
tool: "scoreboard",
|
|
@@ -11278,9 +11353,6 @@ async function runSessionMemory(args, opts) {
|
|
|
11278
11353
|
);
|
|
11279
11354
|
}
|
|
11280
11355
|
if (!opts.storage) {
|
|
11281
|
-
if (opts.bridge && opts.bridge.toolNames.has("session_memory")) {
|
|
11282
|
-
return await deferSessionMemory(args, opts.bridge);
|
|
11283
|
-
}
|
|
11284
11356
|
return errorEnvelope15(
|
|
11285
11357
|
"SESSION_MEMORY_STORAGE_UNAVAILABLE",
|
|
11286
11358
|
"session_memory needs the local database, which isn't available",
|
|
@@ -11385,21 +11457,6 @@ function clampInt4(raw, min, max, fallback) {
|
|
|
11385
11457
|
if (!Number.isFinite(n)) return fallback;
|
|
11386
11458
|
return Math.min(max, Math.max(min, Math.trunc(n)));
|
|
11387
11459
|
}
|
|
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
11460
|
function errorEnvelope15(code, message, hint) {
|
|
11404
11461
|
return {
|
|
11405
11462
|
tool: "session_memory",
|
|
@@ -12019,7 +12076,7 @@ var CHECK_INTERVAL_SECONDS = 3 * 24 * 60 * 60;
|
|
|
12019
12076
|
var DEFAULT_PACKAGE = "crosscheck-cli";
|
|
12020
12077
|
var FETCH_TIMEOUT_MS = 3e3;
|
|
12021
12078
|
function engineVersion() {
|
|
12022
|
-
return true ? "0.2.
|
|
12079
|
+
return true ? "0.2.29" : "0.0.0-dev";
|
|
12023
12080
|
}
|
|
12024
12081
|
function defaultUpdateCachePath() {
|
|
12025
12082
|
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 +12848,11 @@ function helpTool() {
|
|
|
12791
12848
|
}
|
|
12792
12849
|
});
|
|
12793
12850
|
}
|
|
12794
|
-
function registerCoreTools(
|
|
12795
|
-
const o = opts && typeof opts === "object" && "toolNames" in opts ? { bridge: opts } : opts;
|
|
12851
|
+
function registerCoreTools(o = {}) {
|
|
12796
12852
|
const tools = /* @__PURE__ */ new Map();
|
|
12797
12853
|
const list = [
|
|
12798
12854
|
pingTool(),
|
|
12799
|
-
verifyTool(o.
|
|
12855
|
+
verifyTool(o.fetchConfig),
|
|
12800
12856
|
pickTool(
|
|
12801
12857
|
o.providers ?? {},
|
|
12802
12858
|
o.providerAllowlist ?? null,
|
|
@@ -12808,7 +12864,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12808
12864
|
auditTool(
|
|
12809
12865
|
o.providers ?? {},
|
|
12810
12866
|
o.providerAllowlist ?? null,
|
|
12811
|
-
o.bridge,
|
|
12812
12867
|
o.transcriptsDir,
|
|
12813
12868
|
o.pricing,
|
|
12814
12869
|
o.storage,
|
|
@@ -12818,7 +12873,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12818
12873
|
conferTool(
|
|
12819
12874
|
o.providers ?? {},
|
|
12820
12875
|
o.providerAllowlist ?? null,
|
|
12821
|
-
o.bridge,
|
|
12822
12876
|
o.moderatorDefault ?? "anthropic",
|
|
12823
12877
|
o.pricing,
|
|
12824
12878
|
o.storage,
|
|
@@ -12831,7 +12885,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12831
12885
|
debateTool(
|
|
12832
12886
|
o.providers ?? {},
|
|
12833
12887
|
o.providerAllowlist ?? null,
|
|
12834
|
-
o.bridge,
|
|
12835
12888
|
buildInnerCallers(o),
|
|
12836
12889
|
o.storage,
|
|
12837
12890
|
o.pricing,
|
|
@@ -12843,7 +12896,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12843
12896
|
coordinateTool(
|
|
12844
12897
|
o.providers ?? {},
|
|
12845
12898
|
o.providerAllowlist ?? null,
|
|
12846
|
-
o.bridge,
|
|
12847
12899
|
buildInnerCallers(o),
|
|
12848
12900
|
o.storage,
|
|
12849
12901
|
o.circuitBreakers,
|
|
@@ -12854,7 +12906,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12854
12906
|
triangulateTool(
|
|
12855
12907
|
o.providers ?? {},
|
|
12856
12908
|
o.providerAllowlist ?? null,
|
|
12857
|
-
o.bridge,
|
|
12858
12909
|
o.storage,
|
|
12859
12910
|
o.circuitBreakers,
|
|
12860
12911
|
o.transcriptsDir,
|
|
@@ -12863,7 +12914,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12863
12914
|
planTool(
|
|
12864
12915
|
o.providers ?? {},
|
|
12865
12916
|
o.providerAllowlist ?? null,
|
|
12866
|
-
o.bridge,
|
|
12867
12917
|
o.storage,
|
|
12868
12918
|
o.circuitBreakers,
|
|
12869
12919
|
o.transcriptsDir,
|
|
@@ -12872,7 +12922,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12872
12922
|
critiqueTool(
|
|
12873
12923
|
o.providers ?? {},
|
|
12874
12924
|
o.providerAllowlist ?? null,
|
|
12875
|
-
o.bridge,
|
|
12876
12925
|
o.storage,
|
|
12877
12926
|
o.circuitBreakers,
|
|
12878
12927
|
o.transcriptsDir,
|
|
@@ -12881,7 +12930,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12881
12930
|
reviewTool(
|
|
12882
12931
|
o.providers ?? {},
|
|
12883
12932
|
o.providerAllowlist ?? null,
|
|
12884
|
-
o.bridge,
|
|
12885
12933
|
o.storage,
|
|
12886
12934
|
o.circuitBreakers,
|
|
12887
12935
|
o.transcriptsDir,
|
|
@@ -12889,25 +12937,23 @@ function registerCoreTools(opts = {}) {
|
|
|
12889
12937
|
),
|
|
12890
12938
|
listProvidersTool(o.providers ?? {}, o.activeProviders ?? null, o.moderatorDefault ?? "anthropic"),
|
|
12891
12939
|
modelsTool(o.providers ?? {}, o.activeProviders ?? null),
|
|
12892
|
-
recallTool(o.storage
|
|
12893
|
-
sessionMemoryTool(o.storage
|
|
12894
|
-
scoreboardTool(o.storage, o.
|
|
12895
|
-
explainTool(o.storage, o.
|
|
12940
|
+
recallTool(o.storage),
|
|
12941
|
+
sessionMemoryTool(o.storage),
|
|
12942
|
+
scoreboardTool(o.storage, o.eventsPath),
|
|
12943
|
+
explainTool(o.storage, o.transcriptsDir),
|
|
12896
12944
|
delegateTool(
|
|
12897
12945
|
o.providers ?? {},
|
|
12898
12946
|
o.providerAllowlist ?? null,
|
|
12899
12947
|
o.storage,
|
|
12900
|
-
o.bridge,
|
|
12901
12948
|
o.moderatorDefault ?? "anthropic"
|
|
12902
12949
|
),
|
|
12903
12950
|
fetchTool(o.storage, o.fetchConfig, o.repoRoot),
|
|
12904
|
-
recommendPanelTool(o.providers ?? {}, o.storage
|
|
12951
|
+
recommendPanelTool(o.providers ?? {}, o.storage),
|
|
12905
12952
|
updateCrosscheckTool(o.repoRoot ?? null),
|
|
12906
12953
|
benchTool(
|
|
12907
12954
|
o.providers ?? {},
|
|
12908
12955
|
o.providerAllowlist ?? null,
|
|
12909
12956
|
o.storage,
|
|
12910
|
-
o.bridge,
|
|
12911
12957
|
o.moderatorDefault ?? "anthropic",
|
|
12912
12958
|
o.benchGoldensDir,
|
|
12913
12959
|
o.circuitBreakers,
|
|
@@ -12918,7 +12964,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12918
12964
|
solveTool(
|
|
12919
12965
|
o.providers ?? {},
|
|
12920
12966
|
o.providerAllowlist ?? null,
|
|
12921
|
-
o.bridge,
|
|
12922
12967
|
o.storage,
|
|
12923
12968
|
o.circuitBreakers,
|
|
12924
12969
|
o.transcriptsDir,
|
|
@@ -12927,7 +12972,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12927
12972
|
orchestrateTool(
|
|
12928
12973
|
o.providers ?? {},
|
|
12929
12974
|
o.providerAllowlist ?? null,
|
|
12930
|
-
o.bridge,
|
|
12931
12975
|
o.moderatorDefault ?? "anthropic",
|
|
12932
12976
|
o.storage,
|
|
12933
12977
|
o.pricing,
|
|
@@ -12974,7 +13018,6 @@ function createTool(o, toolName, cheapDefault) {
|
|
|
12974
13018
|
providers: o.providers ?? {},
|
|
12975
13019
|
allowlist: o.providerAllowlist ?? null,
|
|
12976
13020
|
...o.storage ? { storage: o.storage } : {},
|
|
12977
|
-
...o.bridge ? { bridge: o.bridge } : {},
|
|
12978
13021
|
...o.moderatorDefault ? { moderator: o.moderatorDefault } : {},
|
|
12979
13022
|
...o.fetchConfig ? { fetchConfig: o.fetchConfig } : {},
|
|
12980
13023
|
...o.repoRoot ? { repoRoot: o.repoRoot } : {},
|
|
@@ -12983,7 +13026,7 @@ function createTool(o, toolName, cheapDefault) {
|
|
|
12983
13026
|
})
|
|
12984
13027
|
};
|
|
12985
13028
|
}
|
|
12986
|
-
function orchestrateTool(providers, allowlist,
|
|
13029
|
+
function orchestrateTool(providers, allowlist, moderator, storage, pricing, breakers, transcriptsDir, repoRoot, nodeCache) {
|
|
12987
13030
|
return {
|
|
12988
13031
|
name: "orchestrate",
|
|
12989
13032
|
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 +13051,6 @@ function orchestrateTool(providers, allowlist, bridge, moderator, storage, prici
|
|
|
13008
13051
|
providers,
|
|
13009
13052
|
allowlist,
|
|
13010
13053
|
moderator,
|
|
13011
|
-
...bridge ? { bridge } : {},
|
|
13012
13054
|
...storage ? { storage } : {},
|
|
13013
13055
|
...pricing ? { pricing } : {},
|
|
13014
13056
|
...breakers ? { breakers } : {},
|
|
@@ -13018,7 +13060,7 @@ function orchestrateTool(providers, allowlist, bridge, moderator, storage, prici
|
|
|
13018
13060
|
})
|
|
13019
13061
|
};
|
|
13020
13062
|
}
|
|
13021
|
-
function solveTool(providers, allowlist,
|
|
13063
|
+
function solveTool(providers, allowlist, storage, breakers, transcriptsDir, repoRoot) {
|
|
13022
13064
|
return {
|
|
13023
13065
|
name: "solve",
|
|
13024
13066
|
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 +13082,6 @@ function solveTool(providers, allowlist, bridge, storage, breakers, transcriptsD
|
|
|
13040
13082
|
handler: (args) => runSolve(args, {
|
|
13041
13083
|
providers,
|
|
13042
13084
|
allowlist,
|
|
13043
|
-
...bridge ? { bridge } : {},
|
|
13044
13085
|
...storage ? { storage } : {},
|
|
13045
13086
|
...breakers ? { breakers } : {},
|
|
13046
13087
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -13079,7 +13120,7 @@ function configPinTool(repoRoot, config, rejectDriftEnv) {
|
|
|
13079
13120
|
}
|
|
13080
13121
|
};
|
|
13081
13122
|
}
|
|
13082
|
-
function benchTool(providers, allowlist, storage,
|
|
13123
|
+
function benchTool(providers, allowlist, storage, moderator, defaultGoldensDir, breakers, transcriptsDir, repoRoot) {
|
|
13083
13124
|
return {
|
|
13084
13125
|
name: "bench",
|
|
13085
13126
|
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 +13139,6 @@ function benchTool(providers, allowlist, storage, bridge, moderator, defaultGold
|
|
|
13098
13139
|
allowlist,
|
|
13099
13140
|
moderator,
|
|
13100
13141
|
...storage ? { storage } : {},
|
|
13101
|
-
...bridge ? { bridge } : {},
|
|
13102
13142
|
...defaultGoldensDir ? { defaultGoldensDir } : {},
|
|
13103
13143
|
...breakers ? { breakers } : {},
|
|
13104
13144
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -13125,7 +13165,7 @@ function updateCrosscheckTool(repoRoot) {
|
|
|
13125
13165
|
}
|
|
13126
13166
|
};
|
|
13127
13167
|
}
|
|
13128
|
-
function recommendPanelTool(providers, storage
|
|
13168
|
+
function recommendPanelTool(providers, storage) {
|
|
13129
13169
|
return {
|
|
13130
13170
|
name: "recommend_panel",
|
|
13131
13171
|
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 +13183,7 @@ function recommendPanelTool(providers, storage, bridge) {
|
|
|
13143
13183
|
},
|
|
13144
13184
|
handler: (args) => runRecommendPanel(args, {
|
|
13145
13185
|
providers,
|
|
13146
|
-
...storage ? { storage } : {}
|
|
13147
|
-
...bridge ? { bridge } : {}
|
|
13186
|
+
...storage ? { storage } : {}
|
|
13148
13187
|
})
|
|
13149
13188
|
};
|
|
13150
13189
|
}
|
|
@@ -13169,7 +13208,7 @@ function fetchTool(storage, fetchConfig, repoRoot) {
|
|
|
13169
13208
|
})
|
|
13170
13209
|
};
|
|
13171
13210
|
}
|
|
13172
|
-
function delegateTool(providers, allowlist, storage,
|
|
13211
|
+
function delegateTool(providers, allowlist, storage, moderator) {
|
|
13173
13212
|
return {
|
|
13174
13213
|
name: "delegate",
|
|
13175
13214
|
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 +13228,11 @@ function delegateTool(providers, allowlist, storage, bridge, moderator) {
|
|
|
13189
13228
|
providers,
|
|
13190
13229
|
allowlist,
|
|
13191
13230
|
moderator,
|
|
13192
|
-
...storage ? { storage } : {}
|
|
13193
|
-
...bridge ? { bridge } : {}
|
|
13231
|
+
...storage ? { storage } : {}
|
|
13194
13232
|
})
|
|
13195
13233
|
};
|
|
13196
13234
|
}
|
|
13197
|
-
function explainTool(storage,
|
|
13235
|
+
function explainTool(storage, transcriptsDir) {
|
|
13198
13236
|
return {
|
|
13199
13237
|
name: "explain",
|
|
13200
13238
|
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 +13250,11 @@ function explainTool(storage, bridge, transcriptsDir) {
|
|
|
13212
13250
|
},
|
|
13213
13251
|
handler: (args) => runExplain(args, {
|
|
13214
13252
|
...storage ? { storage } : {},
|
|
13215
|
-
...bridge ? { bridge } : {},
|
|
13216
13253
|
...transcriptsDir ? { transcriptsDir } : {}
|
|
13217
13254
|
})
|
|
13218
13255
|
};
|
|
13219
13256
|
}
|
|
13220
|
-
function scoreboardTool(storage,
|
|
13257
|
+
function scoreboardTool(storage, eventsPath) {
|
|
13221
13258
|
return {
|
|
13222
13259
|
name: "scoreboard",
|
|
13223
13260
|
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 +13268,11 @@ function scoreboardTool(storage, bridge, eventsPath) {
|
|
|
13231
13268
|
},
|
|
13232
13269
|
handler: (args) => runScoreboard(args, {
|
|
13233
13270
|
...storage ? { storage } : {},
|
|
13234
|
-
...bridge ? { bridge } : {},
|
|
13235
13271
|
...eventsPath ? { eventsPath } : {}
|
|
13236
13272
|
})
|
|
13237
13273
|
};
|
|
13238
13274
|
}
|
|
13239
|
-
function sessionMemoryTool(storage
|
|
13275
|
+
function sessionMemoryTool(storage) {
|
|
13240
13276
|
return {
|
|
13241
13277
|
name: "session_memory",
|
|
13242
13278
|
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 +13295,14 @@ function sessionMemoryTool(storage, bridge) {
|
|
|
13259
13295
|
required: ["action", "session_id"]
|
|
13260
13296
|
},
|
|
13261
13297
|
handler: (args) => runSessionMemory(args, {
|
|
13262
|
-
...storage ? { storage } : {}
|
|
13263
|
-
...bridge ? { bridge } : {}
|
|
13298
|
+
...storage ? { storage } : {}
|
|
13264
13299
|
})
|
|
13265
13300
|
};
|
|
13266
13301
|
}
|
|
13267
|
-
function recallTool(storage
|
|
13302
|
+
function recallTool(storage) {
|
|
13268
13303
|
return {
|
|
13269
13304
|
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
|
|
13305
|
+
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
13306
|
inputSchema: {
|
|
13272
13307
|
type: "object",
|
|
13273
13308
|
additionalProperties: true,
|
|
@@ -13281,8 +13316,7 @@ function recallTool(storage, bridge) {
|
|
|
13281
13316
|
required: ["query"]
|
|
13282
13317
|
},
|
|
13283
13318
|
handler: (args) => runRecall(args, {
|
|
13284
|
-
...storage ? { storage } : {}
|
|
13285
|
-
...bridge ? { bridge } : {}
|
|
13319
|
+
...storage ? { storage } : {}
|
|
13286
13320
|
})
|
|
13287
13321
|
};
|
|
13288
13322
|
}
|
|
@@ -13318,7 +13352,7 @@ function modelsTool(providers, activeProviders) {
|
|
|
13318
13352
|
handler: async (args) => runModels(args, { providers, activeProviders })
|
|
13319
13353
|
};
|
|
13320
13354
|
}
|
|
13321
|
-
function reviewTool(providers, allowlist,
|
|
13355
|
+
function reviewTool(providers, allowlist, storage, breakers, transcriptsDir, repoRoot) {
|
|
13322
13356
|
return {
|
|
13323
13357
|
name: "review",
|
|
13324
13358
|
description: "Have an LLM panel peer-review a code or proposal snippet. Returns the confer envelope (one answer per provider).",
|
|
@@ -13337,7 +13371,6 @@ function reviewTool(providers, allowlist, bridge, storage, breakers, transcripts
|
|
|
13337
13371
|
handler: (args) => runReview(args, {
|
|
13338
13372
|
providers,
|
|
13339
13373
|
allowlist,
|
|
13340
|
-
...bridge ? { bridge } : {},
|
|
13341
13374
|
...storage ? { storage } : {},
|
|
13342
13375
|
...breakers ? { breakers } : {},
|
|
13343
13376
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -13345,7 +13378,7 @@ function reviewTool(providers, allowlist, bridge, storage, breakers, transcripts
|
|
|
13345
13378
|
})
|
|
13346
13379
|
};
|
|
13347
13380
|
}
|
|
13348
|
-
function critiqueTool(providers, allowlist,
|
|
13381
|
+
function critiqueTool(providers, allowlist, storage, breakers, transcriptsDir, repoRoot) {
|
|
13349
13382
|
return {
|
|
13350
13383
|
name: "critique",
|
|
13351
13384
|
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 +13398,6 @@ function critiqueTool(providers, allowlist, bridge, storage, breakers, transcrip
|
|
|
13365
13398
|
handler: (args) => runCritique(args, {
|
|
13366
13399
|
providers,
|
|
13367
13400
|
allowlist,
|
|
13368
|
-
...bridge ? { bridge } : {},
|
|
13369
13401
|
...storage ? { storage } : {},
|
|
13370
13402
|
...breakers ? { breakers } : {},
|
|
13371
13403
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -13373,7 +13405,7 @@ function critiqueTool(providers, allowlist, bridge, storage, breakers, transcrip
|
|
|
13373
13405
|
})
|
|
13374
13406
|
};
|
|
13375
13407
|
}
|
|
13376
|
-
function planTool(providers, allowlist,
|
|
13408
|
+
function planTool(providers, allowlist, storage, breakers, transcriptsDir, repoRoot) {
|
|
13377
13409
|
return {
|
|
13378
13410
|
name: "plan",
|
|
13379
13411
|
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 +13432,6 @@ function planTool(providers, allowlist, bridge, storage, breakers, transcriptsDi
|
|
|
13400
13432
|
handler: (args) => runPlan(args, {
|
|
13401
13433
|
providers,
|
|
13402
13434
|
allowlist,
|
|
13403
|
-
...bridge ? { bridge } : {},
|
|
13404
13435
|
...storage ? { storage } : {},
|
|
13405
13436
|
...breakers ? { breakers } : {},
|
|
13406
13437
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -13408,7 +13439,7 @@ function planTool(providers, allowlist, bridge, storage, breakers, transcriptsDi
|
|
|
13408
13439
|
})
|
|
13409
13440
|
};
|
|
13410
13441
|
}
|
|
13411
|
-
function triangulateTool(providers, allowlist,
|
|
13442
|
+
function triangulateTool(providers, allowlist, storage, breakers, transcriptsDir, repoRoot) {
|
|
13412
13443
|
return {
|
|
13413
13444
|
name: "triangulate",
|
|
13414
13445
|
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 +13460,6 @@ function triangulateTool(providers, allowlist, bridge, storage, breakers, transc
|
|
|
13429
13460
|
handler: (args) => runTriangulate(args, {
|
|
13430
13461
|
providers,
|
|
13431
13462
|
allowlist,
|
|
13432
|
-
...bridge ? { bridge } : {},
|
|
13433
13463
|
...storage ? { storage } : {},
|
|
13434
13464
|
...breakers ? { breakers } : {},
|
|
13435
13465
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -13437,7 +13467,7 @@ function triangulateTool(providers, allowlist, bridge, storage, breakers, transc
|
|
|
13437
13467
|
})
|
|
13438
13468
|
};
|
|
13439
13469
|
}
|
|
13440
|
-
function coordinateTool(providers, allowlist,
|
|
13470
|
+
function coordinateTool(providers, allowlist, innerCallers, storage, breakers, transcriptsDir, repoRoot, workerToolsCfg) {
|
|
13441
13471
|
return {
|
|
13442
13472
|
name: "coordinate",
|
|
13443
13473
|
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 +13492,6 @@ function coordinateTool(providers, allowlist, bridge, innerCallers, storage, bre
|
|
|
13462
13492
|
handler: (args) => runCoordinate(args, {
|
|
13463
13493
|
providers,
|
|
13464
13494
|
allowlist,
|
|
13465
|
-
...bridge ? { bridge } : {},
|
|
13466
13495
|
innerCallers,
|
|
13467
13496
|
...storage ? { storage } : {},
|
|
13468
13497
|
...breakers ? { breakers } : {},
|
|
@@ -13472,7 +13501,7 @@ function coordinateTool(providers, allowlist, bridge, innerCallers, storage, bre
|
|
|
13472
13501
|
})
|
|
13473
13502
|
};
|
|
13474
13503
|
}
|
|
13475
|
-
function debateTool(providers, allowlist,
|
|
13504
|
+
function debateTool(providers, allowlist, innerCallers, storage, pricing, breakers, transcriptsDir, repoRoot, workerToolsCfg) {
|
|
13476
13505
|
return {
|
|
13477
13506
|
name: "debate",
|
|
13478
13507
|
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 +13531,6 @@ function debateTool(providers, allowlist, bridge, innerCallers, storage, pricing
|
|
|
13502
13531
|
handler: (args) => runDebate(args, {
|
|
13503
13532
|
providers,
|
|
13504
13533
|
allowlist,
|
|
13505
|
-
...bridge ? { bridge } : {},
|
|
13506
13534
|
innerCallers,
|
|
13507
13535
|
...storage ? { storage } : {},
|
|
13508
13536
|
...pricing ? { pricing } : {},
|
|
@@ -13522,10 +13550,10 @@ function buildInnerCallers(o) {
|
|
|
13522
13550
|
...o.repoRoot ? { repoRoot: o.repoRoot } : {}
|
|
13523
13551
|
});
|
|
13524
13552
|
}
|
|
13525
|
-
out.verify = (args) => runVerify(args, o.
|
|
13553
|
+
out.verify = (args) => runVerify(args, o.fetchConfig);
|
|
13526
13554
|
return out;
|
|
13527
13555
|
}
|
|
13528
|
-
function conferTool(providers, allowlist,
|
|
13556
|
+
function conferTool(providers, allowlist, moderator, pricing, storage, innerCallers, breakers, transcriptsDir, repoRoot, workerToolsCfg) {
|
|
13529
13557
|
return {
|
|
13530
13558
|
name: "confer",
|
|
13531
13559
|
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 +13580,6 @@ function conferTool(providers, allowlist, bridge, moderator, pricing, storage, i
|
|
|
13552
13580
|
handler: (args) => runConfer(args, {
|
|
13553
13581
|
providers,
|
|
13554
13582
|
allowlist,
|
|
13555
|
-
...bridge ? { bridge } : {},
|
|
13556
13583
|
moderator,
|
|
13557
13584
|
...pricing ? { pricing } : {},
|
|
13558
13585
|
...storage ? { storage } : {},
|
|
@@ -13564,7 +13591,7 @@ function conferTool(providers, allowlist, bridge, moderator, pricing, storage, i
|
|
|
13564
13591
|
})
|
|
13565
13592
|
};
|
|
13566
13593
|
}
|
|
13567
|
-
function auditTool(providers, allowlist,
|
|
13594
|
+
function auditTool(providers, allowlist, transcriptsDir, pricing, storage, breakers, repoRoot) {
|
|
13568
13595
|
return {
|
|
13569
13596
|
name: "audit",
|
|
13570
13597
|
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 +13617,6 @@ function auditTool(providers, allowlist, bridge, transcriptsDir, pricing, storag
|
|
|
13590
13617
|
handler: (args) => runAudit(args, {
|
|
13591
13618
|
providers,
|
|
13592
13619
|
allowlist,
|
|
13593
|
-
...bridge ? { bridge } : {},
|
|
13594
13620
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
13595
13621
|
...pricing ? { pricing } : {},
|
|
13596
13622
|
...storage ? { storage } : {},
|
|
@@ -13654,7 +13680,7 @@ function pickTool(providers, allowlist, storage, breakers, transcriptsDir, repoR
|
|
|
13654
13680
|
})
|
|
13655
13681
|
};
|
|
13656
13682
|
}
|
|
13657
|
-
function verifyTool(
|
|
13683
|
+
function verifyTool(fetchConfig) {
|
|
13658
13684
|
return {
|
|
13659
13685
|
name: "verify",
|
|
13660
13686
|
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 +13698,7 @@ function verifyTool(bridge, fetchConfig) {
|
|
|
13672
13698
|
},
|
|
13673
13699
|
required: ["checks"]
|
|
13674
13700
|
},
|
|
13675
|
-
handler: (args) => runVerify(args,
|
|
13701
|
+
handler: (args) => runVerify(args, fetchConfig)
|
|
13676
13702
|
};
|
|
13677
13703
|
}
|
|
13678
13704
|
function pingTool() {
|
|
@@ -13722,7 +13748,7 @@ function createCrosscheck(opts) {
|
|
|
13722
13748
|
// Direct runConfer call with a streaming hook — bypasses the tool
|
|
13723
13749
|
// registry (whose handler signature can't carry a callback). Uses the
|
|
13724
13750
|
// same opts the registry wires for confer in a browser build: providers
|
|
13725
|
-
// + pricing + default moderator; storage/
|
|
13751
|
+
// + pricing + default moderator; storage/innerCallers aren't
|
|
13726
13752
|
// available here, matching the non-streaming path.
|
|
13727
13753
|
conferStream: (args, onAnswer) => runConfer(args, { providers, pricing: pricingDoc, moderator: "anthropic", onAnswer }),
|
|
13728
13754
|
debateStream: (args, { onTurn, onSynthesis } = {}) => runDebate(args, {
|