crosscheck-mcp 0.2.26 → 0.2.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -20
- package/dist/browser-ext.cjs +372 -381
- package/dist/browser-ext.cjs.map +1 -1
- package/dist/browser-ext.js +357 -366
- package/dist/browser-ext.js.map +1 -1
- package/dist/embed.cjs +374 -387
- package/dist/embed.cjs.map +1 -1
- package/dist/embed.d.cts +58 -1
- package/dist/embed.d.ts +58 -1
- package/dist/embed.js +352 -368
- package/dist/embed.js.map +1 -1
- package/dist/node-stdio.cjs +398 -483
- package/dist/node-stdio.cjs.map +1 -1
- package/dist/node-stdio.d.cts +11 -47
- package/dist/node-stdio.d.ts +11 -47
- package/dist/node-stdio.js +369 -454
- package/dist/node-stdio.js.map +1 -1
- package/dist/pricing.json +90 -22
- package/dist/self-check.cjs.map +1 -1
- package/dist/self-check.js.map +1 -1
- package/package.json +7 -2
package/dist/browser-ext.js
CHANGED
|
@@ -15,20 +15,24 @@ var pricing_default = {
|
|
|
15
15
|
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."
|
|
16
16
|
},
|
|
17
17
|
anthropic: {
|
|
18
|
+
_source: {
|
|
19
|
+
url: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
20
|
+
verified_at: "2026-09-27"
|
|
21
|
+
},
|
|
18
22
|
"claude-opus-4-5": {
|
|
19
|
-
prompt_per_1k:
|
|
20
|
-
completion_per_1k: 0.
|
|
21
|
-
cached_per_1k:
|
|
23
|
+
prompt_per_1k: 5e-3,
|
|
24
|
+
completion_per_1k: 0.025,
|
|
25
|
+
cached_per_1k: 5e-4
|
|
22
26
|
},
|
|
23
27
|
"claude-opus-4-7": {
|
|
24
|
-
prompt_per_1k:
|
|
25
|
-
completion_per_1k: 0.
|
|
26
|
-
cached_per_1k:
|
|
28
|
+
prompt_per_1k: 5e-3,
|
|
29
|
+
completion_per_1k: 0.025,
|
|
30
|
+
cached_per_1k: 5e-4
|
|
27
31
|
},
|
|
28
32
|
"claude-opus-4-8": {
|
|
29
|
-
prompt_per_1k:
|
|
30
|
-
completion_per_1k: 0.
|
|
31
|
-
cached_per_1k:
|
|
33
|
+
prompt_per_1k: 5e-3,
|
|
34
|
+
completion_per_1k: 0.025,
|
|
35
|
+
cached_per_1k: 5e-4
|
|
32
36
|
},
|
|
33
37
|
"claude-opus-5-5": {
|
|
34
38
|
prompt_per_1k: 4e-3,
|
|
@@ -77,10 +81,44 @@ var pricing_default = {
|
|
|
77
81
|
}
|
|
78
82
|
},
|
|
79
83
|
openai: {
|
|
84
|
+
_source: {
|
|
85
|
+
url: "https://developers.openai.com/api/docs/pricing",
|
|
86
|
+
verified_at: "2026-09-27"
|
|
87
|
+
},
|
|
88
|
+
"gpt-6-astra": {
|
|
89
|
+
prompt_per_1k: 0.01,
|
|
90
|
+
completion_per_1k: 0.05,
|
|
91
|
+
cached_per_1k: 1e-3
|
|
92
|
+
},
|
|
93
|
+
"gpt-6-sol": {
|
|
94
|
+
prompt_per_1k: 2e-3,
|
|
95
|
+
completion_per_1k: 0.01,
|
|
96
|
+
cached_per_1k: 2e-4
|
|
97
|
+
},
|
|
98
|
+
"gpt-6-luna": {
|
|
99
|
+
prompt_per_1k: 1e-4,
|
|
100
|
+
completion_per_1k: 5e-4,
|
|
101
|
+
cached_per_1k: 1e-5
|
|
102
|
+
},
|
|
103
|
+
"gpt-5.6-sol": {
|
|
104
|
+
prompt_per_1k: 4e-3,
|
|
105
|
+
completion_per_1k: 0.02,
|
|
106
|
+
cached_per_1k: 4e-4
|
|
107
|
+
},
|
|
108
|
+
"gpt-5.6-terra": {
|
|
109
|
+
prompt_per_1k: 2e-3,
|
|
110
|
+
completion_per_1k: 0.012,
|
|
111
|
+
cached_per_1k: 2e-4
|
|
112
|
+
},
|
|
113
|
+
"gpt-5.6-luna": {
|
|
114
|
+
prompt_per_1k: 2e-4,
|
|
115
|
+
completion_per_1k: 12e-4,
|
|
116
|
+
cached_per_1k: 2e-5
|
|
117
|
+
},
|
|
80
118
|
"gpt-5.6": {
|
|
81
|
-
prompt_per_1k:
|
|
82
|
-
completion_per_1k: 0.
|
|
83
|
-
cached_per_1k:
|
|
119
|
+
prompt_per_1k: 4e-3,
|
|
120
|
+
completion_per_1k: 0.02,
|
|
121
|
+
cached_per_1k: 4e-4
|
|
84
122
|
},
|
|
85
123
|
"gpt-5.5": {
|
|
86
124
|
prompt_per_1k: 5e-3,
|
|
@@ -93,9 +131,14 @@ var pricing_default = {
|
|
|
93
131
|
cached_per_1k: 125e-6
|
|
94
132
|
},
|
|
95
133
|
"gpt-5-mini": {
|
|
96
|
-
prompt_per_1k:
|
|
97
|
-
completion_per_1k:
|
|
98
|
-
cached_per_1k: 25e-
|
|
134
|
+
prompt_per_1k: 25e-5,
|
|
135
|
+
completion_per_1k: 2e-3,
|
|
136
|
+
cached_per_1k: 25e-6
|
|
137
|
+
},
|
|
138
|
+
"gpt-5-nano": {
|
|
139
|
+
prompt_per_1k: 5e-5,
|
|
140
|
+
completion_per_1k: 4e-4,
|
|
141
|
+
cached_per_1k: 5e-6
|
|
99
142
|
},
|
|
100
143
|
"gpt-4o": {
|
|
101
144
|
prompt_per_1k: 25e-4,
|
|
@@ -118,19 +161,44 @@ var pricing_default = {
|
|
|
118
161
|
cached_per_1k: 15e-4
|
|
119
162
|
},
|
|
120
163
|
o3: {
|
|
121
|
-
prompt_per_1k:
|
|
122
|
-
completion_per_1k:
|
|
123
|
-
cached_per_1k: 5e-
|
|
164
|
+
prompt_per_1k: 2e-3,
|
|
165
|
+
completion_per_1k: 8e-3,
|
|
166
|
+
cached_per_1k: 5e-4
|
|
124
167
|
},
|
|
125
168
|
"o3-mini": {
|
|
126
169
|
prompt_per_1k: 11e-4,
|
|
127
170
|
completion_per_1k: 44e-4,
|
|
128
171
|
cached_per_1k: 55e-5
|
|
129
172
|
},
|
|
130
|
-
"gpt-
|
|
131
|
-
prompt_per_1k: 0.
|
|
132
|
-
completion_per_1k: 0.
|
|
133
|
-
cached_per_1k:
|
|
173
|
+
"gpt-5-pro": {
|
|
174
|
+
prompt_per_1k: 0.015,
|
|
175
|
+
completion_per_1k: 0.12,
|
|
176
|
+
cached_per_1k: 0
|
|
177
|
+
},
|
|
178
|
+
"gpt-5.2-pro": {
|
|
179
|
+
prompt_per_1k: 0.021,
|
|
180
|
+
completion_per_1k: 0.168,
|
|
181
|
+
cached_per_1k: 0
|
|
182
|
+
},
|
|
183
|
+
"gpt-5.4-pro": {
|
|
184
|
+
prompt_per_1k: 0.03,
|
|
185
|
+
completion_per_1k: 0.18,
|
|
186
|
+
cached_per_1k: 0
|
|
187
|
+
},
|
|
188
|
+
"gpt-5.5-pro": {
|
|
189
|
+
prompt_per_1k: 0.03,
|
|
190
|
+
completion_per_1k: 0.18,
|
|
191
|
+
cached_per_1k: 0
|
|
192
|
+
},
|
|
193
|
+
"o1-pro": {
|
|
194
|
+
prompt_per_1k: 0.15,
|
|
195
|
+
completion_per_1k: 0.6,
|
|
196
|
+
cached_per_1k: 0
|
|
197
|
+
},
|
|
198
|
+
"o3-pro": {
|
|
199
|
+
prompt_per_1k: 0.02,
|
|
200
|
+
completion_per_1k: 0.08,
|
|
201
|
+
cached_per_1k: 0
|
|
134
202
|
}
|
|
135
203
|
},
|
|
136
204
|
xai: {
|
|
@@ -365,20 +433,30 @@ function modelPricing(pricing, provider, model) {
|
|
|
365
433
|
const block = pricing[provider];
|
|
366
434
|
if (!block || typeof block !== "object" || Array.isArray(block)) return null;
|
|
367
435
|
const table = block;
|
|
436
|
+
if (model.startsWith("_")) return null;
|
|
368
437
|
let entry = table[model];
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
438
|
+
let match = "exact";
|
|
439
|
+
if (!isRates(entry)) {
|
|
440
|
+
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];
|
|
441
|
+
if (best !== void 0) {
|
|
442
|
+
entry = table[best];
|
|
443
|
+
match = "stamp";
|
|
444
|
+
}
|
|
372
445
|
}
|
|
373
|
-
if (!
|
|
446
|
+
if (!isRates(entry)) return null;
|
|
374
447
|
const e = entry;
|
|
375
448
|
return {
|
|
376
449
|
prompt_per_1k: numberOrZero(e["prompt_per_1k"]),
|
|
377
450
|
completion_per_1k: numberOrZero(e["completion_per_1k"]),
|
|
378
451
|
cached_per_1k: numberOrZero(e["cached_per_1k"]),
|
|
379
|
-
...e["estimated"] === true ? { estimated: true } : {}
|
|
452
|
+
...e["estimated"] === true ? { estimated: true } : {},
|
|
453
|
+
match
|
|
380
454
|
};
|
|
381
455
|
}
|
|
456
|
+
var DATE_STAMP = /^-\d{8}$/;
|
|
457
|
+
function isRates(v) {
|
|
458
|
+
return Boolean(v) && typeof v === "object" && !Array.isArray(v);
|
|
459
|
+
}
|
|
382
460
|
function numberOrZero(v) {
|
|
383
461
|
if (typeof v === "number" && Number.isFinite(v)) return v;
|
|
384
462
|
if (typeof v === "string") {
|
|
@@ -458,8 +536,20 @@ var PROVIDER_CAPS = {
|
|
|
458
536
|
gemini: {
|
|
459
537
|
family: "gemini",
|
|
460
538
|
system_role: "separate",
|
|
461
|
-
|
|
462
|
-
|
|
539
|
+
// No sampling, on any Gemini model. Ignored since 3.6 Flash and rejected
|
|
540
|
+
// by upcoming models (Google, 2026-10). "model" means "omit for reasoning
|
|
541
|
+
// models", and every Gemini model is reasoning-class (below) — so this
|
|
542
|
+
// resolves to never, through the same rule the other providers use. The
|
|
543
|
+
// adapter also never sends it; this keeps the record honest for anything
|
|
544
|
+
// else that reads it.
|
|
545
|
+
supports_temperature: "model",
|
|
546
|
+
// EVERY Gemini model is reasoning-class. The old list named three
|
|
547
|
+
// families and missed gemini-3.8-flash — the DEFAULT — so the default
|
|
548
|
+
// model got the small non-reasoning budgets (768 tokens for an audit)
|
|
549
|
+
// while spending up to ~480 tokens of each call thinking. Google's docs
|
|
550
|
+
// say thinking cannot be switched off on current models, so a list of
|
|
551
|
+
// which ones think is a list that can only ever be incomplete.
|
|
552
|
+
reasoning_prefixes: ["gemini-"]
|
|
463
553
|
},
|
|
464
554
|
// Qwen's "Max" tier (qwen-v3.8, qwen-v3.7) is a standard instruct/chat
|
|
465
555
|
// model, not a visible-reasoning model like QwQ — normal temperature and
|
|
@@ -582,6 +672,73 @@ function httpFailureToProviderError(provider, status, bodyText, retryAfterS, mod
|
|
|
582
672
|
);
|
|
583
673
|
}
|
|
584
674
|
|
|
675
|
+
// src/providers/network-errors.ts
|
|
676
|
+
function codeOf(e) {
|
|
677
|
+
if (!e || typeof e !== "object") return null;
|
|
678
|
+
const c = e.code;
|
|
679
|
+
return typeof c === "string" && c.length > 0 ? c : null;
|
|
680
|
+
}
|
|
681
|
+
function rootCause(e, depth = 0) {
|
|
682
|
+
if (depth > 5 || !e || typeof e !== "object") return e;
|
|
683
|
+
const o = e;
|
|
684
|
+
if (Array.isArray(o.errors) && o.errors.length > 0) {
|
|
685
|
+
const coded = o.errors.find((x) => codeOf(x) !== null);
|
|
686
|
+
return rootCause(coded ?? o.errors[0], depth + 1);
|
|
687
|
+
}
|
|
688
|
+
if (o.cause !== void 0 && o.cause !== null) return rootCause(o.cause, depth + 1);
|
|
689
|
+
return e;
|
|
690
|
+
}
|
|
691
|
+
var BY_CODE = {
|
|
692
|
+
ENOTFOUND: { cause: "dns", detail: "the provider's hostname did not resolve \u2014 DNS, or a typo'd base URL", transient: false, kind: "network" },
|
|
693
|
+
EAI_AGAIN: { cause: "dns", detail: "DNS lookup failed temporarily \u2014 resolver or network is flapping", transient: true, kind: "network" },
|
|
694
|
+
ECONNREFUSED: { cause: "refused", detail: "the connection was refused \u2014 nothing is listening, or a proxy blocked it", transient: false, kind: "network" },
|
|
695
|
+
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" },
|
|
696
|
+
EPIPE: { cause: "reset", detail: "the connection closed while we were still writing", transient: true, kind: "network" },
|
|
697
|
+
ETIMEDOUT: { cause: "connect_timeout", detail: "the connection timed out before it was established", transient: true, kind: "timeout" },
|
|
698
|
+
EHOSTUNREACH: { cause: "unreachable", detail: "no route to the provider \u2014 VPN, or offline", transient: true, kind: "network" },
|
|
699
|
+
ENETUNREACH: { cause: "unreachable", detail: "the network is unreachable \u2014 offline, or a routing change", transient: true, kind: "network" },
|
|
700
|
+
ENETDOWN: { cause: "unreachable", detail: "the local network is down", transient: true, kind: "network" },
|
|
701
|
+
EPROTO: { cause: "tls", detail: "the TLS handshake failed \u2014 an intercepting proxy, or a protocol mismatch", transient: false, kind: "network" },
|
|
702
|
+
ERR_TLS_CERT_ALTNAME_INVALID: { cause: "tls", detail: "the certificate did not match the hostname \u2014 traffic is being intercepted", transient: false, kind: "network" },
|
|
703
|
+
CERT_HAS_EXPIRED: { cause: "tls", detail: "the server certificate has expired, or this machine's clock is wrong", transient: false, kind: "network" },
|
|
704
|
+
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" },
|
|
705
|
+
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" },
|
|
706
|
+
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" },
|
|
707
|
+
UND_ERR_BODY_TIMEOUT: { cause: "read_timeout", detail: "the response body stalled mid-stream", transient: true, kind: "timeout" },
|
|
708
|
+
UND_ERR_SOCKET: { cause: "reset", detail: "the socket closed unexpectedly", transient: true, kind: "network" },
|
|
709
|
+
UND_ERR_ABORTED: { cause: "aborted", detail: "the request was cancelled", transient: false, kind: "network" },
|
|
710
|
+
ABORT_ERR: { cause: "aborted", detail: "the request was cancelled", transient: false, kind: "network" }
|
|
711
|
+
};
|
|
712
|
+
function diagnoseNetworkError(e) {
|
|
713
|
+
const root = rootCause(e);
|
|
714
|
+
const code = codeOf(root) ?? codeOf(e);
|
|
715
|
+
if (code && BY_CODE[code]) return { ...BY_CODE[code], code };
|
|
716
|
+
const name = root && typeof root === "object" ? root.name : void 0;
|
|
717
|
+
if (name === "AbortError" || name === "TimeoutError") {
|
|
718
|
+
return {
|
|
719
|
+
cause: name === "TimeoutError" ? "read_timeout" : "aborted",
|
|
720
|
+
code: code ?? String(name),
|
|
721
|
+
detail: name === "TimeoutError" ? "the request exceeded its timeout" : "the request was cancelled",
|
|
722
|
+
transient: name === "TimeoutError",
|
|
723
|
+
kind: name === "TimeoutError" ? "timeout" : "network"
|
|
724
|
+
};
|
|
725
|
+
}
|
|
726
|
+
return {
|
|
727
|
+
cause: "unknown",
|
|
728
|
+
code,
|
|
729
|
+
detail: code ? `the connection failed with ${code}` : "the connection failed and the underlying error carried no code",
|
|
730
|
+
transient: true,
|
|
731
|
+
kind: "network"
|
|
732
|
+
};
|
|
733
|
+
}
|
|
734
|
+
function looksLikeNetworkFailure(d) {
|
|
735
|
+
return d.code !== null || d.cause !== "unknown";
|
|
736
|
+
}
|
|
737
|
+
function networkErrorMessage(provider, d) {
|
|
738
|
+
const code = d.code ? ` [${d.code}]` : "";
|
|
739
|
+
return `${provider}: ${d.detail}${code}`;
|
|
740
|
+
}
|
|
741
|
+
|
|
585
742
|
// src/providers/retry.ts
|
|
586
743
|
var override = null;
|
|
587
744
|
function resolveRetryConfig() {
|
|
@@ -904,7 +1061,11 @@ async function sendAnthropic(args) {
|
|
|
904
1061
|
try {
|
|
905
1062
|
respLike = await doFetch(url, init);
|
|
906
1063
|
} catch (e) {
|
|
907
|
-
|
|
1064
|
+
const d = diagnoseNetworkError(e);
|
|
1065
|
+
if (!looksLikeNetworkFailure(d)) throw e;
|
|
1066
|
+
throw new ProviderError(d.kind, networkErrorMessage("anthropic", d), {
|
|
1067
|
+
transient: d.transient
|
|
1068
|
+
});
|
|
908
1069
|
}
|
|
909
1070
|
const status = respLike.status;
|
|
910
1071
|
if (status >= 200 && status < 300) {
|
|
@@ -977,6 +1138,11 @@ function jsonSchemaToGeminiSchema(schema) {
|
|
|
977
1138
|
}
|
|
978
1139
|
return out;
|
|
979
1140
|
}
|
|
1141
|
+
var GEMINI_THINKING_HEADROOM_TOKENS = 16384;
|
|
1142
|
+
function thinkingHeadroom() {
|
|
1143
|
+
const raw = Number(process.env["CROSSCHECK_GEMINI_THINKING_HEADROOM_TOKENS"]);
|
|
1144
|
+
return Number.isFinite(raw) && raw >= 0 ? Math.trunc(raw) : GEMINI_THINKING_HEADROOM_TOKENS;
|
|
1145
|
+
}
|
|
980
1146
|
function buildGeminiRequest(opts) {
|
|
981
1147
|
const contents = [];
|
|
982
1148
|
let systemText = null;
|
|
@@ -995,8 +1161,9 @@ function buildGeminiRequest(opts) {
|
|
|
995
1161
|
const body = {
|
|
996
1162
|
contents,
|
|
997
1163
|
generationConfig: {
|
|
998
|
-
|
|
999
|
-
|
|
1164
|
+
// Answer budget + thinking headroom. No temperature / topP / topK /
|
|
1165
|
+
// thinkingBudget, on any model — see the header note.
|
|
1166
|
+
maxOutputTokens: opts.maxTokens + thinkingHeadroom()
|
|
1000
1167
|
}
|
|
1001
1168
|
};
|
|
1002
1169
|
if (systemText !== null && systemText !== "") {
|
|
@@ -1006,8 +1173,8 @@ function buildGeminiRequest(opts) {
|
|
|
1006
1173
|
body.generationConfig.responseMimeType = "application/json";
|
|
1007
1174
|
body.generationConfig.responseSchema = jsonSchemaToGeminiSchema(opts.jsonSchema);
|
|
1008
1175
|
}
|
|
1009
|
-
const url = `${GEMINI_API_URL_BASE}/${encodeURIComponent(opts.model)}:generateContent
|
|
1010
|
-
return { url, headers: {}, body };
|
|
1176
|
+
const url = `${GEMINI_API_URL_BASE}/${encodeURIComponent(opts.model)}:generateContent`;
|
|
1177
|
+
return { url, headers: { "x-goog-api-key": opts.apiKey }, body };
|
|
1011
1178
|
}
|
|
1012
1179
|
function parseGeminiResponse(opts) {
|
|
1013
1180
|
const r = opts.resp ?? {};
|
|
@@ -1037,16 +1204,19 @@ function parseGeminiResponse(opts) {
|
|
|
1037
1204
|
}
|
|
1038
1205
|
try {
|
|
1039
1206
|
const first = cands[0];
|
|
1040
|
-
const
|
|
1041
|
-
const
|
|
1207
|
+
const finishReason = typeof first["finishReason"] === "string" ? first["finishReason"] : void 0;
|
|
1208
|
+
const content = first["content"] ?? {};
|
|
1209
|
+
const parts = Array.isArray(content["parts"]) ? content["parts"] : [];
|
|
1042
1210
|
let text = "";
|
|
1043
1211
|
for (const p of parts) {
|
|
1044
1212
|
if (p && typeof p === "object") {
|
|
1045
|
-
const
|
|
1213
|
+
const part = p;
|
|
1214
|
+
if (part["thought"] === true) continue;
|
|
1215
|
+
const t = part["text"];
|
|
1046
1216
|
if (typeof t === "string") text += t;
|
|
1047
1217
|
}
|
|
1048
1218
|
}
|
|
1049
|
-
return { text, usage };
|
|
1219
|
+
return { text, usage, ...finishReason ? { finishReason } : {} };
|
|
1050
1220
|
} catch (e) {
|
|
1051
1221
|
throw new ProviderError(
|
|
1052
1222
|
"parse",
|
|
@@ -1075,7 +1245,8 @@ async function sendGemini(args) {
|
|
|
1075
1245
|
apiKey: args.apiKey,
|
|
1076
1246
|
messages: args.messages,
|
|
1077
1247
|
maxTokens: args.maxTokens,
|
|
1078
|
-
|
|
1248
|
+
// args.temperature is deliberately NOT forwarded: Gemini ignores it and
|
|
1249
|
+
// upcoming models reject it. See the header note.
|
|
1079
1250
|
...args.jsonSchema ? { jsonSchema: args.jsonSchema } : {}
|
|
1080
1251
|
});
|
|
1081
1252
|
const doFetch = args.fetchImpl ?? globalThis.fetch;
|
|
@@ -1090,7 +1261,11 @@ async function sendGemini(args) {
|
|
|
1090
1261
|
try {
|
|
1091
1262
|
respLike = await doFetch(url, init);
|
|
1092
1263
|
} catch (e) {
|
|
1093
|
-
|
|
1264
|
+
const d = diagnoseNetworkError(e);
|
|
1265
|
+
if (!looksLikeNetworkFailure(d)) throw e;
|
|
1266
|
+
throw new ProviderError(d.kind, networkErrorMessage("gemini", d), {
|
|
1267
|
+
transient: d.transient
|
|
1268
|
+
});
|
|
1094
1269
|
}
|
|
1095
1270
|
const status = respLike.status;
|
|
1096
1271
|
if (status >= 200 && status < 300) {
|
|
@@ -1100,11 +1275,18 @@ async function sendGemini(args) {
|
|
|
1100
1275
|
} catch (e) {
|
|
1101
1276
|
throw new ProviderError("parse", `gemini: response body not JSON: ${e.message}`);
|
|
1102
1277
|
}
|
|
1103
|
-
const { text, usage } = parseGeminiResponse({
|
|
1278
|
+
const { text, usage, finishReason } = parseGeminiResponse({
|
|
1104
1279
|
resp: parsed,
|
|
1105
1280
|
model: args.model,
|
|
1106
1281
|
purpose: args.purpose ?? "worker"
|
|
1107
1282
|
});
|
|
1283
|
+
if (text.trim() === "" && finishReason === "MAX_TOKENS") {
|
|
1284
|
+
throw new ProviderError(
|
|
1285
|
+
"parse",
|
|
1286
|
+
`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.`,
|
|
1287
|
+
{ transient: false }
|
|
1288
|
+
);
|
|
1289
|
+
}
|
|
1108
1290
|
return { text, attempts: 1, usage: applyPricing2(usage, args.pricing) };
|
|
1109
1291
|
}
|
|
1110
1292
|
const bodyText = await respLike.text().catch(() => "");
|
|
@@ -1271,7 +1453,11 @@ async function sendOpenAICompatible(args) {
|
|
|
1271
1453
|
try {
|
|
1272
1454
|
respLike = await doFetch(url, init);
|
|
1273
1455
|
} catch (e) {
|
|
1274
|
-
|
|
1456
|
+
const d = diagnoseNetworkError(e);
|
|
1457
|
+
if (!looksLikeNetworkFailure(d)) throw e;
|
|
1458
|
+
throw new ProviderError(d.kind, networkErrorMessage(args.provider, d), {
|
|
1459
|
+
transient: d.transient
|
|
1460
|
+
});
|
|
1275
1461
|
}
|
|
1276
1462
|
const status = respLike.status;
|
|
1277
1463
|
if (status >= 200 && status < 300) {
|
|
@@ -1299,7 +1485,7 @@ async function sendOpenAICompatible(args) {
|
|
|
1299
1485
|
// src/providers/registry.ts
|
|
1300
1486
|
var DEFAULT_MODELS = {
|
|
1301
1487
|
anthropic: "claude-opus-5-5",
|
|
1302
|
-
openai: "gpt-
|
|
1488
|
+
openai: "gpt-6-sol",
|
|
1303
1489
|
xai: "grok-4-latest",
|
|
1304
1490
|
mistral: "mistral-large-latest",
|
|
1305
1491
|
groq: "llama-3.3-70b-versatile",
|
|
@@ -1445,7 +1631,7 @@ import { z } from "zod";
|
|
|
1445
1631
|
|
|
1446
1632
|
// src/server-meta.ts
|
|
1447
1633
|
var SERVER_NAME = "crosscheck-agent";
|
|
1448
|
-
var SERVER_VERSION = true ? "0.2.
|
|
1634
|
+
var SERVER_VERSION = true ? "0.2.28" : "0.0.0-dev";
|
|
1449
1635
|
|
|
1450
1636
|
// src/tools/audit.ts
|
|
1451
1637
|
import { readdirSync, readFileSync as readFileSync3, statSync } from "fs";
|
|
@@ -1668,6 +1854,31 @@ function pyReprType(t) {
|
|
|
1668
1854
|
return String(t);
|
|
1669
1855
|
}
|
|
1670
1856
|
|
|
1857
|
+
// src/core/session.ts
|
|
1858
|
+
import { randomUUID } from "crypto";
|
|
1859
|
+
var processSessionId = null;
|
|
1860
|
+
var startedAt = null;
|
|
1861
|
+
function engineSessionId() {
|
|
1862
|
+
if (processSessionId === null) {
|
|
1863
|
+
processSessionId = randomUUID();
|
|
1864
|
+
startedAt = Date.now();
|
|
1865
|
+
}
|
|
1866
|
+
return processSessionId;
|
|
1867
|
+
}
|
|
1868
|
+
function resolveSessionId(callerSupplied) {
|
|
1869
|
+
const trimmed = typeof callerSupplied === "string" ? callerSupplied.trim() : "";
|
|
1870
|
+
return trimmed.length > 0 ? trimmed : engineSessionId();
|
|
1871
|
+
}
|
|
1872
|
+
function localSessionRecordingEnabled(env = globalThis.process?.env ?? {}) {
|
|
1873
|
+
const v = (env["CROSSCHECK_RECORD_SESSIONS"] ?? "").trim().toLowerCase();
|
|
1874
|
+
return !["0", "false", "off", "no"].includes(v);
|
|
1875
|
+
}
|
|
1876
|
+
function recordingSessionId(callerSupplied) {
|
|
1877
|
+
if (localSessionRecordingEnabled()) return resolveSessionId(callerSupplied);
|
|
1878
|
+
const trimmed = typeof callerSupplied === "string" ? callerSupplied.trim() : "";
|
|
1879
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1671
1882
|
// src/core/usage.ts
|
|
1672
1883
|
function emptyUsage(provider, model, purpose = "worker") {
|
|
1673
1884
|
return {
|
|
@@ -1773,11 +1984,11 @@ function withCommas(n) {
|
|
|
1773
1984
|
function renderRunSummary(opts) {
|
|
1774
1985
|
const endedAt = opts.endedAtS ?? Math.trunc(Date.now() / 1e3);
|
|
1775
1986
|
let scope = "call";
|
|
1776
|
-
let
|
|
1987
|
+
let startedAt2 = null;
|
|
1777
1988
|
let rows = [];
|
|
1778
1989
|
if (opts.sessionScope && opts.sessionScope.rows.length > 0) {
|
|
1779
1990
|
scope = "session";
|
|
1780
|
-
|
|
1991
|
+
startedAt2 = opts.sessionScope.startedAt;
|
|
1781
1992
|
rows = opts.sessionScope.rows.map((r) => ({ ...r }));
|
|
1782
1993
|
} else {
|
|
1783
1994
|
const byPurpose = /* @__PURE__ */ new Map();
|
|
@@ -1808,6 +2019,7 @@ function renderRunSummary(opts) {
|
|
|
1808
2019
|
row.cpu_ms += a.cpu_ms ?? 0;
|
|
1809
2020
|
if (a.cache_hit) row.cache_hits += 1;
|
|
1810
2021
|
if (a.error) row.errors += 1;
|
|
2022
|
+
if (a.usage?.estimated) row.estimated = true;
|
|
1811
2023
|
}
|
|
1812
2024
|
rows = Array.from(byPurpose.values());
|
|
1813
2025
|
}
|
|
@@ -1820,16 +2032,18 @@ function renderRunSummary(opts) {
|
|
|
1820
2032
|
wall_ms: rows.reduce((s, r) => s + r.wall_ms, 0),
|
|
1821
2033
|
cpu_ms: rows.reduce((s, r) => s + r.cpu_ms, 0),
|
|
1822
2034
|
cache_hits: rows.reduce((s, r) => s + r.cache_hits, 0),
|
|
1823
|
-
errors: rows.reduce((s, r) => s + r.errors, 0)
|
|
2035
|
+
errors: rows.reduce((s, r) => s + r.errors, 0),
|
|
2036
|
+
...rows.some((r) => r.estimated) ? { estimated: true } : {}
|
|
1824
2037
|
};
|
|
1825
2038
|
const titleLeft = scope === "session" ? `session: ${opts.sessionId ?? ""}` : `call: ${opts.toolName}`;
|
|
1826
|
-
const
|
|
2039
|
+
const costText = totals.estimated ? `$${totals.cost_usd.toFixed(4)}+ (some calls unpriced)` : `$${totals.cost_usd.toFixed(4)}`;
|
|
2040
|
+
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)`;
|
|
1827
2041
|
const bodyLines = [];
|
|
1828
2042
|
for (let i = 0; i < rows.length; i++) {
|
|
1829
2043
|
const r = rows[i];
|
|
1830
2044
|
const glyph = i === rows.length - 1 ? "`-" : "|-";
|
|
1831
2045
|
bodyLines.push(
|
|
1832
|
-
`${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)`
|
|
2046
|
+
`${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)`
|
|
1833
2047
|
);
|
|
1834
2048
|
}
|
|
1835
2049
|
const callByModel = rollupSpendByModel(
|
|
@@ -1877,7 +2091,7 @@ function renderRunSummary(opts) {
|
|
|
1877
2091
|
tool: opts.toolName,
|
|
1878
2092
|
scope,
|
|
1879
2093
|
currency: "USD",
|
|
1880
|
-
started_at:
|
|
2094
|
+
started_at: startedAt2,
|
|
1881
2095
|
ended_at: endedAt,
|
|
1882
2096
|
rows,
|
|
1883
2097
|
totals,
|
|
@@ -2002,14 +2216,15 @@ async function attachUsageBlock(result, answers, opts) {
|
|
|
2002
2216
|
delete result["_suppress_run_summary"];
|
|
2003
2217
|
}
|
|
2004
2218
|
async function appendUsageLog(storage, sessionId, toolName, answers, nowS) {
|
|
2005
|
-
|
|
2219
|
+
const sid = recordingSessionId(sessionId);
|
|
2220
|
+
if (!sid || answers.length === 0) return;
|
|
2006
2221
|
const now = nowS ?? Math.trunc(Date.now() / 1e3);
|
|
2007
2222
|
const rows = [];
|
|
2008
2223
|
for (const a of answers) {
|
|
2009
2224
|
const u = a.usage;
|
|
2010
2225
|
if (!u || typeof u.provider !== "string" || u.provider === "") continue;
|
|
2011
2226
|
rows.push({
|
|
2012
|
-
session_id:
|
|
2227
|
+
session_id: sid,
|
|
2013
2228
|
ts: now,
|
|
2014
2229
|
tool: toolName,
|
|
2015
2230
|
purpose: u.purpose ?? "worker",
|
|
@@ -2032,13 +2247,14 @@ async function appendUsageLog(storage, sessionId, toolName, answers, nowS) {
|
|
|
2032
2247
|
}
|
|
2033
2248
|
}
|
|
2034
2249
|
async function recordSessionCall(storage, sessionId, answers, wallMs, cpuMs, nowS) {
|
|
2035
|
-
|
|
2250
|
+
const sid = recordingSessionId(sessionId);
|
|
2251
|
+
if (!sid) return;
|
|
2036
2252
|
const now = nowS ?? Math.trunc(Date.now() / 1e3);
|
|
2037
2253
|
try {
|
|
2038
|
-
let existing = await storage.getSession(
|
|
2254
|
+
let existing = await storage.getSession(sid);
|
|
2039
2255
|
if (!existing) {
|
|
2040
2256
|
await storage.upsertSession({
|
|
2041
|
-
session_id:
|
|
2257
|
+
session_id: sid,
|
|
2042
2258
|
started_at: now,
|
|
2043
2259
|
last_at: now,
|
|
2044
2260
|
calls: 0,
|
|
@@ -2051,7 +2267,7 @@ async function recordSessionCall(storage, sessionId, answers, wallMs, cpuMs, now
|
|
|
2051
2267
|
total_cost_usd: 0,
|
|
2052
2268
|
total_cpu_ms: 0
|
|
2053
2269
|
});
|
|
2054
|
-
existing = await storage.getSession(
|
|
2270
|
+
existing = await storage.getSession(sid);
|
|
2055
2271
|
}
|
|
2056
2272
|
if (!existing) return;
|
|
2057
2273
|
let promptDelta = 0;
|
|
@@ -2071,7 +2287,7 @@ async function recordSessionCall(storage, sessionId, answers, wallMs, cpuMs, now
|
|
|
2071
2287
|
}
|
|
2072
2288
|
if (a.cache_hit) cacheHitDelta += 1;
|
|
2073
2289
|
}
|
|
2074
|
-
await storage.accumulateSessionTotals(
|
|
2290
|
+
await storage.accumulateSessionTotals(sid, {
|
|
2075
2291
|
calls: answers.length,
|
|
2076
2292
|
wall_ms: wallMs,
|
|
2077
2293
|
cache_hits: cacheHitDelta,
|
|
@@ -3019,13 +3235,25 @@ function numberOrNull(v) {
|
|
|
3019
3235
|
import { performance as performance2 } from "perf_hooks";
|
|
3020
3236
|
|
|
3021
3237
|
// src/core/co-reason.ts
|
|
3022
|
-
var CO_REASON_MODEL = "gpt-
|
|
3238
|
+
var CO_REASON_MODEL = "gpt-6-sol";
|
|
3239
|
+
var CO_REASON_ALTERNATE = "gpt-6-astra";
|
|
3240
|
+
var LABELS = {
|
|
3241
|
+
"gpt-6-sol": "GPT-6 Sol",
|
|
3242
|
+
"gpt-6-astra": "GPT-6 Astra",
|
|
3243
|
+
"gpt-5.6-sol": "GPT-5.6 Sol"
|
|
3244
|
+
};
|
|
3245
|
+
function coReasonLabel(model) {
|
|
3246
|
+
return LABELS[model] ?? model;
|
|
3247
|
+
}
|
|
3248
|
+
var CO_REASON_LABEL = coReasonLabel(CO_REASON_MODEL);
|
|
3023
3249
|
var CO_REASON_PROVIDER = "openai";
|
|
3024
|
-
|
|
3025
|
-
function pickCoReasoner(providers, upgradeRequested) {
|
|
3250
|
+
function pickCoReasoner(providers, upgradeRequested, openAiSeatModel) {
|
|
3026
3251
|
if (!upgradeRequested) return null;
|
|
3027
3252
|
const base = providers[CO_REASON_PROVIDER];
|
|
3028
|
-
|
|
3253
|
+
if (!base) return null;
|
|
3254
|
+
const seat = openAiSeatModel ?? base.model;
|
|
3255
|
+
const model = seat === CO_REASON_MODEL ? CO_REASON_ALTERNATE : CO_REASON_MODEL;
|
|
3256
|
+
return retargetProvider(base, model);
|
|
3029
3257
|
}
|
|
3030
3258
|
async function coReasonThenInject(opts) {
|
|
3031
3259
|
const { provider, messages, maxTokens } = opts;
|
|
@@ -3251,7 +3479,7 @@ function buildSuggestedUpgrade(toolName, assessment) {
|
|
|
3251
3479
|
model: UPGRADE_MODEL,
|
|
3252
3480
|
label: UPGRADE_LABEL,
|
|
3253
3481
|
reason: assessment.reason,
|
|
3254
|
-
how: `re-run \`${toolName}\` with reasoning:"max" (or upgrade:true) to route the lead reasoning seat to ${UPGRADE_LABEL}, and \u2014 when an OpenAI key is configured \u2014 add
|
|
3482
|
+
how: `re-run \`${toolName}\` with reasoning:"max" (or upgrade:true) to route the lead reasoning seat to ${UPGRADE_LABEL}, and \u2014 when an OpenAI key is configured \u2014 add an OpenAI second-opinion pass that ${UPGRADE_LABEL} weighs before finalizing (the result names which model ran). Other panel seats stay on their normal models.`
|
|
3255
3483
|
};
|
|
3256
3484
|
}
|
|
3257
3485
|
|
|
@@ -3554,8 +3782,9 @@ ${rubricText}`;
|
|
|
3554
3782
|
const upgradeRequested = isUpgradeRequested(args);
|
|
3555
3783
|
const upgraded = upgradeRequested && opts.providers["anthropic"] !== void 0;
|
|
3556
3784
|
const auditorForCall = upgraded ? retargetProvider(opts.providers["anthropic"], UPGRADE_MODEL) : auditor;
|
|
3785
|
+
const coProvider = pickCoReasoner(opts.providers, upgradeRequested);
|
|
3557
3786
|
const coReason = await coReasonThenInject({
|
|
3558
|
-
provider:
|
|
3787
|
+
provider: coProvider,
|
|
3559
3788
|
messages: msgs,
|
|
3560
3789
|
maxTokens: 2048,
|
|
3561
3790
|
purpose: "audit-coreason"
|
|
@@ -3639,7 +3868,7 @@ ${rubricText}`;
|
|
|
3639
3868
|
model: UPGRADE_MODEL,
|
|
3640
3869
|
label: UPGRADE_LABEL,
|
|
3641
3870
|
seat: "auditor",
|
|
3642
|
-
...coReasoned ? { co_reasoner: { model:
|
|
3871
|
+
...coReasoned ? { co_reasoner: { model: coProvider.model, label: coReasonLabel(coProvider.model) } } : {}
|
|
3643
3872
|
};
|
|
3644
3873
|
} else if (upgradeRequested) {
|
|
3645
3874
|
result["reasoning_upgrade"] = {
|
|
@@ -4370,8 +4599,12 @@ var SUPER_MODELS = {
|
|
|
4370
4599
|
// Fable 5.1 verified present on the account; 5 as the fallback for accounts
|
|
4371
4600
|
// that haven't been granted 5.1 yet.
|
|
4372
4601
|
anthropic: ["claude-fable-5-1", UPGRADE_MODEL],
|
|
4373
|
-
// Astra
|
|
4374
|
-
|
|
4602
|
+
// Astra is live (verified against the account's model list 2026-09-23).
|
|
4603
|
+
// The fallback is named explicitly rather than reusing CO_REASON_MODEL:
|
|
4604
|
+
// that constant means "OpenAI's top reasoning model" for the max-reasoning
|
|
4605
|
+
// co-reasoner, which is a different question from "what should super fall
|
|
4606
|
+
// back to". Sharing the symbol silently coupled two unrelated decisions.
|
|
4607
|
+
openai: ["gpt-6-astra", "gpt-6-sol"],
|
|
4375
4608
|
// Explicitly left as-is per product decision. Note grok-4-latest is not in
|
|
4376
4609
|
// xAI's published model list, but it resolves in practice — real panel calls
|
|
4377
4610
|
// on it succeeded as recently as 2026-08-30 — so it is an unlisted alias
|
|
@@ -4986,10 +5219,6 @@ If you need supporting evidence, you may emit ONE \`<tool_call>...</tool_call>\`
|
|
|
4986
5219
|
}
|
|
4987
5220
|
|
|
4988
5221
|
// src/tools/confer.ts
|
|
4989
|
-
var DEFERRED_OPTS = [
|
|
4990
|
-
// empty — every confer opt runs natively except worker_tools, which
|
|
4991
|
-
// is gated below (non-empty list → defer).
|
|
4992
|
-
];
|
|
4993
5222
|
async function runConfer(args, opts) {
|
|
4994
5223
|
const callStartedWall = performance3.now();
|
|
4995
5224
|
const callStartedCpu = process.cpuUsage();
|
|
@@ -5005,16 +5234,11 @@ async function runConfer(args, opts) {
|
|
|
5005
5234
|
rejectedWorkerTools.push(t);
|
|
5006
5235
|
}
|
|
5007
5236
|
}
|
|
5008
|
-
|
|
5009
|
-
const needsBridge = DEFERRED_OPTS.some((k) => Boolean(args[k])) || workerToolsNeedsBridge;
|
|
5010
|
-
if (needsBridge) {
|
|
5011
|
-
if (opts.bridge && opts.bridge.toolNames.has("confer")) {
|
|
5012
|
-
return await deferConfer(args, opts.bridge);
|
|
5013
|
-
}
|
|
5237
|
+
if (acceptedWorkerTools.length > 0 && !opts.innerCallers) {
|
|
5014
5238
|
return errorEnvelope2(
|
|
5015
5239
|
"CONFER_OPT_NOT_NATIVE",
|
|
5016
5240
|
"worker_tools requested but innerCallers are not wired",
|
|
5017
|
-
"Native confer covers untrusted_input + early_stop + extract_claims + inject_session_memory + auto_panel. worker_tools needs innerCallers wired by the host
|
|
5241
|
+
"Native confer covers untrusted_input + early_stop + extract_claims + inject_session_memory + auto_panel. worker_tools needs innerCallers wired by the host."
|
|
5018
5242
|
);
|
|
5019
5243
|
}
|
|
5020
5244
|
const question = typeof args["question"] === "string" ? args["question"] : String(args["question"] ?? "");
|
|
@@ -5365,21 +5589,6 @@ function unknownProviderError(unknownNames, available) {
|
|
|
5365
5589
|
available_now: Object.keys(available).sort()
|
|
5366
5590
|
};
|
|
5367
5591
|
}
|
|
5368
|
-
async function deferConfer(args, bridge) {
|
|
5369
|
-
const r = await bridge.callTool("confer", args);
|
|
5370
|
-
const text = r.content[0]?.text;
|
|
5371
|
-
if (typeof text === "string") {
|
|
5372
|
-
try {
|
|
5373
|
-
return JSON.parse(text);
|
|
5374
|
-
} catch {
|
|
5375
|
-
}
|
|
5376
|
-
}
|
|
5377
|
-
return errorEnvelope2(
|
|
5378
|
-
"CONFER_BRIDGE_BAD_ENVELOPE",
|
|
5379
|
-
"bridge returned an unparseable envelope for confer",
|
|
5380
|
-
"Check that the Python child is healthy."
|
|
5381
|
-
);
|
|
5382
|
-
}
|
|
5383
5592
|
function errorEnvelope2(code, message, hint) {
|
|
5384
5593
|
return {
|
|
5385
5594
|
tool: "confer",
|
|
@@ -5751,7 +5960,7 @@ function errorEnvelope3(code, message, hint) {
|
|
|
5751
5960
|
transient: false
|
|
5752
5961
|
};
|
|
5753
5962
|
}
|
|
5754
|
-
async function runVerify(args,
|
|
5963
|
+
async function runVerify(args, fetchConfig) {
|
|
5755
5964
|
const checks = args["checks"];
|
|
5756
5965
|
if (!Array.isArray(checks) || checks.length === 0) {
|
|
5757
5966
|
return {
|
|
@@ -5763,7 +5972,6 @@ async function runVerify(args, bridge, fetchConfig) {
|
|
|
5763
5972
|
)
|
|
5764
5973
|
};
|
|
5765
5974
|
}
|
|
5766
|
-
void bridge;
|
|
5767
5975
|
const allowShell = Boolean(args["allow_shell"] ?? false);
|
|
5768
5976
|
const wallStart = performance4.now();
|
|
5769
5977
|
const cpuStart = process.cpuUsage();
|
|
@@ -6065,7 +6273,6 @@ async function runBench(args, opts) {
|
|
|
6065
6273
|
const innerOpts = {
|
|
6066
6274
|
providers: opts.providers,
|
|
6067
6275
|
allowlist: opts.allowlist ?? null,
|
|
6068
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
6069
6276
|
...opts.moderator ? { moderator: opts.moderator } : {}
|
|
6070
6277
|
};
|
|
6071
6278
|
let inner;
|
|
@@ -6759,7 +6966,6 @@ var EST_TOKENS = {
|
|
|
6759
6966
|
med: [1500, 800],
|
|
6760
6967
|
high: [2500, 1500]
|
|
6761
6968
|
};
|
|
6762
|
-
var DEFERRED_OPTS2 = [];
|
|
6763
6969
|
var REACTIVE_SIGNAL_RE = /<signals>\s*(\{[\s\S]*?\})\s*<\/signals>/g;
|
|
6764
6970
|
function parseReactiveSignals(output) {
|
|
6765
6971
|
if (typeof output !== "string" || !output.includes("<signals>")) return [];
|
|
@@ -6799,17 +7005,6 @@ async function runOrchestrate(args, opts) {
|
|
|
6799
7005
|
);
|
|
6800
7006
|
if (breakerEnv) return breakerEnv;
|
|
6801
7007
|
}
|
|
6802
|
-
const needsBridge = DEFERRED_OPTS2.some((k) => Boolean(args[k]));
|
|
6803
|
-
if (needsBridge) {
|
|
6804
|
-
if (opts.bridge && opts.bridge.toolNames.has("orchestrate")) {
|
|
6805
|
-
return await deferOrchestrate(args, opts.bridge);
|
|
6806
|
-
}
|
|
6807
|
-
return errorEnvelope5(
|
|
6808
|
-
"ORCHESTRATE_OPT_NOT_NATIVE",
|
|
6809
|
-
"this orchestrate opt-in requires the Python bridge in v1",
|
|
6810
|
-
"v1 native covers the plain DAG flow + cheap_mode. reactive (mid-flight DAG updates) still defers. Set CROSSCHECK_BRIDGE_PYTHON=1 to enable."
|
|
6811
|
-
);
|
|
6812
|
-
}
|
|
6813
7008
|
const goal = typeof args["goal"] === "string" ? args["goal"] : null;
|
|
6814
7009
|
const dagIn = isObj5(args["dag"]) ? args["dag"] : null;
|
|
6815
7010
|
if (goal === null === (dagIn === null)) {
|
|
@@ -7352,8 +7547,9 @@ ${recombineSys}` : recombineSys },
|
|
|
7352
7547
|
provider: synthProvider.name
|
|
7353
7548
|
} }
|
|
7354
7549
|
);
|
|
7550
|
+
const coProvider = pickCoReasoner(opts.providers, upgradeRequested);
|
|
7355
7551
|
const coReason = await coReasonThenInject({
|
|
7356
|
-
provider:
|
|
7552
|
+
provider: coProvider,
|
|
7357
7553
|
messages: recMsgs,
|
|
7358
7554
|
maxTokens,
|
|
7359
7555
|
purpose: "orchestrate-coreason"
|
|
@@ -7412,7 +7608,7 @@ ${recombineSys}` : recombineSys },
|
|
|
7412
7608
|
model: UPGRADE_MODEL,
|
|
7413
7609
|
label: UPGRADE_LABEL,
|
|
7414
7610
|
seat: "recombine/synthesis",
|
|
7415
|
-
...coReasoned ? { co_reasoner: { model:
|
|
7611
|
+
...coReasoned ? { co_reasoner: { model: coProvider.model, label: coReasonLabel(coProvider.model) } } : {}
|
|
7416
7612
|
};
|
|
7417
7613
|
} else if (upgradeRequested) {
|
|
7418
7614
|
result["reasoning_upgrade"] = {
|
|
@@ -7750,21 +7946,6 @@ function resolveProviders3(names, available, allowlist) {
|
|
|
7750
7946
|
}
|
|
7751
7947
|
return out;
|
|
7752
7948
|
}
|
|
7753
|
-
async function deferOrchestrate(args, bridge) {
|
|
7754
|
-
const r = await bridge.callTool("orchestrate", args);
|
|
7755
|
-
const text = r.content[0]?.text;
|
|
7756
|
-
if (typeof text === "string") {
|
|
7757
|
-
try {
|
|
7758
|
-
return JSON.parse(text);
|
|
7759
|
-
} catch {
|
|
7760
|
-
}
|
|
7761
|
-
}
|
|
7762
|
-
return errorEnvelope5(
|
|
7763
|
-
"ORCHESTRATE_BRIDGE_BAD_ENVELOPE",
|
|
7764
|
-
"bridge returned an unparseable envelope for orchestrate",
|
|
7765
|
-
"Check that the Python child is healthy."
|
|
7766
|
-
);
|
|
7767
|
-
}
|
|
7768
7949
|
function errorEnvelope5(code, message, hint, kind = "client") {
|
|
7769
7950
|
return {
|
|
7770
7951
|
tool: "orchestrate",
|
|
@@ -8127,7 +8308,6 @@ ${documentsPayload}`;
|
|
|
8127
8308
|
}, {
|
|
8128
8309
|
providers: opts.providers,
|
|
8129
8310
|
allowlist: opts.allowlist ?? null,
|
|
8130
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
8131
8311
|
ctx
|
|
8132
8312
|
});
|
|
8133
8313
|
const scopeAnswer = Array.isArray(scope["answers"]) ? scope["answers"].filter((a) => typeof a["response"] === "string" && a["response"]).map((a) => `[${a["provider"]}]
|
|
@@ -8150,7 +8330,6 @@ ${scopeAnswer || "(none)"}
|
|
|
8150
8330
|
providers: opts.providers,
|
|
8151
8331
|
allowlist: opts.allowlist ?? null,
|
|
8152
8332
|
moderator,
|
|
8153
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
8154
8333
|
ctx
|
|
8155
8334
|
});
|
|
8156
8335
|
let attempts = 1;
|
|
@@ -8185,7 +8364,6 @@ ${scopeAnswer || "(none)"}
|
|
|
8185
8364
|
}, {
|
|
8186
8365
|
providers: opts.providers,
|
|
8187
8366
|
allowlist: opts.allowlist ?? null,
|
|
8188
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
8189
8367
|
ctx
|
|
8190
8368
|
});
|
|
8191
8369
|
}
|
|
@@ -8208,7 +8386,6 @@ ${scopeAnswer || "(none)"}
|
|
|
8208
8386
|
}, {
|
|
8209
8387
|
providers: opts.providers,
|
|
8210
8388
|
allowlist: opts.allowlist ?? null,
|
|
8211
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
8212
8389
|
ctx
|
|
8213
8390
|
});
|
|
8214
8391
|
let overallF = toNumberOrNull(auditEnvelope["overall_score"]);
|
|
@@ -8233,7 +8410,6 @@ ${documentsPayload}`
|
|
|
8233
8410
|
providers: opts.providers,
|
|
8234
8411
|
allowlist: opts.allowlist ?? null,
|
|
8235
8412
|
moderator,
|
|
8236
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
8237
8413
|
ctx
|
|
8238
8414
|
}
|
|
8239
8415
|
);
|
|
@@ -8253,7 +8429,6 @@ ${documentsPayload}`
|
|
|
8253
8429
|
}, {
|
|
8254
8430
|
providers: opts.providers,
|
|
8255
8431
|
allowlist: opts.allowlist ?? null,
|
|
8256
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
8257
8432
|
ctx
|
|
8258
8433
|
});
|
|
8259
8434
|
overallF = toNumberOrNull(auditEnvelope["overall_score"]);
|
|
@@ -8491,11 +8666,6 @@ function errorEnvelope6(toolName, code, message, hint) {
|
|
|
8491
8666
|
|
|
8492
8667
|
// src/tools/coordinate.ts
|
|
8493
8668
|
import { performance as performance8 } from "perf_hooks";
|
|
8494
|
-
var DEFERRED_OPTS3 = [
|
|
8495
|
-
// empty — every coordinate opt runs natively when its deps
|
|
8496
|
-
// (storage / innerCallers) are wired. Without them the
|
|
8497
|
-
// worker_tools gate still triggers a bridge defer.
|
|
8498
|
-
];
|
|
8499
8669
|
var COORDINATE_DEFAULT_TEMP = 0.4;
|
|
8500
8670
|
var ROLE_TURN_SCHEMA = {
|
|
8501
8671
|
type: "object",
|
|
@@ -8550,23 +8720,18 @@ async function runCoordinate(args, opts) {
|
|
|
8550
8720
|
rejectedWorkerTools.push(t);
|
|
8551
8721
|
}
|
|
8552
8722
|
}
|
|
8553
|
-
|
|
8554
|
-
const needsBridge = DEFERRED_OPTS3.some((k) => Boolean(args[k])) || workerToolsNeedsBridge;
|
|
8555
|
-
if (needsBridge) {
|
|
8723
|
+
if (acceptedWorkerTools.length > 0 && !opts.innerCallers) {
|
|
8556
8724
|
if (superRequested) {
|
|
8557
8725
|
return errorEnvelope7(
|
|
8558
8726
|
"COORDINATE_SUPER_NOT_NATIVE",
|
|
8559
|
-
"super mode requested
|
|
8560
|
-
"worker_tools
|
|
8727
|
+
"super mode requested with worker_tools, but innerCallers are not wired",
|
|
8728
|
+
"worker_tools needs innerCallers wired by the host. Drop worker_tools, or wire innerCallers, to use super."
|
|
8561
8729
|
);
|
|
8562
8730
|
}
|
|
8563
|
-
if (opts.bridge && opts.bridge.toolNames.has("coordinate")) {
|
|
8564
|
-
return await deferCoordinate(args, opts.bridge);
|
|
8565
|
-
}
|
|
8566
8731
|
return errorEnvelope7(
|
|
8567
8732
|
"COORDINATE_OPT_NOT_NATIVE",
|
|
8568
8733
|
"worker_tools requested but innerCallers are not wired",
|
|
8569
|
-
"Native coordinate covers the three-role flow + untrusted_input + inject_session_memory. worker_tools needs innerCallers wired by the host
|
|
8734
|
+
"Native coordinate covers the three-role flow + untrusted_input + inject_session_memory. worker_tools needs innerCallers wired by the host."
|
|
8570
8735
|
);
|
|
8571
8736
|
}
|
|
8572
8737
|
const untrusted = Boolean(args["untrusted_input"]);
|
|
@@ -8758,8 +8923,9 @@ CRITIQUES:
|
|
|
8758
8923
|
${critiqueBlock}`
|
|
8759
8924
|
}
|
|
8760
8925
|
];
|
|
8926
|
+
const coProvider = pickCoReasoner(opts.providers, upgradeRequested);
|
|
8761
8927
|
const coReason = await coReasonThenInject({
|
|
8762
|
-
provider:
|
|
8928
|
+
provider: coProvider,
|
|
8763
8929
|
messages: synthMessages,
|
|
8764
8930
|
maxTokens,
|
|
8765
8931
|
purpose: "coordinate-coreason"
|
|
@@ -8823,7 +8989,7 @@ ${critiqueBlock}`
|
|
|
8823
8989
|
model: superRequested ? superPrimary("anthropic") ?? UPGRADE_MODEL : UPGRADE_MODEL,
|
|
8824
8990
|
label: UPGRADE_LABEL,
|
|
8825
8991
|
seat: "synthesizer",
|
|
8826
|
-
...coReasonAns ? { co_reasoner: { model:
|
|
8992
|
+
...coReasonAns ? { co_reasoner: { model: coProvider.model, label: coReasonLabel(coProvider.model) } } : {}
|
|
8827
8993
|
};
|
|
8828
8994
|
} else if (upgradeRequested) {
|
|
8829
8995
|
result["reasoning_upgrade"] = {
|
|
@@ -8965,21 +9131,6 @@ function unknownProviderError3(unknownNames, available) {
|
|
|
8965
9131
|
available_now: Object.keys(available).sort()
|
|
8966
9132
|
};
|
|
8967
9133
|
}
|
|
8968
|
-
async function deferCoordinate(args, bridge) {
|
|
8969
|
-
const r = await bridge.callTool("coordinate", args);
|
|
8970
|
-
const text = r.content[0]?.text;
|
|
8971
|
-
if (typeof text === "string") {
|
|
8972
|
-
try {
|
|
8973
|
-
return JSON.parse(text);
|
|
8974
|
-
} catch {
|
|
8975
|
-
}
|
|
8976
|
-
}
|
|
8977
|
-
return errorEnvelope7(
|
|
8978
|
-
"COORDINATE_BRIDGE_BAD_ENVELOPE",
|
|
8979
|
-
"bridge returned an unparseable envelope for coordinate",
|
|
8980
|
-
"Check that the Python child is healthy."
|
|
8981
|
-
);
|
|
8982
|
-
}
|
|
8983
9134
|
function errorEnvelope7(code, message, hint) {
|
|
8984
9135
|
return {
|
|
8985
9136
|
tool: "coordinate",
|
|
@@ -9307,10 +9458,6 @@ function buildModeratorTranscript(transcript) {
|
|
|
9307
9458
|
|
|
9308
9459
|
// src/tools/debate.ts
|
|
9309
9460
|
import { performance as performance10 } from "perf_hooks";
|
|
9310
|
-
var DEFERRED_OPTS4 = [
|
|
9311
|
-
// empty — every debate opt runs natively when its deps
|
|
9312
|
-
// (storage / innerCallers) are wired.
|
|
9313
|
-
];
|
|
9314
9461
|
async function runDebate(args, opts) {
|
|
9315
9462
|
const callStartedWall = performance10.now();
|
|
9316
9463
|
const callStartedCpu = process.cpuUsage();
|
|
@@ -9328,23 +9475,18 @@ async function runDebate(args, opts) {
|
|
|
9328
9475
|
rejectedWorkerTools.push(t);
|
|
9329
9476
|
}
|
|
9330
9477
|
}
|
|
9331
|
-
|
|
9332
|
-
const needsBridge = DEFERRED_OPTS4.some((k) => Boolean(args[k])) || workerToolsNeedsBridge;
|
|
9333
|
-
if (needsBridge) {
|
|
9478
|
+
if (acceptedWorkerTools.length > 0 && !opts.innerCallers) {
|
|
9334
9479
|
if (superRequested) {
|
|
9335
9480
|
return errorEnvelope9(
|
|
9336
9481
|
"DEBATE_SUPER_NOT_NATIVE",
|
|
9337
|
-
"super mode requested
|
|
9338
|
-
"worker_tools
|
|
9482
|
+
"super mode requested with worker_tools, but innerCallers are not wired",
|
|
9483
|
+
"worker_tools needs innerCallers wired by the host. Drop worker_tools, or wire innerCallers, to use super."
|
|
9339
9484
|
);
|
|
9340
9485
|
}
|
|
9341
|
-
if (opts.bridge && opts.bridge.toolNames.has("debate")) {
|
|
9342
|
-
return await deferDebate(args, opts.bridge);
|
|
9343
|
-
}
|
|
9344
9486
|
return errorEnvelope9(
|
|
9345
9487
|
"DEBATE_OPT_NOT_NATIVE",
|
|
9346
9488
|
"worker_tools requested but innerCallers are not wired",
|
|
9347
|
-
"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
|
|
9489
|
+
"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."
|
|
9348
9490
|
);
|
|
9349
9491
|
}
|
|
9350
9492
|
const topic = typeof args["topic"] === "string" ? args["topic"] : String(args["topic"] ?? "");
|
|
@@ -9545,6 +9687,7 @@ ${prior.body}` });
|
|
|
9545
9687
|
let synthesisErrors = [];
|
|
9546
9688
|
let personaMeta = null;
|
|
9547
9689
|
let coReasoned = false;
|
|
9690
|
+
let coReasonerModel = null;
|
|
9548
9691
|
if (moderator) {
|
|
9549
9692
|
const synthProvider = superRequested && opts.providers["anthropic"] ? retargetForSuper(opts.providers["anthropic"]) : upgraded ? retargetProvider(opts.providers["anthropic"], UPGRADE_MODEL) : moderator;
|
|
9550
9693
|
const condensed = buildModeratorTranscript(transcript);
|
|
@@ -9572,13 +9715,16 @@ TRANSCRIPT:
|
|
|
9572
9715
|
${condensed}`
|
|
9573
9716
|
}
|
|
9574
9717
|
];
|
|
9718
|
+
const openAiSeat = selected.find((p) => p.name === "openai")?.model;
|
|
9719
|
+
const coProvider = pickCoReasoner(opts.providers, upgradeRequested, openAiSeat);
|
|
9575
9720
|
const coReason = await coReasonThenInject({
|
|
9576
|
-
provider:
|
|
9721
|
+
provider: coProvider,
|
|
9577
9722
|
messages: synthMessages,
|
|
9578
9723
|
maxTokens,
|
|
9579
9724
|
purpose: "debate-coreason"
|
|
9580
9725
|
});
|
|
9581
9726
|
synthMessages = coReason.messages;
|
|
9727
|
+
coReasonerModel = coProvider?.model ?? null;
|
|
9582
9728
|
if (coReason.answer) extraAnswers.push(coReason.answer);
|
|
9583
9729
|
coReasoned = coReason.answer !== null;
|
|
9584
9730
|
if (structuredOpt) {
|
|
@@ -9637,7 +9783,7 @@ ${condensed}`
|
|
|
9637
9783
|
model: superRequested ? superPrimary("anthropic") ?? UPGRADE_MODEL : UPGRADE_MODEL,
|
|
9638
9784
|
label: UPGRADE_LABEL,
|
|
9639
9785
|
seat: "moderator synthesis",
|
|
9640
|
-
...coReasoned ? { co_reasoner: { model:
|
|
9786
|
+
...coReasoned && coReasonerModel ? { co_reasoner: { model: coReasonerModel, label: coReasonLabel(coReasonerModel) } } : {}
|
|
9641
9787
|
};
|
|
9642
9788
|
} else if (upgradeRequested) {
|
|
9643
9789
|
result["reasoning_upgrade"] = {
|
|
@@ -9777,21 +9923,6 @@ function unknownProviderError5(unknownNames, available) {
|
|
|
9777
9923
|
available_now: Object.keys(available).sort()
|
|
9778
9924
|
};
|
|
9779
9925
|
}
|
|
9780
|
-
async function deferDebate(args, bridge) {
|
|
9781
|
-
const r = await bridge.callTool("debate", args);
|
|
9782
|
-
const text = r.content[0]?.text;
|
|
9783
|
-
if (typeof text === "string") {
|
|
9784
|
-
try {
|
|
9785
|
-
return JSON.parse(text);
|
|
9786
|
-
} catch {
|
|
9787
|
-
}
|
|
9788
|
-
}
|
|
9789
|
-
return errorEnvelope9(
|
|
9790
|
-
"DEBATE_BRIDGE_BAD_ENVELOPE",
|
|
9791
|
-
"bridge returned an unparseable envelope for debate",
|
|
9792
|
-
"Check that the Python child is healthy."
|
|
9793
|
-
);
|
|
9794
|
-
}
|
|
9795
9926
|
function errorEnvelope9(code, message, hint) {
|
|
9796
9927
|
return {
|
|
9797
9928
|
tool: "debate",
|
|
@@ -9811,9 +9942,6 @@ var DEFAULT_DELEGATION_LIMITS = {
|
|
|
9811
9942
|
};
|
|
9812
9943
|
async function runDelegate(args, opts) {
|
|
9813
9944
|
if (!opts.storage) {
|
|
9814
|
-
if (opts.bridge && opts.bridge.toolNames.has("delegate")) {
|
|
9815
|
-
return await deferDelegate(args, opts.bridge);
|
|
9816
|
-
}
|
|
9817
9945
|
return errorEnvelope10(
|
|
9818
9946
|
"DELEGATE_STORAGE_UNAVAILABLE",
|
|
9819
9947
|
"delegate needs the local database (for quota tracking), which isn't available",
|
|
@@ -9885,7 +10013,6 @@ async function runDelegate(args, opts) {
|
|
|
9885
10013
|
const innerOpts = {
|
|
9886
10014
|
providers: opts.providers,
|
|
9887
10015
|
allowlist: opts.allowlist ?? null,
|
|
9888
|
-
...opts.bridge ? { bridge: opts.bridge } : {},
|
|
9889
10016
|
...opts.moderator ? { moderator: opts.moderator } : {}
|
|
9890
10017
|
};
|
|
9891
10018
|
let result;
|
|
@@ -9924,21 +10051,6 @@ async function record(storage, sessionId, requester, toolCall, via, accepted, no
|
|
|
9924
10051
|
created_at: nowEpochSeconds
|
|
9925
10052
|
});
|
|
9926
10053
|
}
|
|
9927
|
-
async function deferDelegate(args, bridge) {
|
|
9928
|
-
const r = await bridge.callTool("delegate", args);
|
|
9929
|
-
const text = r.content[0]?.text;
|
|
9930
|
-
if (typeof text === "string") {
|
|
9931
|
-
try {
|
|
9932
|
-
return JSON.parse(text);
|
|
9933
|
-
} catch {
|
|
9934
|
-
}
|
|
9935
|
-
}
|
|
9936
|
-
return errorEnvelope10(
|
|
9937
|
-
"DELEGATE_BRIDGE_BAD_ENVELOPE",
|
|
9938
|
-
"bridge returned an unparseable envelope for delegate",
|
|
9939
|
-
"Check that the Python child is healthy."
|
|
9940
|
-
);
|
|
9941
|
-
}
|
|
9942
10054
|
function errorEnvelope10(code, message, hint) {
|
|
9943
10055
|
return {
|
|
9944
10056
|
tool: "delegate",
|
|
@@ -9981,9 +10093,6 @@ async function runExplain(args, opts) {
|
|
|
9981
10093
|
);
|
|
9982
10094
|
}
|
|
9983
10095
|
if (!opts.storage) {
|
|
9984
|
-
if (opts.bridge && opts.bridge.toolNames.has("explain")) {
|
|
9985
|
-
return await deferExplain(args, opts.bridge);
|
|
9986
|
-
}
|
|
9987
10096
|
return errorEnvelope11(
|
|
9988
10097
|
"EXPLAIN_STORAGE_UNAVAILABLE",
|
|
9989
10098
|
"explain needs the local transcript/stats database, which isn't available",
|
|
@@ -10265,21 +10374,6 @@ function pyRepr5(v) {
|
|
|
10265
10374
|
}
|
|
10266
10375
|
return String(v);
|
|
10267
10376
|
}
|
|
10268
|
-
async function deferExplain(args, bridge) {
|
|
10269
|
-
const r = await bridge.callTool("explain", args);
|
|
10270
|
-
const text = r.content[0]?.text;
|
|
10271
|
-
if (typeof text === "string") {
|
|
10272
|
-
try {
|
|
10273
|
-
return JSON.parse(text);
|
|
10274
|
-
} catch {
|
|
10275
|
-
}
|
|
10276
|
-
}
|
|
10277
|
-
return errorEnvelope11(
|
|
10278
|
-
"EXPLAIN_BRIDGE_BAD_ENVELOPE",
|
|
10279
|
-
"bridge returned an unparseable envelope for explain",
|
|
10280
|
-
"Check that the Python child is healthy."
|
|
10281
|
-
);
|
|
10282
|
-
}
|
|
10283
10377
|
function errorEnvelope11(code, message, hint, kind = "client", extra = {}) {
|
|
10284
10378
|
return {
|
|
10285
10379
|
tool: "explain",
|
|
@@ -10832,9 +10926,6 @@ async function runRecall(args, opts) {
|
|
|
10832
10926
|
if (k < 1) k = 1;
|
|
10833
10927
|
if (k > 50) k = 50;
|
|
10834
10928
|
if (!opts.storage) {
|
|
10835
|
-
if (opts.bridge && opts.bridge.toolNames.has("recall")) {
|
|
10836
|
-
return await deferRecall(args, opts.bridge);
|
|
10837
|
-
}
|
|
10838
10929
|
return errorEnvelope12(
|
|
10839
10930
|
"RECALL_STORAGE_UNAVAILABLE",
|
|
10840
10931
|
"recall needs the local database, which isn't available",
|
|
@@ -10887,21 +10978,6 @@ async function runRecall(args, opts) {
|
|
|
10887
10978
|
applied_filters: applied
|
|
10888
10979
|
};
|
|
10889
10980
|
}
|
|
10890
|
-
async function deferRecall(args, bridge) {
|
|
10891
|
-
const r = await bridge.callTool("recall", args);
|
|
10892
|
-
const text = r.content[0]?.text;
|
|
10893
|
-
if (typeof text === "string") {
|
|
10894
|
-
try {
|
|
10895
|
-
return JSON.parse(text);
|
|
10896
|
-
} catch {
|
|
10897
|
-
}
|
|
10898
|
-
}
|
|
10899
|
-
return errorEnvelope12(
|
|
10900
|
-
"RECALL_BRIDGE_BAD_ENVELOPE",
|
|
10901
|
-
"bridge returned an unparseable envelope for recall",
|
|
10902
|
-
"Check that the Python child is healthy."
|
|
10903
|
-
);
|
|
10904
|
-
}
|
|
10905
10981
|
function errorEnvelope12(code, message, hint) {
|
|
10906
10982
|
return {
|
|
10907
10983
|
tool: "recall",
|
|
@@ -10924,9 +11000,6 @@ async function runRecommendPanel(args, opts) {
|
|
|
10924
11000
|
);
|
|
10925
11001
|
}
|
|
10926
11002
|
if (!opts.storage) {
|
|
10927
|
-
if (opts.bridge && opts.bridge.toolNames.has("recommend_panel")) {
|
|
10928
|
-
return await deferRecommendPanel(args, opts.bridge);
|
|
10929
|
-
}
|
|
10930
11003
|
return errorEnvelope13(
|
|
10931
11004
|
"RECOMMEND_PANEL_STORAGE_UNAVAILABLE",
|
|
10932
11005
|
"recommend_panel needs the local stats database, which isn't available",
|
|
@@ -10989,21 +11062,6 @@ async function runRecommendPanel(args, opts) {
|
|
|
10989
11062
|
meta: result.meta
|
|
10990
11063
|
};
|
|
10991
11064
|
}
|
|
10992
|
-
async function deferRecommendPanel(args, bridge) {
|
|
10993
|
-
const r = await bridge.callTool("recommend_panel", args);
|
|
10994
|
-
const text = r.content[0]?.text;
|
|
10995
|
-
if (typeof text === "string") {
|
|
10996
|
-
try {
|
|
10997
|
-
return JSON.parse(text);
|
|
10998
|
-
} catch {
|
|
10999
|
-
}
|
|
11000
|
-
}
|
|
11001
|
-
return errorEnvelope13(
|
|
11002
|
-
"RECOMMEND_PANEL_BRIDGE_BAD_ENVELOPE",
|
|
11003
|
-
"bridge returned an unparseable envelope for recommend_panel",
|
|
11004
|
-
"Check that the Python child is healthy."
|
|
11005
|
-
);
|
|
11006
|
-
}
|
|
11007
11065
|
function errorEnvelope13(code, message, hint) {
|
|
11008
11066
|
return {
|
|
11009
11067
|
tool: "recommend_panel",
|
|
@@ -11033,9 +11091,6 @@ function toStringArray3(v) {
|
|
|
11033
11091
|
import { readFileSync as readFileSync10, existsSync as existsSync8 } from "fs";
|
|
11034
11092
|
async function runScoreboard(args, opts) {
|
|
11035
11093
|
if (!opts.storage) {
|
|
11036
|
-
if (opts.bridge && opts.bridge.toolNames.has("scoreboard")) {
|
|
11037
|
-
return await deferScoreboard(args, opts.bridge);
|
|
11038
|
-
}
|
|
11039
11094
|
return errorEnvelope14(
|
|
11040
11095
|
"SCOREBOARD_STORAGE_UNAVAILABLE",
|
|
11041
11096
|
"scoreboard needs the local stats database, which isn't available",
|
|
@@ -11158,21 +11213,6 @@ function clampInt3(raw, min, max, fallback) {
|
|
|
11158
11213
|
if (!Number.isFinite(n)) return fallback;
|
|
11159
11214
|
return Math.min(max, Math.max(min, Math.trunc(n)));
|
|
11160
11215
|
}
|
|
11161
|
-
async function deferScoreboard(args, bridge) {
|
|
11162
|
-
const r = await bridge.callTool("scoreboard", args);
|
|
11163
|
-
const text = r.content[0]?.text;
|
|
11164
|
-
if (typeof text === "string") {
|
|
11165
|
-
try {
|
|
11166
|
-
return JSON.parse(text);
|
|
11167
|
-
} catch {
|
|
11168
|
-
}
|
|
11169
|
-
}
|
|
11170
|
-
return errorEnvelope14(
|
|
11171
|
-
"SCOREBOARD_BRIDGE_BAD_ENVELOPE",
|
|
11172
|
-
"bridge returned an unparseable envelope for scoreboard",
|
|
11173
|
-
"Check that the Python child is healthy."
|
|
11174
|
-
);
|
|
11175
|
-
}
|
|
11176
11216
|
function errorEnvelope14(code, message, hint) {
|
|
11177
11217
|
return {
|
|
11178
11218
|
tool: "scoreboard",
|
|
@@ -11209,9 +11249,6 @@ async function runSessionMemory(args, opts) {
|
|
|
11209
11249
|
);
|
|
11210
11250
|
}
|
|
11211
11251
|
if (!opts.storage) {
|
|
11212
|
-
if (opts.bridge && opts.bridge.toolNames.has("session_memory")) {
|
|
11213
|
-
return await deferSessionMemory(args, opts.bridge);
|
|
11214
|
-
}
|
|
11215
11252
|
return errorEnvelope15(
|
|
11216
11253
|
"SESSION_MEMORY_STORAGE_UNAVAILABLE",
|
|
11217
11254
|
"session_memory needs the local database, which isn't available",
|
|
@@ -11316,21 +11353,6 @@ function clampInt4(raw, min, max, fallback) {
|
|
|
11316
11353
|
if (!Number.isFinite(n)) return fallback;
|
|
11317
11354
|
return Math.min(max, Math.max(min, Math.trunc(n)));
|
|
11318
11355
|
}
|
|
11319
|
-
async function deferSessionMemory(args, bridge) {
|
|
11320
|
-
const r = await bridge.callTool("session_memory", args);
|
|
11321
|
-
const text = r.content[0]?.text;
|
|
11322
|
-
if (typeof text === "string") {
|
|
11323
|
-
try {
|
|
11324
|
-
return JSON.parse(text);
|
|
11325
|
-
} catch {
|
|
11326
|
-
}
|
|
11327
|
-
}
|
|
11328
|
-
return errorEnvelope15(
|
|
11329
|
-
"SESSION_MEMORY_BRIDGE_BAD_ENVELOPE",
|
|
11330
|
-
"bridge returned an unparseable envelope for session_memory",
|
|
11331
|
-
"Check that the Python child is healthy."
|
|
11332
|
-
);
|
|
11333
|
-
}
|
|
11334
11356
|
function errorEnvelope15(code, message, hint) {
|
|
11335
11357
|
return {
|
|
11336
11358
|
tool: "session_memory",
|
|
@@ -11661,7 +11683,7 @@ Re-emit the FULL solution. No commentary.`
|
|
|
11661
11683
|
model: UPGRADE_MODEL,
|
|
11662
11684
|
label: UPGRADE_LABEL,
|
|
11663
11685
|
seat: "solver",
|
|
11664
|
-
...coReasoned ? { co_reasoner: { model:
|
|
11686
|
+
...coReasoned ? { co_reasoner: { model: coProvider.model, label: coReasonLabel(coProvider.model) } } : {}
|
|
11665
11687
|
};
|
|
11666
11688
|
} else if (upgradeRequested) {
|
|
11667
11689
|
result["reasoning_upgrade"] = {
|
|
@@ -11950,7 +11972,7 @@ var CHECK_INTERVAL_SECONDS = 3 * 24 * 60 * 60;
|
|
|
11950
11972
|
var DEFAULT_PACKAGE = "crosscheck-cli";
|
|
11951
11973
|
var FETCH_TIMEOUT_MS = 3e3;
|
|
11952
11974
|
function engineVersion() {
|
|
11953
|
-
return true ? "0.2.
|
|
11975
|
+
return true ? "0.2.28" : "0.0.0-dev";
|
|
11954
11976
|
}
|
|
11955
11977
|
function defaultUpdateCachePath() {
|
|
11956
11978
|
const base = process.env["CROSSCHECK_DATA_DIR"] || path9.join(os.homedir() || os.tmpdir(), ".crosscheck");
|
|
@@ -12722,12 +12744,11 @@ function helpTool() {
|
|
|
12722
12744
|
}
|
|
12723
12745
|
});
|
|
12724
12746
|
}
|
|
12725
|
-
function registerCoreTools(
|
|
12726
|
-
const o = opts && typeof opts === "object" && "toolNames" in opts ? { bridge: opts } : opts;
|
|
12747
|
+
function registerCoreTools(o = {}) {
|
|
12727
12748
|
const tools = /* @__PURE__ */ new Map();
|
|
12728
12749
|
const list = [
|
|
12729
12750
|
pingTool(),
|
|
12730
|
-
verifyTool(o.
|
|
12751
|
+
verifyTool(o.fetchConfig),
|
|
12731
12752
|
pickTool(
|
|
12732
12753
|
o.providers ?? {},
|
|
12733
12754
|
o.providerAllowlist ?? null,
|
|
@@ -12739,7 +12760,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12739
12760
|
auditTool(
|
|
12740
12761
|
o.providers ?? {},
|
|
12741
12762
|
o.providerAllowlist ?? null,
|
|
12742
|
-
o.bridge,
|
|
12743
12763
|
o.transcriptsDir,
|
|
12744
12764
|
o.pricing,
|
|
12745
12765
|
o.storage,
|
|
@@ -12749,7 +12769,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12749
12769
|
conferTool(
|
|
12750
12770
|
o.providers ?? {},
|
|
12751
12771
|
o.providerAllowlist ?? null,
|
|
12752
|
-
o.bridge,
|
|
12753
12772
|
o.moderatorDefault ?? "anthropic",
|
|
12754
12773
|
o.pricing,
|
|
12755
12774
|
o.storage,
|
|
@@ -12762,7 +12781,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12762
12781
|
debateTool(
|
|
12763
12782
|
o.providers ?? {},
|
|
12764
12783
|
o.providerAllowlist ?? null,
|
|
12765
|
-
o.bridge,
|
|
12766
12784
|
buildInnerCallers(o),
|
|
12767
12785
|
o.storage,
|
|
12768
12786
|
o.pricing,
|
|
@@ -12774,7 +12792,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12774
12792
|
coordinateTool(
|
|
12775
12793
|
o.providers ?? {},
|
|
12776
12794
|
o.providerAllowlist ?? null,
|
|
12777
|
-
o.bridge,
|
|
12778
12795
|
buildInnerCallers(o),
|
|
12779
12796
|
o.storage,
|
|
12780
12797
|
o.circuitBreakers,
|
|
@@ -12785,7 +12802,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12785
12802
|
triangulateTool(
|
|
12786
12803
|
o.providers ?? {},
|
|
12787
12804
|
o.providerAllowlist ?? null,
|
|
12788
|
-
o.bridge,
|
|
12789
12805
|
o.storage,
|
|
12790
12806
|
o.circuitBreakers,
|
|
12791
12807
|
o.transcriptsDir,
|
|
@@ -12794,7 +12810,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12794
12810
|
planTool(
|
|
12795
12811
|
o.providers ?? {},
|
|
12796
12812
|
o.providerAllowlist ?? null,
|
|
12797
|
-
o.bridge,
|
|
12798
12813
|
o.storage,
|
|
12799
12814
|
o.circuitBreakers,
|
|
12800
12815
|
o.transcriptsDir,
|
|
@@ -12803,7 +12818,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12803
12818
|
critiqueTool(
|
|
12804
12819
|
o.providers ?? {},
|
|
12805
12820
|
o.providerAllowlist ?? null,
|
|
12806
|
-
o.bridge,
|
|
12807
12821
|
o.storage,
|
|
12808
12822
|
o.circuitBreakers,
|
|
12809
12823
|
o.transcriptsDir,
|
|
@@ -12812,7 +12826,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12812
12826
|
reviewTool(
|
|
12813
12827
|
o.providers ?? {},
|
|
12814
12828
|
o.providerAllowlist ?? null,
|
|
12815
|
-
o.bridge,
|
|
12816
12829
|
o.storage,
|
|
12817
12830
|
o.circuitBreakers,
|
|
12818
12831
|
o.transcriptsDir,
|
|
@@ -12820,25 +12833,23 @@ function registerCoreTools(opts = {}) {
|
|
|
12820
12833
|
),
|
|
12821
12834
|
listProvidersTool(o.providers ?? {}, o.activeProviders ?? null, o.moderatorDefault ?? "anthropic"),
|
|
12822
12835
|
modelsTool(o.providers ?? {}, o.activeProviders ?? null),
|
|
12823
|
-
recallTool(o.storage
|
|
12824
|
-
sessionMemoryTool(o.storage
|
|
12825
|
-
scoreboardTool(o.storage, o.
|
|
12826
|
-
explainTool(o.storage, o.
|
|
12836
|
+
recallTool(o.storage),
|
|
12837
|
+
sessionMemoryTool(o.storage),
|
|
12838
|
+
scoreboardTool(o.storage, o.eventsPath),
|
|
12839
|
+
explainTool(o.storage, o.transcriptsDir),
|
|
12827
12840
|
delegateTool(
|
|
12828
12841
|
o.providers ?? {},
|
|
12829
12842
|
o.providerAllowlist ?? null,
|
|
12830
12843
|
o.storage,
|
|
12831
|
-
o.bridge,
|
|
12832
12844
|
o.moderatorDefault ?? "anthropic"
|
|
12833
12845
|
),
|
|
12834
12846
|
fetchTool(o.storage, o.fetchConfig, o.repoRoot),
|
|
12835
|
-
recommendPanelTool(o.providers ?? {}, o.storage
|
|
12847
|
+
recommendPanelTool(o.providers ?? {}, o.storage),
|
|
12836
12848
|
updateCrosscheckTool(o.repoRoot ?? null),
|
|
12837
12849
|
benchTool(
|
|
12838
12850
|
o.providers ?? {},
|
|
12839
12851
|
o.providerAllowlist ?? null,
|
|
12840
12852
|
o.storage,
|
|
12841
|
-
o.bridge,
|
|
12842
12853
|
o.moderatorDefault ?? "anthropic",
|
|
12843
12854
|
o.benchGoldensDir,
|
|
12844
12855
|
o.circuitBreakers,
|
|
@@ -12849,7 +12860,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12849
12860
|
solveTool(
|
|
12850
12861
|
o.providers ?? {},
|
|
12851
12862
|
o.providerAllowlist ?? null,
|
|
12852
|
-
o.bridge,
|
|
12853
12863
|
o.storage,
|
|
12854
12864
|
o.circuitBreakers,
|
|
12855
12865
|
o.transcriptsDir,
|
|
@@ -12858,7 +12868,6 @@ function registerCoreTools(opts = {}) {
|
|
|
12858
12868
|
orchestrateTool(
|
|
12859
12869
|
o.providers ?? {},
|
|
12860
12870
|
o.providerAllowlist ?? null,
|
|
12861
|
-
o.bridge,
|
|
12862
12871
|
o.moderatorDefault ?? "anthropic",
|
|
12863
12872
|
o.storage,
|
|
12864
12873
|
o.pricing,
|
|
@@ -12905,7 +12914,6 @@ function createTool(o, toolName, cheapDefault) {
|
|
|
12905
12914
|
providers: o.providers ?? {},
|
|
12906
12915
|
allowlist: o.providerAllowlist ?? null,
|
|
12907
12916
|
...o.storage ? { storage: o.storage } : {},
|
|
12908
|
-
...o.bridge ? { bridge: o.bridge } : {},
|
|
12909
12917
|
...o.moderatorDefault ? { moderator: o.moderatorDefault } : {},
|
|
12910
12918
|
...o.fetchConfig ? { fetchConfig: o.fetchConfig } : {},
|
|
12911
12919
|
...o.repoRoot ? { repoRoot: o.repoRoot } : {},
|
|
@@ -12914,7 +12922,7 @@ function createTool(o, toolName, cheapDefault) {
|
|
|
12914
12922
|
})
|
|
12915
12923
|
};
|
|
12916
12924
|
}
|
|
12917
|
-
function orchestrateTool(providers, allowlist,
|
|
12925
|
+
function orchestrateTool(providers, allowlist, moderator, storage, pricing, breakers, transcriptsDir, repoRoot, nodeCache) {
|
|
12918
12926
|
return {
|
|
12919
12927
|
name: "orchestrate",
|
|
12920
12928
|
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.",
|
|
@@ -12939,7 +12947,6 @@ function orchestrateTool(providers, allowlist, bridge, moderator, storage, prici
|
|
|
12939
12947
|
providers,
|
|
12940
12948
|
allowlist,
|
|
12941
12949
|
moderator,
|
|
12942
|
-
...bridge ? { bridge } : {},
|
|
12943
12950
|
...storage ? { storage } : {},
|
|
12944
12951
|
...pricing ? { pricing } : {},
|
|
12945
12952
|
...breakers ? { breakers } : {},
|
|
@@ -12949,7 +12956,7 @@ function orchestrateTool(providers, allowlist, bridge, moderator, storage, prici
|
|
|
12949
12956
|
})
|
|
12950
12957
|
};
|
|
12951
12958
|
}
|
|
12952
|
-
function solveTool(providers, allowlist,
|
|
12959
|
+
function solveTool(providers, allowlist, storage, breakers, transcriptsDir, repoRoot) {
|
|
12953
12960
|
return {
|
|
12954
12961
|
name: "solve",
|
|
12955
12962
|
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.",
|
|
@@ -12971,7 +12978,6 @@ function solveTool(providers, allowlist, bridge, storage, breakers, transcriptsD
|
|
|
12971
12978
|
handler: (args) => runSolve(args, {
|
|
12972
12979
|
providers,
|
|
12973
12980
|
allowlist,
|
|
12974
|
-
...bridge ? { bridge } : {},
|
|
12975
12981
|
...storage ? { storage } : {},
|
|
12976
12982
|
...breakers ? { breakers } : {},
|
|
12977
12983
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -13010,7 +13016,7 @@ function configPinTool(repoRoot, config, rejectDriftEnv) {
|
|
|
13010
13016
|
}
|
|
13011
13017
|
};
|
|
13012
13018
|
}
|
|
13013
|
-
function benchTool(providers, allowlist, storage,
|
|
13019
|
+
function benchTool(providers, allowlist, storage, moderator, defaultGoldensDir, breakers, transcriptsDir, repoRoot) {
|
|
13014
13020
|
return {
|
|
13015
13021
|
name: "bench",
|
|
13016
13022
|
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).",
|
|
@@ -13029,7 +13035,6 @@ function benchTool(providers, allowlist, storage, bridge, moderator, defaultGold
|
|
|
13029
13035
|
allowlist,
|
|
13030
13036
|
moderator,
|
|
13031
13037
|
...storage ? { storage } : {},
|
|
13032
|
-
...bridge ? { bridge } : {},
|
|
13033
13038
|
...defaultGoldensDir ? { defaultGoldensDir } : {},
|
|
13034
13039
|
...breakers ? { breakers } : {},
|
|
13035
13040
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -13056,7 +13061,7 @@ function updateCrosscheckTool(repoRoot) {
|
|
|
13056
13061
|
}
|
|
13057
13062
|
};
|
|
13058
13063
|
}
|
|
13059
|
-
function recommendPanelTool(providers, storage
|
|
13064
|
+
function recommendPanelTool(providers, storage) {
|
|
13060
13065
|
return {
|
|
13061
13066
|
name: "recommend_panel",
|
|
13062
13067
|
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.",
|
|
@@ -13074,8 +13079,7 @@ function recommendPanelTool(providers, storage, bridge) {
|
|
|
13074
13079
|
},
|
|
13075
13080
|
handler: (args) => runRecommendPanel(args, {
|
|
13076
13081
|
providers,
|
|
13077
|
-
...storage ? { storage } : {}
|
|
13078
|
-
...bridge ? { bridge } : {}
|
|
13082
|
+
...storage ? { storage } : {}
|
|
13079
13083
|
})
|
|
13080
13084
|
};
|
|
13081
13085
|
}
|
|
@@ -13100,7 +13104,7 @@ function fetchTool(storage, fetchConfig, repoRoot) {
|
|
|
13100
13104
|
})
|
|
13101
13105
|
};
|
|
13102
13106
|
}
|
|
13103
|
-
function delegateTool(providers, allowlist, storage,
|
|
13107
|
+
function delegateTool(providers, allowlist, storage, moderator) {
|
|
13104
13108
|
return {
|
|
13105
13109
|
name: "delegate",
|
|
13106
13110
|
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.",
|
|
@@ -13120,12 +13124,11 @@ function delegateTool(providers, allowlist, storage, bridge, moderator) {
|
|
|
13120
13124
|
providers,
|
|
13121
13125
|
allowlist,
|
|
13122
13126
|
moderator,
|
|
13123
|
-
...storage ? { storage } : {}
|
|
13124
|
-
...bridge ? { bridge } : {}
|
|
13127
|
+
...storage ? { storage } : {}
|
|
13125
13128
|
})
|
|
13126
13129
|
};
|
|
13127
13130
|
}
|
|
13128
|
-
function explainTool(storage,
|
|
13131
|
+
function explainTool(storage, transcriptsDir) {
|
|
13129
13132
|
return {
|
|
13130
13133
|
name: "explain",
|
|
13131
13134
|
description: "Replay a session as a navigable tree with cost/latency annotations. Reads usage_log + optionally walks the transcripts directory for per-tool summaries.",
|
|
@@ -13143,12 +13146,11 @@ function explainTool(storage, bridge, transcriptsDir) {
|
|
|
13143
13146
|
},
|
|
13144
13147
|
handler: (args) => runExplain(args, {
|
|
13145
13148
|
...storage ? { storage } : {},
|
|
13146
|
-
...bridge ? { bridge } : {},
|
|
13147
13149
|
...transcriptsDir ? { transcriptsDir } : {}
|
|
13148
13150
|
})
|
|
13149
13151
|
};
|
|
13150
13152
|
}
|
|
13151
|
-
function scoreboardTool(storage,
|
|
13153
|
+
function scoreboardTool(storage, eventsPath) {
|
|
13152
13154
|
return {
|
|
13153
13155
|
name: "scoreboard",
|
|
13154
13156
|
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).",
|
|
@@ -13162,12 +13164,11 @@ function scoreboardTool(storage, bridge, eventsPath) {
|
|
|
13162
13164
|
},
|
|
13163
13165
|
handler: (args) => runScoreboard(args, {
|
|
13164
13166
|
...storage ? { storage } : {},
|
|
13165
|
-
...bridge ? { bridge } : {},
|
|
13166
13167
|
...eventsPath ? { eventsPath } : {}
|
|
13167
13168
|
})
|
|
13168
13169
|
};
|
|
13169
13170
|
}
|
|
13170
|
-
function sessionMemoryTool(storage
|
|
13171
|
+
function sessionMemoryTool(storage) {
|
|
13171
13172
|
return {
|
|
13172
13173
|
name: "session_memory",
|
|
13173
13174
|
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).",
|
|
@@ -13190,15 +13191,14 @@ function sessionMemoryTool(storage, bridge) {
|
|
|
13190
13191
|
required: ["action", "session_id"]
|
|
13191
13192
|
},
|
|
13192
13193
|
handler: (args) => runSessionMemory(args, {
|
|
13193
|
-
...storage ? { storage } : {}
|
|
13194
|
-
...bridge ? { bridge } : {}
|
|
13194
|
+
...storage ? { storage } : {}
|
|
13195
13195
|
})
|
|
13196
13196
|
};
|
|
13197
13197
|
}
|
|
13198
|
-
function recallTool(storage
|
|
13198
|
+
function recallTool(storage) {
|
|
13199
13199
|
return {
|
|
13200
13200
|
name: "recall",
|
|
13201
|
-
description: "Full-text search across persisted transcripts via SQLite FTS5. Returns rows ordered by relevance with a windowed snippet. Requires a wired Storage adapter
|
|
13201
|
+
description: "Full-text search across persisted transcripts via SQLite FTS5. Returns rows ordered by relevance with a windowed snippet. Requires a wired Storage adapter.",
|
|
13202
13202
|
inputSchema: {
|
|
13203
13203
|
type: "object",
|
|
13204
13204
|
additionalProperties: true,
|
|
@@ -13212,8 +13212,7 @@ function recallTool(storage, bridge) {
|
|
|
13212
13212
|
required: ["query"]
|
|
13213
13213
|
},
|
|
13214
13214
|
handler: (args) => runRecall(args, {
|
|
13215
|
-
...storage ? { storage } : {}
|
|
13216
|
-
...bridge ? { bridge } : {}
|
|
13215
|
+
...storage ? { storage } : {}
|
|
13217
13216
|
})
|
|
13218
13217
|
};
|
|
13219
13218
|
}
|
|
@@ -13249,7 +13248,7 @@ function modelsTool(providers, activeProviders) {
|
|
|
13249
13248
|
handler: async (args) => runModels(args, { providers, activeProviders })
|
|
13250
13249
|
};
|
|
13251
13250
|
}
|
|
13252
|
-
function reviewTool(providers, allowlist,
|
|
13251
|
+
function reviewTool(providers, allowlist, storage, breakers, transcriptsDir, repoRoot) {
|
|
13253
13252
|
return {
|
|
13254
13253
|
name: "review",
|
|
13255
13254
|
description: "Have an LLM panel peer-review a code or proposal snippet. Returns the confer envelope (one answer per provider).",
|
|
@@ -13268,7 +13267,6 @@ function reviewTool(providers, allowlist, bridge, storage, breakers, transcripts
|
|
|
13268
13267
|
handler: (args) => runReview(args, {
|
|
13269
13268
|
providers,
|
|
13270
13269
|
allowlist,
|
|
13271
|
-
...bridge ? { bridge } : {},
|
|
13272
13270
|
...storage ? { storage } : {},
|
|
13273
13271
|
...breakers ? { breakers } : {},
|
|
13274
13272
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -13276,7 +13274,7 @@ function reviewTool(providers, allowlist, bridge, storage, breakers, transcripts
|
|
|
13276
13274
|
})
|
|
13277
13275
|
};
|
|
13278
13276
|
}
|
|
13279
|
-
function critiqueTool(providers, allowlist,
|
|
13277
|
+
function critiqueTool(providers, allowlist, storage, breakers, transcriptsDir, repoRoot) {
|
|
13280
13278
|
return {
|
|
13281
13279
|
name: "critique",
|
|
13282
13280
|
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.",
|
|
@@ -13296,7 +13294,6 @@ function critiqueTool(providers, allowlist, bridge, storage, breakers, transcrip
|
|
|
13296
13294
|
handler: (args) => runCritique(args, {
|
|
13297
13295
|
providers,
|
|
13298
13296
|
allowlist,
|
|
13299
|
-
...bridge ? { bridge } : {},
|
|
13300
13297
|
...storage ? { storage } : {},
|
|
13301
13298
|
...breakers ? { breakers } : {},
|
|
13302
13299
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -13304,7 +13301,7 @@ function critiqueTool(providers, allowlist, bridge, storage, breakers, transcrip
|
|
|
13304
13301
|
})
|
|
13305
13302
|
};
|
|
13306
13303
|
}
|
|
13307
|
-
function planTool(providers, allowlist,
|
|
13304
|
+
function planTool(providers, allowlist, storage, breakers, transcriptsDir, repoRoot) {
|
|
13308
13305
|
return {
|
|
13309
13306
|
name: "plan",
|
|
13310
13307
|
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.',
|
|
@@ -13331,7 +13328,6 @@ function planTool(providers, allowlist, bridge, storage, breakers, transcriptsDi
|
|
|
13331
13328
|
handler: (args) => runPlan(args, {
|
|
13332
13329
|
providers,
|
|
13333
13330
|
allowlist,
|
|
13334
|
-
...bridge ? { bridge } : {},
|
|
13335
13331
|
...storage ? { storage } : {},
|
|
13336
13332
|
...breakers ? { breakers } : {},
|
|
13337
13333
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -13339,7 +13335,7 @@ function planTool(providers, allowlist, bridge, storage, breakers, transcriptsDi
|
|
|
13339
13335
|
})
|
|
13340
13336
|
};
|
|
13341
13337
|
}
|
|
13342
|
-
function triangulateTool(providers, allowlist,
|
|
13338
|
+
function triangulateTool(providers, allowlist, storage, breakers, transcriptsDir, repoRoot) {
|
|
13343
13339
|
return {
|
|
13344
13340
|
name: "triangulate",
|
|
13345
13341
|
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.",
|
|
@@ -13360,7 +13356,6 @@ function triangulateTool(providers, allowlist, bridge, storage, breakers, transc
|
|
|
13360
13356
|
handler: (args) => runTriangulate(args, {
|
|
13361
13357
|
providers,
|
|
13362
13358
|
allowlist,
|
|
13363
|
-
...bridge ? { bridge } : {},
|
|
13364
13359
|
...storage ? { storage } : {},
|
|
13365
13360
|
...breakers ? { breakers } : {},
|
|
13366
13361
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
@@ -13368,7 +13363,7 @@ function triangulateTool(providers, allowlist, bridge, storage, breakers, transc
|
|
|
13368
13363
|
})
|
|
13369
13364
|
};
|
|
13370
13365
|
}
|
|
13371
|
-
function coordinateTool(providers, allowlist,
|
|
13366
|
+
function coordinateTool(providers, allowlist, innerCallers, storage, breakers, transcriptsDir, repoRoot, workerToolsCfg) {
|
|
13372
13367
|
return {
|
|
13373
13368
|
name: "coordinate",
|
|
13374
13369
|
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).",
|
|
@@ -13393,7 +13388,6 @@ function coordinateTool(providers, allowlist, bridge, innerCallers, storage, bre
|
|
|
13393
13388
|
handler: (args) => runCoordinate(args, {
|
|
13394
13389
|
providers,
|
|
13395
13390
|
allowlist,
|
|
13396
|
-
...bridge ? { bridge } : {},
|
|
13397
13391
|
innerCallers,
|
|
13398
13392
|
...storage ? { storage } : {},
|
|
13399
13393
|
...breakers ? { breakers } : {},
|
|
@@ -13403,7 +13397,7 @@ function coordinateTool(providers, allowlist, bridge, innerCallers, storage, bre
|
|
|
13403
13397
|
})
|
|
13404
13398
|
};
|
|
13405
13399
|
}
|
|
13406
|
-
function debateTool(providers, allowlist,
|
|
13400
|
+
function debateTool(providers, allowlist, innerCallers, storage, pricing, breakers, transcriptsDir, repoRoot, workerToolsCfg) {
|
|
13407
13401
|
return {
|
|
13408
13402
|
name: "debate",
|
|
13409
13403
|
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).",
|
|
@@ -13433,7 +13427,6 @@ function debateTool(providers, allowlist, bridge, innerCallers, storage, pricing
|
|
|
13433
13427
|
handler: (args) => runDebate(args, {
|
|
13434
13428
|
providers,
|
|
13435
13429
|
allowlist,
|
|
13436
|
-
...bridge ? { bridge } : {},
|
|
13437
13430
|
innerCallers,
|
|
13438
13431
|
...storage ? { storage } : {},
|
|
13439
13432
|
...pricing ? { pricing } : {},
|
|
@@ -13453,10 +13446,10 @@ function buildInnerCallers(o) {
|
|
|
13453
13446
|
...o.repoRoot ? { repoRoot: o.repoRoot } : {}
|
|
13454
13447
|
});
|
|
13455
13448
|
}
|
|
13456
|
-
out.verify = (args) => runVerify(args, o.
|
|
13449
|
+
out.verify = (args) => runVerify(args, o.fetchConfig);
|
|
13457
13450
|
return out;
|
|
13458
13451
|
}
|
|
13459
|
-
function conferTool(providers, allowlist,
|
|
13452
|
+
function conferTool(providers, allowlist, moderator, pricing, storage, innerCallers, breakers, transcriptsDir, repoRoot, workerToolsCfg) {
|
|
13460
13453
|
return {
|
|
13461
13454
|
name: "confer",
|
|
13462
13455
|
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).",
|
|
@@ -13483,7 +13476,6 @@ function conferTool(providers, allowlist, bridge, moderator, pricing, storage, i
|
|
|
13483
13476
|
handler: (args) => runConfer(args, {
|
|
13484
13477
|
providers,
|
|
13485
13478
|
allowlist,
|
|
13486
|
-
...bridge ? { bridge } : {},
|
|
13487
13479
|
moderator,
|
|
13488
13480
|
...pricing ? { pricing } : {},
|
|
13489
13481
|
...storage ? { storage } : {},
|
|
@@ -13495,7 +13487,7 @@ function conferTool(providers, allowlist, bridge, moderator, pricing, storage, i
|
|
|
13495
13487
|
})
|
|
13496
13488
|
};
|
|
13497
13489
|
}
|
|
13498
|
-
function auditTool(providers, allowlist,
|
|
13490
|
+
function auditTool(providers, allowlist, transcriptsDir, pricing, storage, breakers, repoRoot) {
|
|
13499
13491
|
return {
|
|
13500
13492
|
name: "audit",
|
|
13501
13493
|
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.",
|
|
@@ -13521,7 +13513,6 @@ function auditTool(providers, allowlist, bridge, transcriptsDir, pricing, storag
|
|
|
13521
13513
|
handler: (args) => runAudit(args, {
|
|
13522
13514
|
providers,
|
|
13523
13515
|
allowlist,
|
|
13524
|
-
...bridge ? { bridge } : {},
|
|
13525
13516
|
...transcriptsDir ? { transcriptsDir } : {},
|
|
13526
13517
|
...pricing ? { pricing } : {},
|
|
13527
13518
|
...storage ? { storage } : {},
|
|
@@ -13585,7 +13576,7 @@ function pickTool(providers, allowlist, storage, breakers, transcriptsDir, repoR
|
|
|
13585
13576
|
})
|
|
13586
13577
|
};
|
|
13587
13578
|
}
|
|
13588
|
-
function verifyTool(
|
|
13579
|
+
function verifyTool(fetchConfig) {
|
|
13589
13580
|
return {
|
|
13590
13581
|
name: "verify",
|
|
13591
13582
|
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.",
|
|
@@ -13603,7 +13594,7 @@ function verifyTool(bridge, fetchConfig) {
|
|
|
13603
13594
|
},
|
|
13604
13595
|
required: ["checks"]
|
|
13605
13596
|
},
|
|
13606
|
-
handler: (args) => runVerify(args,
|
|
13597
|
+
handler: (args) => runVerify(args, fetchConfig)
|
|
13607
13598
|
};
|
|
13608
13599
|
}
|
|
13609
13600
|
function pingTool() {
|
|
@@ -13653,7 +13644,7 @@ function createCrosscheck(opts) {
|
|
|
13653
13644
|
// Direct runConfer call with a streaming hook — bypasses the tool
|
|
13654
13645
|
// registry (whose handler signature can't carry a callback). Uses the
|
|
13655
13646
|
// same opts the registry wires for confer in a browser build: providers
|
|
13656
|
-
// + pricing + default moderator; storage/
|
|
13647
|
+
// + pricing + default moderator; storage/innerCallers aren't
|
|
13657
13648
|
// available here, matching the non-streaming path.
|
|
13658
13649
|
conferStream: (args, onAnswer) => runConfer(args, { providers, pricing: pricingDoc, moderator: "anthropic", onAnswer }),
|
|
13659
13650
|
debateStream: (args, { onTurn, onSynthesis } = {}) => runDebate(args, {
|