@remnic/cli 9.6.24 → 9.6.26
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/dist/index.js +269 -59
- package/package.json +28 -28
package/dist/index.js
CHANGED
|
@@ -782,6 +782,14 @@ var BENCH_VALUE_FLAGS = Object.freeze([
|
|
|
782
782
|
"--provider",
|
|
783
783
|
"--base-url",
|
|
784
784
|
"--request-timeout",
|
|
785
|
+
"--local-judge-request-timeout",
|
|
786
|
+
"--frontier-judge-request-timeout",
|
|
787
|
+
"--calibration-dir",
|
|
788
|
+
"--calibration-local-config-sha256",
|
|
789
|
+
"--calibration-frontier-config-sha256",
|
|
790
|
+
"--source-result-id",
|
|
791
|
+
"--expected-answer-set-sha256",
|
|
792
|
+
"--expected-question-id-list-sha256",
|
|
785
793
|
"--drain-timeout",
|
|
786
794
|
"--max-429-wait",
|
|
787
795
|
"--ama-bench-judge-protocol",
|
|
@@ -862,6 +870,9 @@ var RUN_VALUE_FLAGS = Object.freeze([
|
|
|
862
870
|
"--provider",
|
|
863
871
|
"--base-url",
|
|
864
872
|
"--request-timeout",
|
|
873
|
+
"--calibration-dir",
|
|
874
|
+
"--calibration-local-config-sha256",
|
|
875
|
+
"--calibration-frontier-config-sha256",
|
|
865
876
|
"--drain-timeout",
|
|
866
877
|
"--max-429-wait",
|
|
867
878
|
"--ama-bench-judge-protocol",
|
|
@@ -937,9 +948,16 @@ var BENCH_ACTION_FLAGS = {
|
|
|
937
948
|
"--judge-provider",
|
|
938
949
|
"--judge-model",
|
|
939
950
|
"--judge-base-url",
|
|
940
|
-
"--judge-api-key"
|
|
951
|
+
"--judge-api-key",
|
|
952
|
+
"--local-judge-request-timeout",
|
|
953
|
+
"--frontier-judge-request-timeout",
|
|
954
|
+
"--max-429-wait",
|
|
955
|
+
"--calibration-dir",
|
|
956
|
+
"--source-result-id",
|
|
957
|
+
"--expected-answer-set-sha256",
|
|
958
|
+
"--expected-question-id-list-sha256"
|
|
941
959
|
],
|
|
942
|
-
boolean: ["--json", "--help", "-h"]
|
|
960
|
+
boolean: ["--disable-thinking", "--json", "--help", "-h"]
|
|
943
961
|
},
|
|
944
962
|
published: {
|
|
945
963
|
value: PUBLISHED_VALUE_FLAGS,
|
|
@@ -1121,6 +1139,14 @@ function parseBenchArgs(argv) {
|
|
|
1121
1139
|
const output = readBenchOptionValue(args, "--output");
|
|
1122
1140
|
const targetRaw = readBenchOptionValue(args, "--target");
|
|
1123
1141
|
const requestTimeoutRaw = readBenchOptionValue(args, "--request-timeout");
|
|
1142
|
+
const localJudgeRequestTimeoutRaw = readBenchOptionValue(args, "--local-judge-request-timeout");
|
|
1143
|
+
const frontierJudgeRequestTimeoutRaw = readBenchOptionValue(args, "--frontier-judge-request-timeout");
|
|
1144
|
+
const calibrationDirRaw = readBenchOptionValue(args, "--calibration-dir");
|
|
1145
|
+
const calibrationLocalConfigSha256 = readBenchOptionValue(args, "--calibration-local-config-sha256");
|
|
1146
|
+
const calibrationFrontierConfigSha256 = readBenchOptionValue(args, "--calibration-frontier-config-sha256");
|
|
1147
|
+
const sourceResultId = readBenchOptionValue(args, "--source-result-id");
|
|
1148
|
+
const expectedAnswerSetSha256 = readBenchOptionValue(args, "--expected-answer-set-sha256");
|
|
1149
|
+
const expectedQuestionIdListSha256 = readBenchOptionValue(args, "--expected-question-id-list-sha256");
|
|
1124
1150
|
const drainTimeoutRaw = readBenchOptionValue(args, "--drain-timeout");
|
|
1125
1151
|
const judgeCacheDirRaw = readBenchOptionValue(args, "--judge-cache-dir");
|
|
1126
1152
|
const localLabManifestRaw = readBenchOptionValue(args, "--local-lab-manifest");
|
|
@@ -1296,6 +1322,26 @@ function parseBenchArgs(argv) {
|
|
|
1296
1322
|
);
|
|
1297
1323
|
}
|
|
1298
1324
|
}
|
|
1325
|
+
const parseJudgeTimeout = (raw, flag) => {
|
|
1326
|
+
if (raw === void 0) return void 0;
|
|
1327
|
+
const value = Number(raw);
|
|
1328
|
+
if (!Number.isInteger(value) || value <= 0 || value > 36e5) {
|
|
1329
|
+
throw new Error(`ERROR: ${flag} must be a positive integer no greater than 3,600,000 ms.`);
|
|
1330
|
+
}
|
|
1331
|
+
return value;
|
|
1332
|
+
};
|
|
1333
|
+
const localJudgeRequestTimeout = parseJudgeTimeout(localJudgeRequestTimeoutRaw, "--local-judge-request-timeout");
|
|
1334
|
+
const frontierJudgeRequestTimeout = parseJudgeTimeout(frontierJudgeRequestTimeoutRaw, "--frontier-judge-request-timeout");
|
|
1335
|
+
for (const [flag, digest] of [
|
|
1336
|
+
["--expected-answer-set-sha256", expectedAnswerSetSha256],
|
|
1337
|
+
["--expected-question-id-list-sha256", expectedQuestionIdListSha256],
|
|
1338
|
+
["--calibration-local-config-sha256", calibrationLocalConfigSha256],
|
|
1339
|
+
["--calibration-frontier-config-sha256", calibrationFrontierConfigSha256]
|
|
1340
|
+
]) {
|
|
1341
|
+
if (digest !== void 0 && !/^[0-9a-f]{64}$/.test(digest)) {
|
|
1342
|
+
throw new Error(`ERROR: ${flag} must be a lowercase SHA-256 hex digest.`);
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1299
1345
|
let drainTimeout;
|
|
1300
1346
|
if (drainTimeoutRaw !== void 0) {
|
|
1301
1347
|
drainTimeout = Number(drainTimeoutRaw);
|
|
@@ -1604,6 +1650,14 @@ function parseBenchArgs(argv) {
|
|
|
1604
1650
|
publishedOut: publishedOutRaw ? path4.resolve(expandTilde(publishedOutRaw)) : void 0,
|
|
1605
1651
|
publishedDryRun: args.includes("--dry-run"),
|
|
1606
1652
|
requestTimeout,
|
|
1653
|
+
localJudgeRequestTimeout,
|
|
1654
|
+
frontierJudgeRequestTimeout,
|
|
1655
|
+
calibrationDir: calibrationDirRaw ? path4.resolve(expandTilde(calibrationDirRaw)) : void 0,
|
|
1656
|
+
calibrationLocalConfigSha256,
|
|
1657
|
+
calibrationFrontierConfigSha256,
|
|
1658
|
+
sourceResultId,
|
|
1659
|
+
expectedAnswerSetSha256,
|
|
1660
|
+
expectedQuestionIdListSha256,
|
|
1607
1661
|
drainTimeout,
|
|
1608
1662
|
// Issue #1573 PR1: surface judge-cache flags into the runner options.
|
|
1609
1663
|
noJudgeCache: args.includes("--no-judge-cache"),
|
|
@@ -3449,7 +3503,9 @@ Commands:
|
|
|
3449
3503
|
Generate the Remnic.ai benchmark feed from stored runs
|
|
3450
3504
|
ui Launch the local benchmark overview UI
|
|
3451
3505
|
providers discover Auto-detect available local provider backends
|
|
3452
|
-
judge-calibrate --benchmark <id> --
|
|
3506
|
+
judge-calibrate --benchmark <id> --source-result-id <id> --expected-answer-set-sha256 <sha256>
|
|
3507
|
+
--expected-question-id-list-sha256 <sha256>
|
|
3508
|
+
--local-lab-manifest <path> --judge-provider <p> --judge-model <m>
|
|
3453
3509
|
Cross-tier judge calibration (issue #1573): runs the
|
|
3454
3510
|
local + frontier judges over a benchmark's cached
|
|
3455
3511
|
answers, reports Cohen's kappa, and persists it so
|
|
@@ -3510,6 +3566,7 @@ Options:
|
|
|
3510
3566
|
Codex CLI reasoning effort for Remnic's internal LLM
|
|
3511
3567
|
--ama-bench-judge-protocol <default|recommended>
|
|
3512
3568
|
For ama-bench, use the recommended binary LLM-judge protocol
|
|
3569
|
+
(default-protocol calibration is not attached to recommended runs)
|
|
3513
3570
|
--ama-bench-cross-judge-model <model>
|
|
3514
3571
|
For ama-bench, add a second recommended-protocol judge for agreement checks
|
|
3515
3572
|
--ama-bench-cross-judge-provider <provider>
|
|
@@ -3522,6 +3579,22 @@ Options:
|
|
|
3522
3579
|
--results-dir <path> Override the stored benchmark results directory
|
|
3523
3580
|
--baselines-dir <path> Override the named baseline directory
|
|
3524
3581
|
--request-timeout <ms> Provider request timeout in milliseconds (codex-cli default: 180000)
|
|
3582
|
+
--local-judge-request-timeout <ms>
|
|
3583
|
+
Calibration-only timeout for each local judge call
|
|
3584
|
+
--frontier-judge-request-timeout <ms>
|
|
3585
|
+
Calibration-only timeout for each frontier judge call
|
|
3586
|
+
--max-429-wait <ms> Maximum cumulative 429 retry wait for provider calls
|
|
3587
|
+
--disable-thinking Disable thinking for supported provider-backed models
|
|
3588
|
+
--source-result-id <id> Exact full stored result used by judge-calibrate
|
|
3589
|
+
--expected-answer-set-sha256 <sha256>
|
|
3590
|
+
Expected deterministic calibration-slice payload hash
|
|
3591
|
+
--expected-question-id-list-sha256 <sha256>
|
|
3592
|
+
Expected ordered source task-ID list hash
|
|
3593
|
+
--calibration-dir <path> Private final-state and resumable-checkpoint directory
|
|
3594
|
+
--calibration-local-config-sha256 <sha256>
|
|
3595
|
+
Required on later runs that attach calibration state
|
|
3596
|
+
--calibration-frontier-config-sha256 <sha256>
|
|
3597
|
+
Required on later runs that attach calibration state
|
|
3525
3598
|
--drain-timeout <ms> Memory drain timeout in milliseconds
|
|
3526
3599
|
(defaults to --request-timeout; implicit codex-cli default: 600000)
|
|
3527
3600
|
--local-lab-manifest <path>
|
|
@@ -3596,7 +3669,7 @@ function buildBenchRuntimeProfileRequest(parsed, runtimeProfile) {
|
|
|
3596
3669
|
max429WaitMs: parsed.max429WaitMs,
|
|
3597
3670
|
disableThinking: parsed.disableThinking,
|
|
3598
3671
|
lcmObserveConcurrency: parsed.publishedIngestConcurrency,
|
|
3599
|
-
localLabManifestPath:
|
|
3672
|
+
localLabManifestPath: parsed.localLabManifestPath
|
|
3600
3673
|
};
|
|
3601
3674
|
}
|
|
3602
3675
|
var BENCH_STDOUT_REDACTED_SECRET = "[REDACTED]";
|
|
@@ -4673,12 +4746,19 @@ async function calibrateBenchJudges(parsed, rawArgs) {
|
|
|
4673
4746
|
);
|
|
4674
4747
|
process.exit(1);
|
|
4675
4748
|
}
|
|
4749
|
+
if (!parsed.sourceResultId || !parsed.expectedAnswerSetSha256 || !parsed.expectedQuestionIdListSha256) {
|
|
4750
|
+
console.error(
|
|
4751
|
+
"ERROR: judge-calibrate requires --source-result-id, --expected-answer-set-sha256, and --expected-question-id-list-sha256 so all source drift is rejected before judge calls."
|
|
4752
|
+
);
|
|
4753
|
+
process.exit(1);
|
|
4754
|
+
}
|
|
4676
4755
|
const bench = await loadBenchModule();
|
|
4677
4756
|
const resultsDir = expandTilde(
|
|
4678
4757
|
parsed.resultsDir ?? path11.join(resolveHomeDir(), ".remnic", "bench", "results")
|
|
4679
4758
|
);
|
|
4680
|
-
const calibrationDir =
|
|
4681
|
-
|
|
4759
|
+
const calibrationDir = expandTilde(
|
|
4760
|
+
parsed.calibrationDir ?? path11.join(resolveHomeDir(), ".remnic", "bench", "calibration")
|
|
4761
|
+
);
|
|
4682
4762
|
const stored = await bench.listBenchmarkResults(resultsDir);
|
|
4683
4763
|
const allForBenchmark = stored.filter((entry) => entry.benchmark === benchmarkId);
|
|
4684
4764
|
const candidates = allForBenchmark.filter((entry) => entry.mode === "full").sort((a, b) => {
|
|
@@ -4687,32 +4767,16 @@ async function calibrateBenchJudges(parsed, rawArgs) {
|
|
|
4687
4767
|
}
|
|
4688
4768
|
return a.id < b.id ? 1 : a.id > b.id ? -1 : 0;
|
|
4689
4769
|
});
|
|
4690
|
-
const pinnedSourceId =
|
|
4691
|
-
const latest =
|
|
4770
|
+
const pinnedSourceId = parsed.sourceResultId;
|
|
4771
|
+
const latest = candidates.find((entry) => entry.id === pinnedSourceId);
|
|
4692
4772
|
if (!latest) {
|
|
4693
|
-
if (pinnedSourceId) {
|
|
4694
|
-
console.error(
|
|
4695
|
-
`ERROR: pinned calibration source ${pinnedSourceId} for "${benchmarkId}" is no longer present in ${resultsDir}. Restore that stored result or remove the calibration state intentionally before selecting a new answer set.`
|
|
4696
|
-
);
|
|
4697
|
-
process.exit(1);
|
|
4698
|
-
}
|
|
4699
|
-
const quickCount = allForBenchmark.filter((entry) => entry.mode === "quick").length;
|
|
4700
4773
|
console.error(
|
|
4701
|
-
|
|
4774
|
+
`ERROR: explicitly pinned full calibration source ${pinnedSourceId} for "${benchmarkId}" is not present in ${resultsDir}. Restore that exact stored result.`
|
|
4702
4775
|
);
|
|
4703
4776
|
process.exit(1);
|
|
4704
4777
|
}
|
|
4705
4778
|
let loaded = await bench.loadBenchmarkResult(latest.path);
|
|
4706
|
-
if (
|
|
4707
|
-
for (const candidate of candidates.slice(1)) {
|
|
4708
|
-
const candidateResult = await bench.loadBenchmarkResult(candidate.path);
|
|
4709
|
-
if (candidateResult.meta.status !== "partial") {
|
|
4710
|
-
loaded = candidateResult;
|
|
4711
|
-
break;
|
|
4712
|
-
}
|
|
4713
|
-
}
|
|
4714
|
-
}
|
|
4715
|
-
if (pinnedSourceId && loaded.meta.status === "partial") {
|
|
4779
|
+
if (loaded.meta.status === "partial") {
|
|
4716
4780
|
console.error(
|
|
4717
4781
|
`ERROR: pinned calibration source ${pinnedSourceId} is partial. Restore a complete copy or remove the calibration state intentionally before selecting a new answer set.`
|
|
4718
4782
|
);
|
|
@@ -4732,23 +4796,53 @@ async function calibrateBenchJudges(parsed, rawArgs) {
|
|
|
4732
4796
|
predicted: task.actual,
|
|
4733
4797
|
expected: task.expected
|
|
4734
4798
|
}));
|
|
4735
|
-
const
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4799
|
+
const orderedQuestionIdsHash = bench.hashOrderedQuestionIds(
|
|
4800
|
+
loaded.results.tasks.map((task) => task.taskId)
|
|
4801
|
+
);
|
|
4802
|
+
if (orderedQuestionIdsHash !== parsed.expectedQuestionIdListSha256) {
|
|
4803
|
+
console.error(
|
|
4804
|
+
`ERROR: ordered question-id list changed for ${loaded.meta.id} (expected sha256:${parsed.expectedQuestionIdListSha256}, got sha256:${orderedQuestionIdsHash}); refusing to call judges.`
|
|
4805
|
+
);
|
|
4806
|
+
process.exit(1);
|
|
4807
|
+
}
|
|
4808
|
+
const sourceResultSha256 = createHash("sha256").update(fs7.readFileSync(latest.path)).digest("hex");
|
|
4809
|
+
const expandedManifestPath = expandTilde(manifestPath);
|
|
4810
|
+
if (!bench.resolveLocalLabJudgeProviderConfig) {
|
|
4811
|
+
console.error(
|
|
4812
|
+
"ERROR: installed @remnic/bench version does not export resolveLocalLabJudgeProviderConfig; rebuild or upgrade @remnic/bench before calibrating."
|
|
4813
|
+
);
|
|
4814
|
+
process.exit(1);
|
|
4815
|
+
}
|
|
4816
|
+
const localJudgeConfig = await bench.resolveLocalLabJudgeProviderConfig({
|
|
4817
|
+
localLabManifestPath: expandedManifestPath,
|
|
4818
|
+
...parsed.localJudgeRequestTimeout ? { requestTimeout: parsed.localJudgeRequestTimeout } : {},
|
|
4819
|
+
max429WaitMs: parsed.max429WaitMs,
|
|
4820
|
+
disableThinking: parsed.disableThinking
|
|
4744
4821
|
});
|
|
4822
|
+
const localJudge = bench.createProviderBackedJudge(localJudgeConfig);
|
|
4823
|
+
const frontierJudgeConfig = buildCalibrationFrontierJudgeConfig(
|
|
4824
|
+
parsed
|
|
4825
|
+
);
|
|
4826
|
+
const frontierJudge = bench.createProviderBackedJudge(frontierJudgeConfig);
|
|
4827
|
+
const localJudgeConfigHash = hashCalibrationProviderConfig(localJudgeConfig);
|
|
4828
|
+
const frontierJudgeConfigHash = hashCalibrationProviderConfig(frontierJudgeConfig);
|
|
4745
4829
|
const result = await bench.runJudgeCalibration({
|
|
4746
4830
|
benchmarkId,
|
|
4747
4831
|
localJudge,
|
|
4748
4832
|
frontierJudge,
|
|
4749
4833
|
answers,
|
|
4750
|
-
|
|
4751
|
-
|
|
4834
|
+
expectedAnswerSetHash: parsed.expectedAnswerSetSha256,
|
|
4835
|
+
expectedOrderedQuestionIdsHash: parsed.expectedQuestionIdListSha256,
|
|
4836
|
+
checkpoint: {
|
|
4837
|
+
dir: calibrationDir,
|
|
4838
|
+
sourceResultId: loaded.meta.id,
|
|
4839
|
+
sourceResultSha256,
|
|
4840
|
+
orderedQuestionIdsHash,
|
|
4841
|
+
localJudgePromptIdentity: bench.getProviderBackedJudgePromptIdentity(localJudgeConfig),
|
|
4842
|
+
frontierJudgePromptIdentity: bench.getProviderBackedJudgePromptIdentity(frontierJudgeConfig),
|
|
4843
|
+
localJudgeConfigHash,
|
|
4844
|
+
frontierJudgeConfigHash
|
|
4845
|
+
}
|
|
4752
4846
|
});
|
|
4753
4847
|
const calibrationIdentities = {
|
|
4754
4848
|
localJudgeProvider: String(localJudgeConfig.provider),
|
|
@@ -4760,10 +4854,10 @@ async function calibrateBenchJudges(parsed, rawArgs) {
|
|
|
4760
4854
|
result,
|
|
4761
4855
|
calibrationDir,
|
|
4762
4856
|
calibrationIdentities,
|
|
4763
|
-
{ sourceResultId: loaded.meta.id }
|
|
4857
|
+
{ sourceResultId: loaded.meta.id, localJudgeConfigHash, frontierJudgeConfigHash }
|
|
4764
4858
|
);
|
|
4765
4859
|
const persisted = await bench.loadJudgeCalibrationState(benchmarkId, calibrationDir);
|
|
4766
|
-
if (!persisted || persisted.kappa !== result.kappa || persisted.warning !== result.warning) {
|
|
4860
|
+
if (!persisted || persisted.kappa !== result.kappa || persisted.warning !== result.warning || persisted.localJudgeConfigHash !== localJudgeConfigHash || persisted.frontierJudgeConfigHash !== frontierJudgeConfigHash) {
|
|
4767
4861
|
console.error(
|
|
4768
4862
|
`ERROR: calibration state round-trip failed for ${benchmarkId} (wrote kappa ${result.kappa}, read back ${persisted ? persisted.kappa : "nothing"}). Re-run judge-calibrate.`
|
|
4769
4863
|
);
|
|
@@ -4785,6 +4879,11 @@ async function calibrateBenchJudges(parsed, rawArgs) {
|
|
|
4785
4879
|
answerSetHash: result.answerSetHash,
|
|
4786
4880
|
sourceResultId: loaded.meta.id,
|
|
4787
4881
|
categories: result.categories,
|
|
4882
|
+
orderedQuestionIdsHash,
|
|
4883
|
+
sourceResultSha256,
|
|
4884
|
+
localJudgeConfigHash,
|
|
4885
|
+
frontierJudgeConfigHash,
|
|
4886
|
+
execution: result.execution,
|
|
4788
4887
|
statePath
|
|
4789
4888
|
},
|
|
4790
4889
|
null,
|
|
@@ -4800,6 +4899,8 @@ async function calibrateBenchJudges(parsed, rawArgs) {
|
|
|
4800
4899
|
` ${(result.confidenceInterval.level * 100).toFixed(0)}% bootstrap CI: [${result.confidenceInterval.lower.toFixed(4)}, ${result.confidenceInterval.upper.toFixed(4)}] (${result.bootstrapSamples} paired resamples)`
|
|
4801
4900
|
);
|
|
4802
4901
|
console.log(` Pinned source: ${loaded.meta.id} (answer set sha256:${result.answerSetHash})`);
|
|
4902
|
+
console.log(` Ordered question ids: sha256:${orderedQuestionIdsHash}`);
|
|
4903
|
+
console.log(` Judge calls: local ${result.execution.localJudgeCalls}, frontier ${result.execution.frontierJudgeCalls}; resumed outputs ${result.execution.resumedJudgeOutputs}`);
|
|
4803
4904
|
console.log(` Observed agreement: ${result.observedAgreement.toFixed(4)}`);
|
|
4804
4905
|
console.log(` Expected agreement: ${result.expectedAgreement.toFixed(4)}`);
|
|
4805
4906
|
if (result.warning) {
|
|
@@ -4812,6 +4913,26 @@ async function calibrateBenchJudges(parsed, rawArgs) {
|
|
|
4812
4913
|
console.log(` Calibration state written + verified (round-trip ok): ${statePath}`);
|
|
4813
4914
|
console.log(` Subsequent local artifacts for ${benchmarkId} will carry kappa ${persisted.kappa.toFixed(4)}.`);
|
|
4814
4915
|
}
|
|
4916
|
+
function buildCalibrationFrontierJudgeConfig(parsed) {
|
|
4917
|
+
if (!parsed.judgeProvider || !parsed.judgeModel) {
|
|
4918
|
+
throw new Error(
|
|
4919
|
+
"Calibration frontier judge requires both --judge-provider and --judge-model."
|
|
4920
|
+
);
|
|
4921
|
+
}
|
|
4922
|
+
return {
|
|
4923
|
+
provider: parsed.judgeProvider,
|
|
4924
|
+
model: parsed.judgeModel,
|
|
4925
|
+
...parsed.judgeBaseUrl ? { baseUrl: parsed.judgeBaseUrl } : {},
|
|
4926
|
+
...parsed.judgeApiKey ? { apiKey: parsed.judgeApiKey } : {},
|
|
4927
|
+
...parsed.frontierJudgeRequestTimeout !== void 0 || parsed.max429WaitMs !== void 0 ? {
|
|
4928
|
+
retryOptions: {
|
|
4929
|
+
...parsed.frontierJudgeRequestTimeout !== void 0 ? { timeoutMs: parsed.frontierJudgeRequestTimeout } : {},
|
|
4930
|
+
...parsed.max429WaitMs !== void 0 ? { max429WaitMs: parsed.max429WaitMs } : {}
|
|
4931
|
+
}
|
|
4932
|
+
} : {},
|
|
4933
|
+
...parsed.disableThinking ? { disableThinking: true } : {}
|
|
4934
|
+
};
|
|
4935
|
+
}
|
|
4815
4936
|
async function publishBenchPackageResults(parsed) {
|
|
4816
4937
|
if (parsed.benchmarks.length > 0) {
|
|
4817
4938
|
console.error(
|
|
@@ -5200,6 +5321,12 @@ async function runBenchViaPackage(parsed, benchmarkId, runtimeProfile, benchStat
|
|
|
5200
5321
|
if (!plan) {
|
|
5201
5322
|
return { ok: false };
|
|
5202
5323
|
}
|
|
5324
|
+
const judgeCalibration = await preparePersistedJudgeCalibrationAttachment(
|
|
5325
|
+
benchModule,
|
|
5326
|
+
benchmarkId,
|
|
5327
|
+
plan.runtime.judgeProvider,
|
|
5328
|
+
parsed
|
|
5329
|
+
);
|
|
5203
5330
|
await preflightLocalLabEndpointsIfNeeded(benchModule, plan);
|
|
5204
5331
|
const outputDir = parsed.resultsDir ?? resolveBenchOutputDir();
|
|
5205
5332
|
const datasetDir = resolveBenchDatasetDir(
|
|
@@ -5283,7 +5410,7 @@ async function runBenchViaPackage(parsed, benchmarkId, runtimeProfile, benchStat
|
|
|
5283
5410
|
});
|
|
5284
5411
|
result.config.remnicConfig = plan.runtime.remnicConfig;
|
|
5285
5412
|
result.config.internalProvider = plan.runtime.internalProvider;
|
|
5286
|
-
|
|
5413
|
+
attachPreparedJudgeCalibration(result, judgeCalibration);
|
|
5287
5414
|
const writtenPath = await benchModule.writeBenchmarkResult(result, outputDir);
|
|
5288
5415
|
if (parsed.json) {
|
|
5289
5416
|
console.log(JSON.stringify(redactBenchResultForStdout(benchModule, result), null, 2));
|
|
@@ -5304,7 +5431,7 @@ async function runBenchViaPackage(parsed, benchmarkId, runtimeProfile, benchStat
|
|
|
5304
5431
|
err instanceof Error ? err.message : String(err),
|
|
5305
5432
|
parsed.quick ? "quick" : "full"
|
|
5306
5433
|
);
|
|
5307
|
-
|
|
5434
|
+
attachPreparedJudgeCalibration(partialResult, judgeCalibration);
|
|
5308
5435
|
try {
|
|
5309
5436
|
const partialPath = await benchModule.writeBenchmarkResult(partialResult, outputDir);
|
|
5310
5437
|
console.error(` Partial results (${partialTasks.length} tasks) written to ${partialPath}`);
|
|
@@ -5328,32 +5455,111 @@ async function runBenchViaPackage(parsed, benchmarkId, runtimeProfile, benchStat
|
|
|
5328
5455
|
}
|
|
5329
5456
|
}
|
|
5330
5457
|
}
|
|
5331
|
-
async function
|
|
5332
|
-
const
|
|
5458
|
+
async function preparePersistedJudgeCalibrationAttachment(benchModule, benchmarkId, runJudgeProvider, calibrationBinding) {
|
|
5459
|
+
const hasLocalPin = Boolean(calibrationBinding.calibrationLocalConfigSha256);
|
|
5460
|
+
const hasFrontierPin = Boolean(calibrationBinding.calibrationFrontierConfigSha256);
|
|
5461
|
+
const hasAnyPin = hasLocalPin || hasFrontierPin;
|
|
5462
|
+
const hasBothPins = hasLocalPin && hasFrontierPin;
|
|
5463
|
+
if (benchmarkId === "ama-bench" && calibrationBinding.amaBenchJudgeProtocol === "recommended") {
|
|
5464
|
+
if (hasAnyPin) {
|
|
5465
|
+
throw new Error(
|
|
5466
|
+
"AMA-Bench recommended-protocol runs cannot attach default-protocol judge calibration; remove both calibration pins or calibrate the recommended prompt contract separately."
|
|
5467
|
+
);
|
|
5468
|
+
}
|
|
5469
|
+
return void 0;
|
|
5470
|
+
}
|
|
5471
|
+
if (hasAnyPin && !hasBothPins) {
|
|
5472
|
+
throw new Error(
|
|
5473
|
+
"--calibration-local-config-sha256 and --calibration-frontier-config-sha256 must be supplied together."
|
|
5474
|
+
);
|
|
5475
|
+
}
|
|
5476
|
+
const calibrationDir = expandTilde(
|
|
5477
|
+
calibrationBinding.calibrationDir ?? path11.join(resolveHomeDir(), ".remnic", "bench", "calibration")
|
|
5478
|
+
);
|
|
5333
5479
|
const state = await benchModule.loadJudgeCalibrationState?.(benchmarkId, calibrationDir);
|
|
5334
|
-
if (!state)
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5480
|
+
if (!state) {
|
|
5481
|
+
if (hasAnyPin) {
|
|
5482
|
+
throw new Error(
|
|
5483
|
+
`Calibration binding pins were supplied for ${benchmarkId}, but no valid calibration state could be loaded from ${calibrationDir}; rerun judge-calibrate or remove both pins.`
|
|
5484
|
+
);
|
|
5485
|
+
}
|
|
5486
|
+
return void 0;
|
|
5487
|
+
}
|
|
5488
|
+
if (state.localJudgeProvider !== void 0 && state.localJudgeModel !== void 0) {
|
|
5489
|
+
const matchesLocal = runJudgeProvider?.provider === state.localJudgeProvider && runJudgeProvider.model === state.localJudgeModel;
|
|
5339
5490
|
if (!matchesLocal) {
|
|
5340
|
-
|
|
5491
|
+
if (hasBothPins) {
|
|
5492
|
+
throw new Error(
|
|
5493
|
+
`Calibration binding pins for ${benchmarkId} target the calibrated local judge ${state.localJudgeProvider}/${state.localJudgeModel}, but the run judge is ${runJudgeProvider?.provider ?? "unset"}/${runJudgeProvider?.model ?? "unset"}; refusing to ignore explicit pins.`
|
|
5494
|
+
);
|
|
5495
|
+
}
|
|
5496
|
+
return void 0;
|
|
5341
5497
|
}
|
|
5342
5498
|
}
|
|
5499
|
+
if (!state.localJudgeConfigHash || !state.frontierJudgeConfigHash) {
|
|
5500
|
+
throw new Error(
|
|
5501
|
+
`Calibration state for ${benchmarkId} is missing bound judge configuration hashes; recalibrate before attaching it.`
|
|
5502
|
+
);
|
|
5503
|
+
}
|
|
5504
|
+
const resolvedRunJudgeConfigHash = hashCalibrationProviderConfig(runJudgeProvider);
|
|
5505
|
+
const hasCompleteLocalIdentity = state.localJudgeProvider !== void 0 && state.localJudgeModel !== void 0;
|
|
5506
|
+
if (!hasCompleteLocalIdentity && resolvedRunJudgeConfigHash !== state.localJudgeConfigHash) {
|
|
5507
|
+
if (hasBothPins) {
|
|
5508
|
+
throw new Error(
|
|
5509
|
+
`Calibration binding pins for ${benchmarkId} do not match the resolved run judge configuration; refusing to ignore explicit pins.`
|
|
5510
|
+
);
|
|
5511
|
+
}
|
|
5512
|
+
return void 0;
|
|
5513
|
+
}
|
|
5514
|
+
if (!calibrationBinding.calibrationLocalConfigSha256 || !calibrationBinding.calibrationFrontierConfigSha256) {
|
|
5515
|
+
throw new Error(
|
|
5516
|
+
`Calibration state exists for ${benchmarkId}; --calibration-local-config-sha256 and --calibration-frontier-config-sha256 are required to attach it.`
|
|
5517
|
+
);
|
|
5518
|
+
}
|
|
5519
|
+
if (calibrationBinding.calibrationLocalConfigSha256 !== state.localJudgeConfigHash || calibrationBinding.calibrationFrontierConfigSha256 !== state.frontierJudgeConfigHash) {
|
|
5520
|
+
throw new Error(`Calibration configuration hash mismatch for ${benchmarkId}; refusing to attach stale kappa.`);
|
|
5521
|
+
}
|
|
5522
|
+
if (resolvedRunJudgeConfigHash !== state.localJudgeConfigHash) {
|
|
5523
|
+
throw new Error(
|
|
5524
|
+
`Resolved run judge configuration hash mismatch for ${benchmarkId}; expected sha256:${state.localJudgeConfigHash}, got sha256:${resolvedRunJudgeConfigHash}. Refusing to attach stale kappa before benchmark dispatch.`
|
|
5525
|
+
);
|
|
5526
|
+
}
|
|
5527
|
+
return {
|
|
5528
|
+
kappa: state.kappa,
|
|
5529
|
+
sampleSize: state.sampleSize,
|
|
5530
|
+
threshold: state.threshold,
|
|
5531
|
+
warning: state.warning,
|
|
5532
|
+
...state.confidenceInterval ? { confidenceInterval: state.confidenceInterval } : {},
|
|
5533
|
+
...state.bootstrapSamples ? { bootstrapSamples: state.bootstrapSamples } : {},
|
|
5534
|
+
...state.answerSetHash ? { answerSetHash: state.answerSetHash } : {},
|
|
5535
|
+
...state.sourceResultId ? { sourceResultId: state.sourceResultId } : {},
|
|
5536
|
+
...state.sliceQuestionIds ? { sliceQuestionIds: state.sliceQuestionIds } : {},
|
|
5537
|
+
localJudgeConfigHash: state.localJudgeConfigHash,
|
|
5538
|
+
frontierJudgeConfigHash: state.frontierJudgeConfigHash
|
|
5539
|
+
};
|
|
5540
|
+
}
|
|
5541
|
+
function attachPreparedJudgeCalibration(result, judgeCalibration) {
|
|
5542
|
+
if (!judgeCalibration) return;
|
|
5343
5543
|
result.config.benchmarkOptions = {
|
|
5344
5544
|
...result.config.benchmarkOptions ?? {},
|
|
5345
|
-
judgeCalibration
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
|
|
5350
|
-
|
|
5351
|
-
|
|
5352
|
-
...state.answerSetHash ? { answerSetHash: state.answerSetHash } : {},
|
|
5353
|
-
...state.sourceResultId ? { sourceResultId: state.sourceResultId } : {},
|
|
5354
|
-
...state.sliceQuestionIds ? { sliceQuestionIds: state.sliceQuestionIds } : {}
|
|
5545
|
+
judgeCalibration
|
|
5546
|
+
};
|
|
5547
|
+
}
|
|
5548
|
+
function hashCalibrationProviderConfig(config) {
|
|
5549
|
+
const canonicalize = (value, key = "") => {
|
|
5550
|
+
if (typeof value === "string" && /(?:api.?key|authorization|token|secret)/i.test(key)) {
|
|
5551
|
+
return { secretSha256: createHash("sha256").update(value).digest("hex") };
|
|
5355
5552
|
}
|
|
5553
|
+
if (Array.isArray(value)) return value.map((item) => canonicalize(item));
|
|
5554
|
+
if (value && typeof value === "object") {
|
|
5555
|
+
return Object.fromEntries(Object.keys(value).sort().map((childKey) => [
|
|
5556
|
+
childKey,
|
|
5557
|
+
canonicalize(value[childKey], childKey)
|
|
5558
|
+
]));
|
|
5559
|
+
}
|
|
5560
|
+
return value;
|
|
5356
5561
|
};
|
|
5562
|
+
return createHash("sha256").update(JSON.stringify(canonicalize(config))).digest("hex");
|
|
5357
5563
|
}
|
|
5358
5564
|
function restoreOptionalEnv(key, previousValue) {
|
|
5359
5565
|
if (previousValue === void 0) {
|
|
@@ -12920,7 +13126,9 @@ export {
|
|
|
12920
13126
|
__benchDatasetTestHooks,
|
|
12921
13127
|
advanceOfflineBaseFilesForSuccessfulPush,
|
|
12922
13128
|
advanceOfflineLargeFileFailureCounts,
|
|
13129
|
+
attachPreparedJudgeCalibration,
|
|
12923
13130
|
buildBenchRuntimeProfileRequest,
|
|
13131
|
+
buildCalibrationFrontierJudgeConfig,
|
|
12924
13132
|
buildPackageBenchExecutionPlans,
|
|
12925
13133
|
buildQueryRecallRequest,
|
|
12926
13134
|
chunkOfflineChangesetApplyBatches,
|
|
@@ -12932,6 +13140,7 @@ export {
|
|
|
12932
13140
|
formatOfflineRequestForError,
|
|
12933
13141
|
getBenchUsageText,
|
|
12934
13142
|
hasFlag,
|
|
13143
|
+
hashCalibrationProviderConfig,
|
|
12935
13144
|
hydrateOfflineSnapshotContent,
|
|
12936
13145
|
isOfflineMissingContentDeferrablePath,
|
|
12937
13146
|
isOfflineSnapshotPostFallbackError,
|
|
@@ -12947,6 +13156,7 @@ export {
|
|
|
12947
13156
|
parseOfflineSyncRequestTimeoutMs,
|
|
12948
13157
|
parseTaxonomyResolveArgs,
|
|
12949
13158
|
parseTrainingExportArgs,
|
|
13159
|
+
preparePersistedJudgeCalibrationAttachment,
|
|
12950
13160
|
pushOfflineFileContent,
|
|
12951
13161
|
pushOfflineFileContentFromChunkReader,
|
|
12952
13162
|
renderQueryTextLines,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remnic/cli",
|
|
3
|
-
"version": "9.6.
|
|
3
|
+
"version": "9.6.26",
|
|
4
4
|
"description": "CLI for Remnic memory — init, query, doctor, daemon management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -26,23 +26,23 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"yaml": "^2.4.2",
|
|
29
|
-
"@remnic/
|
|
30
|
-
"@remnic/
|
|
31
|
-
"@remnic/
|
|
29
|
+
"@remnic/plugin-pi": "^9.6.26",
|
|
30
|
+
"@remnic/core": "^9.6.26",
|
|
31
|
+
"@remnic/server": "^9.6.26"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"@remnic/bench": "^9.6.
|
|
35
|
-
"@remnic/export-weclone": "^9.6.
|
|
36
|
-
"@remnic/import-weclone": "^9.6.
|
|
37
|
-
"@remnic/import-chatgpt": "^9.6.
|
|
38
|
-
"@remnic/import-claude": "^9.6.
|
|
39
|
-
"@remnic/import-gemini": "^9.6.
|
|
40
|
-
"@remnic/import-lossless-claw": "^9.6.
|
|
41
|
-
"@remnic/import-mem0": "^9.6.
|
|
42
|
-
"@remnic/import-supermemory": "^9.6.
|
|
43
|
-
"@remnic/connector-limitless": "^9.6.
|
|
44
|
-
"@remnic/connector-bee": "^9.6.
|
|
45
|
-
"@remnic/connector-omi": "^9.6.
|
|
34
|
+
"@remnic/bench": "^9.6.26",
|
|
35
|
+
"@remnic/export-weclone": "^9.6.26",
|
|
36
|
+
"@remnic/import-weclone": "^9.6.26",
|
|
37
|
+
"@remnic/import-chatgpt": "^9.6.26",
|
|
38
|
+
"@remnic/import-claude": "^9.6.26",
|
|
39
|
+
"@remnic/import-gemini": "^9.6.26",
|
|
40
|
+
"@remnic/import-lossless-claw": "^9.6.26",
|
|
41
|
+
"@remnic/import-mem0": "^9.6.26",
|
|
42
|
+
"@remnic/import-supermemory": "^9.6.26",
|
|
43
|
+
"@remnic/connector-limitless": "^9.6.26",
|
|
44
|
+
"@remnic/connector-bee": "^9.6.26",
|
|
45
|
+
"@remnic/connector-omi": "^9.6.26"
|
|
46
46
|
},
|
|
47
47
|
"peerDependenciesMeta": {
|
|
48
48
|
"@remnic/bench": {
|
|
@@ -85,18 +85,18 @@
|
|
|
85
85
|
"devDependencies": {
|
|
86
86
|
"tsup": "^8.5.1",
|
|
87
87
|
"typescript": "^5.9.3",
|
|
88
|
-
"@remnic/bench": "9.6.
|
|
89
|
-
"@remnic/export-weclone": "9.6.
|
|
90
|
-
"@remnic/import-weclone": "9.6.
|
|
91
|
-
"@remnic/import-chatgpt": "9.6.
|
|
92
|
-
"@remnic/import-
|
|
93
|
-
"@remnic/import-gemini": "9.6.
|
|
94
|
-
"@remnic/import-
|
|
95
|
-
"@remnic/connector-limitless": "9.6.
|
|
96
|
-
"@remnic/connector-bee": "9.6.
|
|
97
|
-
"@remnic/import-
|
|
98
|
-
"@remnic/
|
|
99
|
-
"@remnic/
|
|
88
|
+
"@remnic/bench": "9.6.26",
|
|
89
|
+
"@remnic/export-weclone": "9.6.26",
|
|
90
|
+
"@remnic/import-weclone": "9.6.26",
|
|
91
|
+
"@remnic/import-chatgpt": "9.6.26",
|
|
92
|
+
"@remnic/import-claude": "9.6.26",
|
|
93
|
+
"@remnic/import-gemini": "9.6.26",
|
|
94
|
+
"@remnic/import-mem0": "9.6.26",
|
|
95
|
+
"@remnic/connector-limitless": "9.6.26",
|
|
96
|
+
"@remnic/connector-bee": "9.6.26",
|
|
97
|
+
"@remnic/import-lossless-claw": "9.6.26",
|
|
98
|
+
"@remnic/connector-omi": "9.6.26",
|
|
99
|
+
"@remnic/import-supermemory": "9.6.26"
|
|
100
100
|
},
|
|
101
101
|
"license": "MIT",
|
|
102
102
|
"repository": {
|