@remnic/cli 9.3.701 → 9.3.702
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 +187 -3
- package/package.json +28 -28
package/dist/index.js
CHANGED
|
@@ -643,6 +643,7 @@ function readBenchOptionValue(argv, flag) {
|
|
|
643
643
|
}
|
|
644
644
|
var BENCH_VALUE_FLAGS = Object.freeze([
|
|
645
645
|
"--dataset-dir",
|
|
646
|
+
"--benchmark",
|
|
646
647
|
"--results-dir",
|
|
647
648
|
"--baselines-dir",
|
|
648
649
|
"--runtime-profile",
|
|
@@ -826,6 +827,18 @@ var BENCH_ACTION_FLAGS = {
|
|
|
826
827
|
value: ["--results-dir", "--target", "--output"],
|
|
827
828
|
boolean: ["--json", "--help", "-h"]
|
|
828
829
|
},
|
|
830
|
+
"judge-calibrate": {
|
|
831
|
+
value: [
|
|
832
|
+
"--results-dir",
|
|
833
|
+
"--benchmark",
|
|
834
|
+
"--local-lab-manifest",
|
|
835
|
+
"--judge-provider",
|
|
836
|
+
"--judge-model",
|
|
837
|
+
"--judge-base-url",
|
|
838
|
+
"--judge-api-key"
|
|
839
|
+
],
|
|
840
|
+
boolean: ["--json", "--help", "-h"]
|
|
841
|
+
},
|
|
829
842
|
published: {
|
|
830
843
|
value: PUBLISHED_VALUE_FLAGS,
|
|
831
844
|
boolean: PUBLISHED_BOOLEAN_FLAGS
|
|
@@ -915,7 +928,7 @@ function collectBenchmarks(argv) {
|
|
|
915
928
|
}
|
|
916
929
|
function parseBenchActionArgs(argv) {
|
|
917
930
|
const [first, ...rest] = argv;
|
|
918
|
-
const action = first === "list" || first === "run" || first === "datasets" || first === "runs" || first === "compare" || first === "ui" || first === "results" || first === "baseline" || first === "export" || first === "providers" || first === "publish" || first === "published" || first === "check" || first === "report" ? first : first === void 0 || first === "--help" || first === "-h" ? "help" : "run";
|
|
931
|
+
const action = first === "list" || first === "run" || first === "datasets" || first === "runs" || first === "compare" || first === "ui" || first === "results" || first === "baseline" || first === "export" || first === "providers" || first === "publish" || first === "published" || first === "judge-calibrate" || first === "check" || first === "report" ? first : first === void 0 || first === "--help" || first === "-h" ? "help" : "run";
|
|
919
932
|
return {
|
|
920
933
|
action,
|
|
921
934
|
args: action === "run" && action !== first ? argv : rest
|
|
@@ -3219,8 +3232,8 @@ async function loadTrainingExportCoreRuntime() {
|
|
|
3219
3232
|
return await import("@remnic/core");
|
|
3220
3233
|
}
|
|
3221
3234
|
function getBenchUsageText() {
|
|
3222
|
-
return `Usage: remnic bench <list|run|published|datasets|runs|compare|results|baseline|export|publish|ui|providers> [options] [benchmark...]
|
|
3223
|
-
remnic benchmark <list|run|published|datasets|runs|compare|results|baseline|export|publish|ui|providers|check|report> [options] [benchmark...]
|
|
3235
|
+
return `Usage: remnic bench <list|run|published|datasets|runs|compare|results|baseline|export|publish|ui|providers|judge-calibrate> [options] [benchmark...]
|
|
3236
|
+
remnic benchmark <list|run|published|datasets|runs|compare|results|baseline|export|publish|ui|providers|judge-calibrate|check|report> [options] [benchmark...]
|
|
3224
3237
|
|
|
3225
3238
|
Commands:
|
|
3226
3239
|
list List published benchmark packs
|
|
@@ -3248,6 +3261,11 @@ Commands:
|
|
|
3248
3261
|
Generate the Remnic.ai benchmark feed from stored runs
|
|
3249
3262
|
ui Launch the local benchmark overview UI
|
|
3250
3263
|
providers discover Auto-detect available local provider backends
|
|
3264
|
+
judge-calibrate --benchmark <id> --local-lab-manifest <path> --judge-provider <p> --judge-model <m>
|
|
3265
|
+
Cross-tier judge calibration (issue #1573): runs the
|
|
3266
|
+
local + frontier judges over a benchmark's cached
|
|
3267
|
+
answers, reports Cohen's kappa, and persists it so
|
|
3268
|
+
subsequent local artifacts carry the kappa + warning.
|
|
3251
3269
|
check Legacy latency regression gate (compatibility)
|
|
3252
3270
|
report Legacy latency report generator (compatibility)
|
|
3253
3271
|
procedural-ablation --out <path> [--fixture <path>]
|
|
@@ -4425,6 +4443,144 @@ async function discoverBenchProviders(parsed) {
|
|
|
4425
4443
|
}
|
|
4426
4444
|
}
|
|
4427
4445
|
}
|
|
4446
|
+
async function calibrateBenchJudges(parsed, rawArgs) {
|
|
4447
|
+
const benchmarkId = readBenchOptionValue(rawArgs, "--benchmark") ?? parsed.benchmarks[0];
|
|
4448
|
+
if (!benchmarkId) {
|
|
4449
|
+
console.error(
|
|
4450
|
+
"ERROR: judge-calibrate requires a benchmark. Usage: remnic bench judge-calibrate --benchmark <id> [--local-lab-manifest <path>] [--judge-provider <p> --judge-model <m>] [--results-dir <path>] [--json]"
|
|
4451
|
+
);
|
|
4452
|
+
process.exit(1);
|
|
4453
|
+
}
|
|
4454
|
+
const knownBenchmarkIds = await resolveKnownBenchmarkIds();
|
|
4455
|
+
if (!knownBenchmarkIds.has(benchmarkId)) {
|
|
4456
|
+
console.error(
|
|
4457
|
+
`ERROR: unknown benchmark "${benchmarkId}". Known: ${[...knownBenchmarkIds].sort().join(", ")}.`
|
|
4458
|
+
);
|
|
4459
|
+
process.exit(1);
|
|
4460
|
+
}
|
|
4461
|
+
const manifestPath = parsed.localLabManifestPath;
|
|
4462
|
+
if (!manifestPath) {
|
|
4463
|
+
console.error(
|
|
4464
|
+
"ERROR: judge-calibrate requires --local-lab-manifest <path> (the Tier L judge source). Provide a local-lab manifest whose judge role names the local model."
|
|
4465
|
+
);
|
|
4466
|
+
process.exit(1);
|
|
4467
|
+
}
|
|
4468
|
+
if (!parsed.judgeProvider || !parsed.judgeModel) {
|
|
4469
|
+
console.error(
|
|
4470
|
+
"ERROR: judge-calibrate requires --judge-provider <p> and --judge-model <m> (the Tier F gold-standard judge)."
|
|
4471
|
+
);
|
|
4472
|
+
process.exit(1);
|
|
4473
|
+
}
|
|
4474
|
+
const bench = await loadBenchModule();
|
|
4475
|
+
const resultsDir = expandTilde(
|
|
4476
|
+
parsed.resultsDir ?? path11.join(resolveHomeDir(), ".remnic", "bench", "results")
|
|
4477
|
+
);
|
|
4478
|
+
const stored = await bench.listBenchmarkResults(resultsDir);
|
|
4479
|
+
const allForBenchmark = stored.filter((entry) => entry.benchmark === benchmarkId);
|
|
4480
|
+
const candidates = allForBenchmark.filter((entry) => entry.mode === "full").sort((a, b) => {
|
|
4481
|
+
if (a.timestamp !== b.timestamp) {
|
|
4482
|
+
return a.timestamp < b.timestamp ? 1 : -1;
|
|
4483
|
+
}
|
|
4484
|
+
return a.id < b.id ? 1 : a.id > b.id ? -1 : 0;
|
|
4485
|
+
});
|
|
4486
|
+
const latest = candidates[0];
|
|
4487
|
+
if (!latest) {
|
|
4488
|
+
const quickCount = allForBenchmark.filter((entry) => entry.mode === "quick").length;
|
|
4489
|
+
console.error(
|
|
4490
|
+
quickCount > 0 ? `ERROR: no full stored results for "${benchmarkId}" in ${resultsDir} (found ${quickCount} quick run(s); a 1-task quick sample cannot calibrate the judge). Run a full benchmark first (remnic bench run ${benchmarkId}).` : `ERROR: no stored benchmark results for "${benchmarkId}" in ${resultsDir}. Run the benchmark first (remnic bench run ${benchmarkId}) so cached answers exist to calibrate against.`
|
|
4491
|
+
);
|
|
4492
|
+
process.exit(1);
|
|
4493
|
+
}
|
|
4494
|
+
let loaded = await bench.loadBenchmarkResult(latest.path);
|
|
4495
|
+
if (loaded.meta.status === "partial") {
|
|
4496
|
+
for (const candidate of candidates.slice(1)) {
|
|
4497
|
+
const candidateResult = await bench.loadBenchmarkResult(candidate.path);
|
|
4498
|
+
if (candidateResult.meta.status !== "partial") {
|
|
4499
|
+
loaded = candidateResult;
|
|
4500
|
+
break;
|
|
4501
|
+
}
|
|
4502
|
+
}
|
|
4503
|
+
}
|
|
4504
|
+
const uniqueTaskIds = new Set(loaded.results.tasks.map((task) => task.taskId));
|
|
4505
|
+
const sourceTaskCount = uniqueTaskIds.size;
|
|
4506
|
+
if (sourceTaskCount < bench.MIN_CALIBRATION_SOURCE_TASKS) {
|
|
4507
|
+
console.error(
|
|
4508
|
+
`ERROR: stored result for "${benchmarkId}" has only ${sourceTaskCount} task(s) \u2014 too few for a meaningful calibration (minimum ${bench.MIN_CALIBRATION_SOURCE_TASKS}). Run a full uncapped benchmark first (remnic bench run ${benchmarkId}).`
|
|
4509
|
+
);
|
|
4510
|
+
process.exit(1);
|
|
4511
|
+
}
|
|
4512
|
+
const answers = loaded.results.tasks.map((task) => ({
|
|
4513
|
+
questionId: task.taskId,
|
|
4514
|
+
question: task.question,
|
|
4515
|
+
predicted: task.actual,
|
|
4516
|
+
expected: task.expected
|
|
4517
|
+
}));
|
|
4518
|
+
const manifest = await bench.loadLocalLabManifest(expandTilde(manifestPath));
|
|
4519
|
+
const resolvedProfile = bench.resolveLocalLabProfile(manifest);
|
|
4520
|
+
const localJudgeConfig = resolvedProfile.judge.providerConfig;
|
|
4521
|
+
const localJudge = bench.createProviderBackedJudge(localJudgeConfig);
|
|
4522
|
+
const frontierJudge = bench.createProviderBackedJudge({
|
|
4523
|
+
provider: parsed.judgeProvider,
|
|
4524
|
+
model: parsed.judgeModel,
|
|
4525
|
+
...parsed.judgeBaseUrl ? { baseUrl: parsed.judgeBaseUrl } : {},
|
|
4526
|
+
...parsed.judgeApiKey ? { apiKey: parsed.judgeApiKey } : {}
|
|
4527
|
+
});
|
|
4528
|
+
const result = await bench.runJudgeCalibration({
|
|
4529
|
+
benchmarkId,
|
|
4530
|
+
localJudge,
|
|
4531
|
+
frontierJudge,
|
|
4532
|
+
answers
|
|
4533
|
+
});
|
|
4534
|
+
const calibrationDir = path11.join(resolveHomeDir(), ".remnic", "bench", "calibration");
|
|
4535
|
+
const calibrationIdentities = {
|
|
4536
|
+
localJudgeProvider: String(localJudgeConfig.provider),
|
|
4537
|
+
localJudgeModel: String(localJudgeConfig.model),
|
|
4538
|
+
frontierJudgeProvider: parsed.judgeProvider,
|
|
4539
|
+
frontierJudgeModel: parsed.judgeModel
|
|
4540
|
+
};
|
|
4541
|
+
const statePath = await bench.writeJudgeCalibrationState(result, calibrationDir, calibrationIdentities);
|
|
4542
|
+
const persisted = await bench.loadJudgeCalibrationState(benchmarkId, calibrationDir);
|
|
4543
|
+
if (!persisted || persisted.kappa !== result.kappa || persisted.warning !== result.warning) {
|
|
4544
|
+
console.error(
|
|
4545
|
+
`ERROR: calibration state round-trip failed for ${benchmarkId} (wrote kappa ${result.kappa}, read back ${persisted ? persisted.kappa : "nothing"}). Re-run judge-calibrate.`
|
|
4546
|
+
);
|
|
4547
|
+
process.exit(1);
|
|
4548
|
+
}
|
|
4549
|
+
if (parsed.json) {
|
|
4550
|
+
console.log(
|
|
4551
|
+
JSON.stringify(
|
|
4552
|
+
{
|
|
4553
|
+
benchmarkId: result.benchmarkId,
|
|
4554
|
+
kappa: result.kappa,
|
|
4555
|
+
observedAgreement: result.observedAgreement,
|
|
4556
|
+
expectedAgreement: result.expectedAgreement,
|
|
4557
|
+
sampleSize: result.sampleSize,
|
|
4558
|
+
threshold: result.threshold,
|
|
4559
|
+
warning: result.warning,
|
|
4560
|
+
categories: result.categories,
|
|
4561
|
+
statePath
|
|
4562
|
+
},
|
|
4563
|
+
null,
|
|
4564
|
+
2
|
|
4565
|
+
)
|
|
4566
|
+
);
|
|
4567
|
+
return;
|
|
4568
|
+
}
|
|
4569
|
+
console.log(`Judge calibration: ${benchmarkId}`);
|
|
4570
|
+
console.log(` Cohen's kappa: ${result.kappa.toFixed(4)} (threshold ${result.threshold})`);
|
|
4571
|
+
console.log(` Sample size: ${result.sampleSize}`);
|
|
4572
|
+
console.log(` Observed agreement: ${result.observedAgreement.toFixed(4)}`);
|
|
4573
|
+
console.log(` Expected agreement: ${result.expectedAgreement.toFixed(4)}`);
|
|
4574
|
+
if (result.warning) {
|
|
4575
|
+
console.log(
|
|
4576
|
+
` WARNING: local judge unreliable for ${benchmarkId} (kappa ${result.kappa.toFixed(4)} < ${result.threshold}). Tier L numbers for this benchmark should not be trusted for regression until the judge improves.`
|
|
4577
|
+
);
|
|
4578
|
+
} else {
|
|
4579
|
+
console.log(` OK: local judge agrees with frontier above threshold.`);
|
|
4580
|
+
}
|
|
4581
|
+
console.log(` Calibration state written + verified (round-trip ok): ${statePath}`);
|
|
4582
|
+
console.log(` Subsequent local artifacts for ${benchmarkId} will carry kappa ${persisted.kappa.toFixed(4)}.`);
|
|
4583
|
+
}
|
|
4428
4584
|
async function publishBenchPackageResults(parsed) {
|
|
4429
4585
|
if (parsed.benchmarks.length > 0) {
|
|
4430
4586
|
console.error(
|
|
@@ -4889,6 +5045,7 @@ async function runBenchViaPackage(parsed, benchmarkId, runtimeProfile, benchStat
|
|
|
4889
5045
|
});
|
|
4890
5046
|
result.config.remnicConfig = plan.runtime.remnicConfig;
|
|
4891
5047
|
result.config.internalProvider = plan.runtime.internalProvider;
|
|
5048
|
+
await attachPersistedJudgeCalibration(benchModule, benchmarkId, result);
|
|
4892
5049
|
const writtenPath = await benchModule.writeBenchmarkResult(result, outputDir);
|
|
4893
5050
|
if (parsed.json) {
|
|
4894
5051
|
console.log(JSON.stringify(redactBenchResultForStdout(benchModule, result), null, 2));
|
|
@@ -4909,6 +5066,7 @@ async function runBenchViaPackage(parsed, benchmarkId, runtimeProfile, benchStat
|
|
|
4909
5066
|
err instanceof Error ? err.message : String(err),
|
|
4910
5067
|
parsed.quick ? "quick" : "full"
|
|
4911
5068
|
);
|
|
5069
|
+
await attachPersistedJudgeCalibration(benchModule, benchmarkId, partialResult);
|
|
4912
5070
|
try {
|
|
4913
5071
|
const partialPath = await benchModule.writeBenchmarkResult(partialResult, outputDir);
|
|
4914
5072
|
console.error(` Partial results (${partialTasks.length} tasks) written to ${partialPath}`);
|
|
@@ -4932,6 +5090,28 @@ async function runBenchViaPackage(parsed, benchmarkId, runtimeProfile, benchStat
|
|
|
4932
5090
|
}
|
|
4933
5091
|
}
|
|
4934
5092
|
}
|
|
5093
|
+
async function attachPersistedJudgeCalibration(benchModule, benchmarkId, result) {
|
|
5094
|
+
const calibrationDir = path11.join(resolveHomeDir(), ".remnic", "bench", "calibration");
|
|
5095
|
+
const state = await benchModule.loadJudgeCalibrationState?.(benchmarkId, calibrationDir);
|
|
5096
|
+
if (!state) return;
|
|
5097
|
+
if (state.localJudgeModel !== void 0 && state.frontierJudgeModel !== void 0) {
|
|
5098
|
+
const runJudgeProvider = result.config.judgeProvider?.provider;
|
|
5099
|
+
const runJudgeModel = result.config.judgeProvider?.model;
|
|
5100
|
+
const matchesLocal = runJudgeProvider === state.localJudgeProvider && runJudgeModel === state.localJudgeModel;
|
|
5101
|
+
if (!matchesLocal) {
|
|
5102
|
+
return;
|
|
5103
|
+
}
|
|
5104
|
+
}
|
|
5105
|
+
result.config.benchmarkOptions = {
|
|
5106
|
+
...result.config.benchmarkOptions ?? {},
|
|
5107
|
+
judgeCalibration: {
|
|
5108
|
+
kappa: state.kappa,
|
|
5109
|
+
sampleSize: state.sampleSize,
|
|
5110
|
+
threshold: state.threshold,
|
|
5111
|
+
warning: state.warning
|
|
5112
|
+
}
|
|
5113
|
+
};
|
|
5114
|
+
}
|
|
4935
5115
|
function restoreOptionalEnv(key, previousValue) {
|
|
4936
5116
|
if (previousValue === void 0) {
|
|
4937
5117
|
delete process.env[key];
|
|
@@ -9666,6 +9846,10 @@ async function cmdBench(rest) {
|
|
|
9666
9846
|
await exportBenchPackageResult(parsed);
|
|
9667
9847
|
return;
|
|
9668
9848
|
}
|
|
9849
|
+
if (parsed.action === "judge-calibrate") {
|
|
9850
|
+
await calibrateBenchJudges(parsed, benchAction.args);
|
|
9851
|
+
return;
|
|
9852
|
+
}
|
|
9669
9853
|
if (parsed.action === "datasets") {
|
|
9670
9854
|
await manageBenchDatasets(parsed);
|
|
9671
9855
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remnic/cli",
|
|
3
|
-
"version": "9.3.
|
|
3
|
+
"version": "9.3.702",
|
|
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/plugin-pi": "^9.3.
|
|
30
|
-
"@remnic/
|
|
31
|
-
"@remnic/
|
|
29
|
+
"@remnic/plugin-pi": "^9.3.702",
|
|
30
|
+
"@remnic/core": "^9.3.702",
|
|
31
|
+
"@remnic/server": "^9.3.702"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"@remnic/bench": "^9.3.
|
|
35
|
-
"@remnic/export-weclone": "^9.3.
|
|
36
|
-
"@remnic/import-weclone": "^9.3.
|
|
37
|
-
"@remnic/import-chatgpt": "^9.3.
|
|
38
|
-
"@remnic/import-claude": "^9.3.
|
|
39
|
-
"@remnic/import-gemini": "^9.3.
|
|
40
|
-
"@remnic/import-lossless-claw": "^9.3.
|
|
41
|
-
"@remnic/import-mem0": "^9.3.
|
|
42
|
-
"@remnic/import-supermemory": "^9.3.
|
|
43
|
-
"@remnic/connector-limitless": "^9.3.
|
|
44
|
-
"@remnic/connector-bee": "^9.3.
|
|
45
|
-
"@remnic/connector-omi": "^9.3.
|
|
34
|
+
"@remnic/bench": "^9.3.702",
|
|
35
|
+
"@remnic/export-weclone": "^9.3.702",
|
|
36
|
+
"@remnic/import-weclone": "^9.3.702",
|
|
37
|
+
"@remnic/import-chatgpt": "^9.3.702",
|
|
38
|
+
"@remnic/import-claude": "^9.3.702",
|
|
39
|
+
"@remnic/import-gemini": "^9.3.702",
|
|
40
|
+
"@remnic/import-lossless-claw": "^9.3.702",
|
|
41
|
+
"@remnic/import-mem0": "^9.3.702",
|
|
42
|
+
"@remnic/import-supermemory": "^9.3.702",
|
|
43
|
+
"@remnic/connector-limitless": "^9.3.702",
|
|
44
|
+
"@remnic/connector-bee": "^9.3.702",
|
|
45
|
+
"@remnic/connector-omi": "^9.3.702"
|
|
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.3.
|
|
89
|
-
"@remnic/export-weclone": "9.3.
|
|
90
|
-
"@remnic/import-weclone": "9.3.
|
|
91
|
-
"@remnic/import-chatgpt": "9.3.
|
|
92
|
-
"@remnic/import-
|
|
93
|
-
"@remnic/import-
|
|
94
|
-
"@remnic/import-
|
|
95
|
-
"@remnic/import-lossless-claw": "9.3.
|
|
96
|
-
"@remnic/import-supermemory": "9.3.
|
|
97
|
-
"@remnic/connector-omi": "9.3.
|
|
98
|
-
"@remnic/connector-
|
|
99
|
-
"@remnic/connector-
|
|
88
|
+
"@remnic/bench": "9.3.702",
|
|
89
|
+
"@remnic/export-weclone": "9.3.702",
|
|
90
|
+
"@remnic/import-weclone": "9.3.702",
|
|
91
|
+
"@remnic/import-chatgpt": "9.3.702",
|
|
92
|
+
"@remnic/import-claude": "9.3.702",
|
|
93
|
+
"@remnic/import-gemini": "9.3.702",
|
|
94
|
+
"@remnic/import-mem0": "9.3.702",
|
|
95
|
+
"@remnic/import-lossless-claw": "9.3.702",
|
|
96
|
+
"@remnic/import-supermemory": "9.3.702",
|
|
97
|
+
"@remnic/connector-omi": "9.3.702",
|
|
98
|
+
"@remnic/connector-limitless": "9.3.702",
|
|
99
|
+
"@remnic/connector-bee": "9.3.702"
|
|
100
100
|
},
|
|
101
101
|
"license": "MIT",
|
|
102
102
|
"repository": {
|