pi-smart-router 0.9.1 → 0.9.3
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 +107 -0
- package/package.json +8 -1
package/README.md
CHANGED
|
@@ -568,8 +568,57 @@ At runtime, `ClusterMatcher` prefers `routing_centroids` from the calibration bu
|
|
|
568
568
|
|
|
569
569
|
Below these thresholds the train path returns bootstrap centroids unchanged. The verify script reports `oats_refinement` metadata when refinement ran.
|
|
570
570
|
|
|
571
|
+
These guards match `DEFAULT_OATS_MIN_POSITIVE_SAMPLES` / `DEFAULT_OATS_MIN_NEGATIVE_SAMPLES` in `scripts/lib/oats-centroid-refinement.ts` and `MINIMUM_TRAINING_SAMPLES.routing_centroids` (10) in `scripts/calibration-aggregate.ts`. The same global floors appear under `minimum_training_samples` in [`config/routing-calibration.json.example`](config/routing-calibration.json.example) (`hydra_projection` 100, `triage_thresholds` 50, `p_success_weights` / `isotonic_calibrator` 30, `routing_centroids` 10).
|
|
572
|
+
|
|
571
573
|
See [routing-roadmap.md](docs/routing-roadmap.md) §2 P2 OATS and GitHub [#77](https://github.com/beettlle/pi-smart-router/issues/77).
|
|
572
574
|
|
|
575
|
+
### Privacy-safe label packs + calibration dry-run (SP-189–SP-191 / #102)
|
|
576
|
+
|
|
577
|
+
Offline **label packs** are feature-vector + binary-outcome JSONL (never prompt/message text). Schema: `scripts/lib/label-pack-schema.ts`. Provenance, pins, and field maps: [`tests/eval/corpus/label-packs/PROVENANCE.md`](tests/eval/corpus/label-packs/PROVENANCE.md).
|
|
578
|
+
|
|
579
|
+
**Regenerate packs (offline / no network for CI fixtures):**
|
|
580
|
+
|
|
581
|
+
```bash
|
|
582
|
+
# SWE-Gym verifier-style → pack
|
|
583
|
+
npm run routing:ingest-swe-gym -- \
|
|
584
|
+
--input tests/eval/corpus/label-packs/swe-gym/ci-fixture.jsonl \
|
|
585
|
+
--output /tmp/swe-gym-pack.jsonl
|
|
586
|
+
|
|
587
|
+
# FC-RewardBench preference / flat → pack
|
|
588
|
+
npm run routing:ingest-fc-rewardbench -- \
|
|
589
|
+
--input tests/eval/corpus/label-packs/fc-rewardbench/ci-fixture.jsonl \
|
|
590
|
+
--output /tmp/fc-rewardbench-pack.jsonl
|
|
591
|
+
|
|
592
|
+
# Optional weak TwinRouterBench tier proxy (exclude from holdout ECE)
|
|
593
|
+
npm run routing:ingest-twinrouterbench-weak -- \
|
|
594
|
+
--input tests/eval/corpus/label-packs/twinrouterbench-weak/ci-fixture.jsonl \
|
|
595
|
+
--output /tmp/trb-weak-pack.jsonl
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
**Calibration dry-run (holdout ECE):**
|
|
599
|
+
|
|
600
|
+
```bash
|
|
601
|
+
# CI fixtures (ingests packs in-memory; sample-starved → report-only)
|
|
602
|
+
npm run routing:calibration-dry-run
|
|
603
|
+
|
|
604
|
+
# Operator packs (schema-valid JSONL)
|
|
605
|
+
npm run routing:calibration-dry-run -- --packs /tmp/swe-gym-pack.jsonl /tmp/fc-rewardbench-pack.jsonl
|
|
606
|
+
|
|
607
|
+
# Soft ECE advisory fail (threshold 0.25 calibrated ECE; not a release-gate absolute)
|
|
608
|
+
npm run routing:calibration-dry-run -- --packs /tmp/swe-gym-pack.jsonl --enforce-soft-ece
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
Dry-run behavior:
|
|
612
|
+
|
|
613
|
+
| Condition | Result |
|
|
614
|
+
|-----------|--------|
|
|
615
|
+
| < 30 ECE-eligible rows | `SAMPLE_STARVED` report-only (exit 0); no soft pass/fail |
|
|
616
|
+
| ≥ 30 ECE-eligible rows | Fit logistic + isotonic; report `holdout_ece_raw` / `holdout_ece_calibrated` |
|
|
617
|
+
| Rows with `exclude_from_holdout_ece` | Counted separately; **never** enter holdout ECE metrics (weak TwinRouterBench) |
|
|
618
|
+
| Soft threshold | Advisory `0.25` calibrated ECE — **does not** change `config/release-gates.json` |
|
|
619
|
+
|
|
620
|
+
**#96 / `modernbert_k4` advisory:** when deciding whether to enable ModernBERT K=4 heads, use **pack holdout ECE / Top-1 error on verifier-grade packs** (SWE-Gym + FC-RewardBench), not fixture-only QR. Weak TwinRouterBench rows are warm-start only. This task does **not** flip `modernbert_k4` defaults.
|
|
621
|
+
|
|
573
622
|
### Operator tuning (frugality slider)
|
|
574
623
|
|
|
575
624
|
The multi-objective scoring weights control the cost-vs-quality tradeoff:
|
|
@@ -793,6 +842,10 @@ Contributors must run `npm run build` before publishing or consuming the library
|
|
|
793
842
|
| `npm run routing:train-calibration` | Train routing calibration artifact bundle |
|
|
794
843
|
| `npm run routing:train-p-success` | Train standalone `config/p-success-weights.json` (synthetic fixture by default) |
|
|
795
844
|
| `npm run routing:verify-calibration` | Verify calibration bundle against benchmark prompts |
|
|
845
|
+
| `npm run routing:calibration-dry-run` | Pack-fed isotonic dry-run: holdout ECE on label packs (CI fixtures by default) |
|
|
846
|
+
| `npm run routing:ingest-swe-gym` | Convert SWE-Gym verifier-style JSONL → privacy-safe label pack |
|
|
847
|
+
| `npm run routing:ingest-fc-rewardbench` | Convert FC-RewardBench JSONL → privacy-safe label pack |
|
|
848
|
+
| `npm run routing:ingest-twinrouterbench-weak` | Convert TwinRouterBench weak tier labels → pack (exclude from ECE) |
|
|
796
849
|
| `npm run routing:ingest-benchmarks` | Regenerate `config/benchmark-profiles.json` from leaderboard fixtures |
|
|
797
850
|
| `npm run routing:verify-benchmark-profiles` | CI smoke: assert checked-in profiles match fixture ingest |
|
|
798
851
|
| `npm run routing:eval-replay` | Counterfactual replay on eval trace fixtures |
|
|
@@ -801,6 +854,9 @@ Contributors must run `npm run build` before publishing or consuming the library
|
|
|
801
854
|
| `npm run routing:eval-harness:corpus-smoke` | Harness summary on TwinRouterBench CI corpus subset (`tests/eval/corpus/twinrouterbench`) |
|
|
802
855
|
| `npm run routing:assert-release-gates:corpus-report` | Soft-feed: assert corpus vs absolute gates with `--report-only` (exit 0; does not gate releases) |
|
|
803
856
|
| `npm run routing:ingest-twinrouterbench` | Convert TwinRouterBench `question_bank.jsonl` → CI subset / full corpus JSON |
|
|
857
|
+
| `npm run routing:ingest-llmrouterbench` | Convert LLMRouterBench BaselineRecord JSONL → static-track subset JSON |
|
|
858
|
+
| `npm run routing:llmrouterbench-regret` | Offline regret / CS report on vendored LLMRouterBench subset (optional; not PR CI) |
|
|
859
|
+
| `npm run routing:community-bench` | Privacy-safe community bench report (Track A TwinRouterBench + optional Track B/C) |
|
|
804
860
|
| `npm run benchmark:encoder` | Compare MiniLM vs Granite encoder latency on held-out agent turns |
|
|
805
861
|
|
|
806
862
|
### Offline eval harness (agent-native routing)
|
|
@@ -847,6 +903,57 @@ npm run routing:eval-replay
|
|
|
847
903
|
|
|
848
904
|
**Deferred:** RouterBench classic (outcome-matrix) smoke is out of scope for SP-188; prefer TwinRouterBench static track + dogfood for #95.
|
|
849
905
|
|
|
906
|
+
#### LLMRouterBench offline regret (SP-192 / SP-193)
|
|
907
|
+
|
|
908
|
+
Optional local / nightly report on the **pinned code/tool subset** — not part of PR CI (no full HF corpus download).
|
|
909
|
+
|
|
910
|
+
| Item | Location / command |
|
|
911
|
+
|------|--------------------|
|
|
912
|
+
| **Pinned upstream** | HF `NPULH/LLMRouterBench` `@0e5af1b84bf73437a01a1849c0f1d2468baa93fc` + git schema `@c77cb0506949d8f959e97967d2fefca0e8ff1b05` (MIT) |
|
|
913
|
+
| **CI subset** | `tests/eval/corpus/llmrouterbench/ci-subset.json` (≤20 synthetic offline records) |
|
|
914
|
+
| **Provenance / refresh** | `tests/eval/corpus/llmrouterbench/PROVENANCE.md` (quarterly pin refresh; re-run report after catalog/subset changes) |
|
|
915
|
+
| **Regenerate subset** | `npm run routing:ingest-llmrouterbench -- --input <jsonl> --output tests/eval/corpus/llmrouterbench/ci-subset.json --limit 20 --prefer-code-tool` |
|
|
916
|
+
| **Regret / CS report** | `npm run routing:llmrouterbench-regret` |
|
|
917
|
+
| **Community Track C** | `npm run routing:community-bench -- --llmrouterbench` (same vendored subset; optional) |
|
|
918
|
+
|
|
919
|
+
PR CI continues to smoke TwinRouterBench only (`routing:eval-harness:corpus-smoke`). Absolute `config/release-gates.json` thresholds are unchanged. See [Contribute a community bench report](#contribute-a-community-bench-report) for Track A + optional Track C sharing.
|
|
920
|
+
|
|
921
|
+
#### Contribute a community bench report
|
|
922
|
+
|
|
923
|
+
Share a privacy-safe setup fingerprint + Track A (TwinRouterBench) gate result with maintainers. No SMTP auto-send and no upload server — you copy artifacts yourself.
|
|
924
|
+
|
|
925
|
+
**Maintainer contact** (must match the CLI footer constant `COMMUNITY_BENCH_MAINTAINER_CONTACT`):
|
|
926
|
+
|
|
927
|
+
`https://github.com/beettlle/pi-smart-router/issues/new?labels=community-bench`
|
|
928
|
+
|
|
929
|
+
```bash
|
|
930
|
+
# Track A offline smoke (vendored TwinRouterBench corpus — no network)
|
|
931
|
+
npm run routing:community-bench -- \
|
|
932
|
+
--output /tmp/community-bench-report.json \
|
|
933
|
+
--email-file /tmp/community-bench-report.txt
|
|
934
|
+
|
|
935
|
+
# Optional Track C: offline LLMRouterBench regret/CS on the vendored subset (no full HF download)
|
|
936
|
+
npm run routing:community-bench -- \
|
|
937
|
+
--llmrouterbench \
|
|
938
|
+
--output /tmp/community-bench-report.json \
|
|
939
|
+
--email-file /tmp/community-bench-report.txt
|
|
940
|
+
```
|
|
941
|
+
|
|
942
|
+
**How to send:**
|
|
943
|
+
|
|
944
|
+
1. **Email `.txt`** — open `/tmp/community-bench-report.txt` (or your `--email-file` path). It includes a `Subject:` line, privacy blurb, fingerprint, Track A PASS/FAIL, and optional Track C metrics. Paste into your mail client; attach `community-bench-report.json` if useful. Do **not** expect the CLI to send mail.
|
|
945
|
+
2. **GitHub issue** — open the [maintainer contact](https://github.com/beettlle/pi-smart-router/issues/new?labels=community-bench) URL, or run with `--print-issue-body` and paste stdout into a new issue. Issues list: https://github.com/beettlle/pi-smart-router/issues
|
|
946
|
+
|
|
947
|
+
**Tracks:**
|
|
948
|
+
|
|
949
|
+
| Track | Corpus | When |
|
|
950
|
+
|-------|--------|------|
|
|
951
|
+
| **A (required)** | [TwinRouterBench CI corpus](#twinrouterbench-ci-corpus-sp-186--sp-187--sp-188) (`tests/eval/corpus/twinrouterbench`) | Always |
|
|
952
|
+
| **B (optional)** | Dogfood export (`--dogfood-export PATH`) | Skips with an explicit reason until [#95](https://github.com/beettlle/pi-smart-router/issues/95) adapter lands — never invents labels |
|
|
953
|
+
| **C (optional)** | [LLMRouterBench offline subset](#llmrouterbench-offline-regret-sp-192--sp-193) (`tests/eval/corpus/llmrouterbench`) | `--llmrouterbench` or `--full`; offline only |
|
|
954
|
+
|
|
955
|
+
PR CI does **not** download full TwinRouterBench / LLMRouterBench corpora. Absolute gate thresholds in `config/release-gates.json` are unchanged by this CLI.
|
|
956
|
+
|
|
850
957
|
Sample fixtures under `tests/eval/fixtures/twinrouterbench/` remain the small adapter unit-test inputs and are unchanged by corpus ingest.
|
|
851
958
|
|
|
852
959
|
Capability scores in `config/benchmark-profiles.json` are grounded from public leaderboard snapshots under `tests/fixtures/benchmark-leaderboards/` (and optional **recorded** live snapshots under `tests/fixtures/benchmark-leaderboards/recorded/`). Each artifact records provenance (`source_urls`, `scrape_date`, `catalog_freeze_date`) in its header.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-smart-router",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.3",
|
|
4
4
|
"description": "Auto-model router middleware for the pi.dev coding agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -67,12 +67,19 @@
|
|
|
67
67
|
"routing:ingest-benchmarks": "tsx scripts/ingest-benchmark-profiles.ts",
|
|
68
68
|
"routing:verify-benchmark-profiles": "vitest run tests/unit/ingest-benchmark-profiles.test.ts -t \"checked-in artifact matches fixture ingest\"",
|
|
69
69
|
"routing:verify-calibration": "bash -c 'if [[ \" $* \" == *\" --skip-embed \"* ]]; then vitest run tests/unit/train-routing-calibration.test.ts -t \"verifyRoutingCalibration passes|evaluates benchmark triage gates\"; else npm run build && tsx scripts/verify-routing-calibration.ts \"$@\"; fi' --",
|
|
70
|
+
"routing:calibration-dry-run": "tsx scripts/verify-routing-calibration.ts --dry-run-packs",
|
|
70
71
|
"routing:eval-replay": "tsx scripts/eval/counterfactual-replay.ts",
|
|
71
72
|
"routing:eval-harness": "tsx scripts/eval/run-harness.ts",
|
|
72
73
|
"routing:eval-harness:smoke": "tsx scripts/eval/run-harness.ts --summary-only",
|
|
73
74
|
"routing:eval-harness:corpus-smoke": "tsx scripts/eval/run-harness.ts --fixtures tests/eval/corpus/twinrouterbench --summary-only",
|
|
74
75
|
"routing:assert-release-gates:corpus-report": "tsx scripts/eval/assert-release-gates.ts --fixtures tests/eval/corpus/twinrouterbench --report-only",
|
|
76
|
+
"routing:community-bench": "tsx scripts/eval/community-bench.ts",
|
|
75
77
|
"routing:ingest-twinrouterbench": "tsx scripts/eval/ingest-twinrouterbench-corpus.ts",
|
|
78
|
+
"routing:ingest-llmrouterbench": "tsx scripts/eval/ingest-llmrouterbench-subset.ts",
|
|
79
|
+
"routing:llmrouterbench-regret": "tsx scripts/eval/llmrouterbench-regret-report.ts",
|
|
80
|
+
"routing:ingest-swe-gym": "tsx scripts/ingest-swe-gym-labels.ts",
|
|
81
|
+
"routing:ingest-fc-rewardbench": "tsx scripts/ingest-fc-rewardbench-labels.ts",
|
|
82
|
+
"routing:ingest-twinrouterbench-weak": "tsx scripts/ingest-twinrouterbench-weak-labels.ts",
|
|
76
83
|
"routing:capture-baseline": "tsx scripts/eval/capture-baseline.ts",
|
|
77
84
|
"routing:test-projection": "npm run build && node --experimental-strip-types scripts/test-hydra-projection.ts",
|
|
78
85
|
"benchmark:encoder": "tsx scripts/benchmark-encoder-latency.ts",
|