@wendellresearch-ai/benchwarmers 0.2.0 → 0.2.2

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.
Files changed (103) hide show
  1. package/AGENTS.md +152 -147
  2. package/BENCHMARKS.md +262 -262
  3. package/GATEWAY.md +415 -272
  4. package/NOTICE +28 -28
  5. package/PRIVACY.md +46 -46
  6. package/README.md +408 -314
  7. package/SECURITY.md +83 -83
  8. package/TERMS.md +22 -22
  9. package/USAGE.md +186 -163
  10. package/VERSION +1 -1
  11. package/bin/benchwarmers.js +16 -74
  12. package/cli.py +674 -0
  13. package/examples/config/gateway.json +5 -5
  14. package/examples/config/model-roles.json +11 -11
  15. package/gateway.py +939 -755
  16. package/launcher.py +120 -0
  17. package/mcp_server.py +266 -266
  18. package/metrics/alerts.py +116 -116
  19. package/metrics/aliases.py +41 -41
  20. package/metrics/bench_collections.py +141 -141
  21. package/metrics/catalog.py +304 -295
  22. package/metrics/client.py +804 -394
  23. package/metrics/cliproxy.py +191 -191
  24. package/metrics/connect.py +691 -691
  25. package/metrics/cost.py +171 -152
  26. package/metrics/decide.py +227 -227
  27. package/metrics/discover.py +318 -318
  28. package/metrics/endpoints.py +436 -436
  29. package/metrics/formats.py +1021 -0
  30. package/metrics/guard.py +647 -592
  31. package/metrics/learn.py +234 -221
  32. package/metrics/ledger.py +148 -0
  33. package/metrics/litellm_hub.py +206 -206
  34. package/metrics/model_roles.py +94 -84
  35. package/metrics/offload.py +166 -166
  36. package/metrics/owui.py +205 -205
  37. package/metrics/pacing.py +248 -0
  38. package/metrics/paths.py +60 -60
  39. package/metrics/quota.py +383 -0
  40. package/metrics/route.py +581 -579
  41. package/metrics/scheduler.py +275 -275
  42. package/metrics/sources.py +167 -167
  43. package/metrics/wrong.py +144 -144
  44. package/package.json +69 -65
  45. package/perf/README.md +89 -89
  46. package/perf/run.py +284 -261
  47. package/scripts/auto_retire.py +367 -367
  48. package/scripts/check.py +113 -106
  49. package/scripts/check_deprecations.py +378 -378
  50. package/scripts/check_themes.py +103 -103
  51. package/scripts/init.py +124 -124
  52. package/scripts/list_served.py +78 -78
  53. package/scripts/notice.py +78 -78
  54. package/scripts/onboard.py +410 -331
  55. package/scripts/provider_tags.py +129 -129
  56. package/scripts/reprefix.py +136 -136
  57. package/scripts/sync_config.py +105 -105
  58. package/scripts/test_auth.py +255 -255
  59. package/scripts/test_cli.py +189 -0
  60. package/scripts/test_client.py +277 -233
  61. package/scripts/test_connect.py +222 -222
  62. package/scripts/test_first_run.py +180 -180
  63. package/scripts/test_formats.py +549 -0
  64. package/scripts/test_hubs.py +328 -328
  65. package/scripts/test_launcher.py +67 -0
  66. package/scripts/test_llm_log.py +85 -81
  67. package/scripts/test_mcp.py +178 -178
  68. package/scripts/test_merged.py +215 -214
  69. package/scripts/test_no_owui.py +291 -291
  70. package/scripts/test_owui.py +90 -90
  71. package/scripts/test_quota.py +334 -0
  72. package/scripts/test_serve_edit.py +453 -438
  73. package/scripts/test_server_json.py +79 -0
  74. package/scripts/test_verdict.py +102 -98
  75. package/scripts/test_vision.py +231 -228
  76. package/serve.py +3972 -3764
  77. package/suite/mine.py +154 -154
  78. package/suite/pace.py +145 -145
  79. package/suite/run.py +1046 -1042
  80. package/suite/seed.py +421 -421
  81. package/suite/tasks/claim-alias-unbound/fixtures/onboard.py +286 -286
  82. package/suite/tasks/claim-error-text-string/fixtures/decide.py +187 -187
  83. package/suite/tasks/claim-list-body/fixtures/gateway.py +235 -235
  84. package/suite/tasks/claim-member-nominated-twice/fixtures/gateway.py +284 -284
  85. package/suite/tasks/claim-nominee-uses-slot/fixtures/gateway.py +284 -284
  86. package/suite/tasks/claim-silent-exit/fixtures/gateway.py +235 -235
  87. package/suite/tasks/claim-sse-hang/fixtures/gateway.py +235 -235
  88. package/suite/tasks/claim-unknown-nominee-crash/fixtures/gateway.py +284 -284
  89. package/suite/tasks/rebench-matchms-809-bug/task.json +23 -23
  90. package/suite/tasks/rebench-matchms-809-control/task.json +27 -27
  91. package/suite/tasks/rebench-more-itertools-1028-bug/task.json +23 -23
  92. package/suite/tasks/rebench-more-itertools-1028-control/task.json +27 -27
  93. package/suite/tasks/rebench-narwhals-2864-bug/task.json +23 -23
  94. package/suite/tasks/rebench-narwhals-2864-control/task.json +27 -27
  95. package/suite/tasks/rebench-quantecon-py-769-bug/task.json +23 -23
  96. package/suite/tasks/rebench-quantecon-py-769-control/task.json +27 -27
  97. package/suite/tasks/rebench-scrapy-6867-bug/task.json +23 -23
  98. package/suite/tasks/rebench-scrapy-6867-control/task.json +27 -27
  99. package/ui/bench.css +430 -425
  100. package/ui/bench.js +1757 -1576
  101. package/ui/themes/dark.css +35 -35
  102. package/ui/themes/hardwood.css +52 -52
  103. package/ui/themes/rainforest.css +32 -32
package/scripts/check.py CHANGED
@@ -1,106 +1,113 @@
1
- """Every self-check and test file, in one command.
2
-
3
- python scripts/check.py # all of them
4
- python scripts/check.py --quick # without the llm-vs-built-in comparison (about two minutes)
5
- python scripts/check.py --fixtures # as CI runs them: on a copy of tests/fixtures/data
6
-
7
- RELEASE-PLAN.md Phase 6: one command a change is checked with, and what CI
8
- runs (.github/workflows/check.yml). Each check is its own process, so one that
9
- crashes cannot take the rest with it; the output of any that fail is shown.
10
- None of them call a model, reach past this machine, or write the install's
11
- data: they use temp copies, stubs and fake servers. Some READ the data folder
12
- (the collections, the registry, the alias history): this install's, or with
13
- --fixtures a temp copy of the repo's fixture folder, with llm's user folder
14
- pointed at an empty temp one, which is how they run on a clean machine.
15
-
16
- The export gate's full scan is not here: it fails by design until the public
17
- tree is clean (`python scripts/export_check.py`). Its pattern self-check is.
18
- """
19
-
20
- from __future__ import annotations
21
-
22
- import os
23
- import pathlib
24
- import shutil
25
- import subprocess
26
- import sys
27
- import tempfile
28
- import time
29
-
30
- ROOT = pathlib.Path(__file__).resolve().parent.parent
31
-
32
- # (script, arguments, slow)
33
- CHECKS = [
34
- ("metrics/locked.py", [], False),
35
- ("metrics/guard.py", [], False),
36
- ("metrics/endpoints.py", ["--selftest"], False),
37
- ("metrics/connect.py", ["--selftest"], False),
38
- ("metrics/client.py", ["--selftest"], False),
39
- ("metrics/bench_collections.py", [], False),
40
- ("metrics/learn.py", ["--selftest"], False),
41
- ("metrics/discover.py", ["--selftest"], False),
42
- ("metrics/test_decide.py", [], False),
43
- ("metrics/wrong.py", [], False),
44
- ("metrics/scheduler.py", ["--selftest"], False),
45
- ("scripts/auto_retire.py", [], False),
46
- ("scripts/onboard.py", ["--selftest"], False),
47
- ("scripts/export_check.py", ["--selftest"], False),
48
- ("scripts/notice.py", ["--check"], False),
49
- ("scripts/check_themes.py", [], False),
50
- ("scripts/test_owui.py", [], False),
51
- ("scripts/test_hubs.py", [], False),
52
- ("scripts/test_verdict.py", [], False),
53
- ("scripts/test_merged.py", [], False),
54
- ("scripts/test_vision.py", [], False),
55
- ("scripts/test_serve_edit.py", [], False),
56
- ("scripts/test_connect.py", [], False),
57
- ("scripts/test_auth.py", [], False),
58
- ("scripts/test_first_run.py", [], False),
59
- ("scripts/test_no_owui.py", [], False),
60
- ("scripts/test_llm_log.py", [], False),
61
- ("scripts/test_mcp.py", [], False),
62
- ("suite/test_score.py", [], False),
63
- ("suite/test_mine.py", [], False),
64
- ("suite/test_seed.py", [], False),
65
- ("suite/test_rebench.py", [], False),
66
- ("suite/test_pick.py", [], False),
67
- ("scripts/test_client.py", [], True), # runs the llm CLI against a fake server
68
- ]
69
-
70
-
71
- def main() -> int:
72
- sys.stdout.reconfigure(encoding="utf-8", errors="replace")
73
- quick = "--quick" in sys.argv
74
- env = {**os.environ, "PYTHONIOENCODING": "utf-8"}
75
- if "--fixtures" in sys.argv:
76
- tmp = pathlib.Path(tempfile.mkdtemp(prefix="bench-check-"))
77
- shutil.copytree(ROOT / "tests" / "fixtures" / "data", tmp / "data")
78
- (tmp / "llm").mkdir()
79
- env.update(BENCHWARMERS_HOME=str(tmp / "data"), LLM_USER_PATH=str(tmp / "llm"))
80
- print(f"data {tmp / 'data'} (a copy of tests/fixtures/data)")
81
- failed = []
82
- for script, args, slow in CHECKS:
83
- if quick and slow:
84
- print(f"skip {script} (--quick)")
85
- continue
86
- if not (ROOT / script).exists(): # the export gate stays in the private repo
87
- print(f"skip {script} (not in this checkout)")
88
- continue
89
- started = time.monotonic()
90
- try:
91
- done = subprocess.run([sys.executable, script, *args], cwd=ROOT, capture_output=True,
92
- text=True, encoding="utf-8", errors="replace", timeout=900, env=env)
93
- ok, out = done.returncode == 0, (done.stdout + done.stderr).strip()
94
- except subprocess.TimeoutExpired:
95
- ok, out = False, "no result in 900 s"
96
- print(f"{'ok ' if ok else 'FAIL '} {script} ({time.monotonic() - started:.0f}s)")
97
- if not ok:
98
- failed.append(script)
99
- # 40: test_client's whole report, so a CI log names the failing scenario.
100
- print("\n".join(" " + line for line in out.splitlines()[-40:]))
101
- print(f"\n{len(failed)} failed: {', '.join(failed)}" if failed else "\nall checks pass")
102
- return 1 if failed else 0
103
-
104
-
105
- if __name__ == "__main__":
106
- sys.exit(main())
1
+ """Every self-check and test file, in one command.
2
+
3
+ python scripts/check.py # all of them
4
+ python scripts/check.py --quick # without the llm-vs-built-in comparison (about two minutes)
5
+ python scripts/check.py --fixtures # as CI runs them: on a copy of tests/fixtures/data
6
+
7
+ RELEASE-PLAN.md Phase 6: one command a change is checked with, and what CI
8
+ runs (.github/workflows/check.yml). Each check is its own process, so one that
9
+ crashes cannot take the rest with it; the output of any that fail is shown.
10
+ None of them call a model, reach past this machine, or write the install's
11
+ data: they use temp copies, stubs and fake servers. Some READ the data folder
12
+ (the collections, the registry, the alias history): this install's, or with
13
+ --fixtures a temp copy of the repo's fixture folder, with llm's user folder
14
+ pointed at an empty temp one, which is how they run on a clean machine.
15
+
16
+ The export gate's full scan is not here: it fails by design until the public
17
+ tree is clean (`python scripts/export_check.py`). Its pattern self-check is.
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ import os
23
+ import pathlib
24
+ import shutil
25
+ import subprocess
26
+ import sys
27
+ import tempfile
28
+ import time
29
+
30
+ ROOT = pathlib.Path(__file__).resolve().parent.parent
31
+
32
+ # (script, arguments, slow)
33
+ CHECKS = [
34
+ ("metrics/locked.py", [], False),
35
+ ("metrics/guard.py", [], False),
36
+ ("metrics/endpoints.py", ["--selftest"], False),
37
+ ("metrics/connect.py", ["--selftest"], False),
38
+ ("metrics/client.py", ["--selftest"], False),
39
+ ("metrics/bench_collections.py", [], False),
40
+ ("metrics/learn.py", ["--selftest"], False),
41
+ ("metrics/quota.py", ["--selftest"], False),
42
+ ("metrics/discover.py", ["--selftest"], False),
43
+ ("metrics/test_decide.py", [], False),
44
+ ("metrics/wrong.py", [], False),
45
+ ("metrics/scheduler.py", ["--selftest"], False),
46
+ ("deploy/container.py", ["--selftest"], False),
47
+ ("scripts/auto_retire.py", [], False),
48
+ ("scripts/onboard.py", ["--selftest"], False),
49
+ ("scripts/export_check.py", ["--selftest"], False),
50
+ ("scripts/notice.py", ["--check"], False),
51
+ ("scripts/check_themes.py", [], False),
52
+ ("scripts/test_owui.py", [], False),
53
+ ("scripts/test_hubs.py", [], False),
54
+ ("scripts/test_verdict.py", [], False),
55
+ ("scripts/test_merged.py", [], False),
56
+ ("scripts/test_vision.py", [], False),
57
+ ("scripts/test_formats.py", [], False),
58
+ ("scripts/test_serve_edit.py", [], False),
59
+ ("scripts/test_connect.py", [], False),
60
+ ("scripts/test_auth.py", [], False),
61
+ ("scripts/test_first_run.py", [], False),
62
+ ("scripts/test_no_owui.py", [], False),
63
+ ("scripts/test_llm_log.py", [], False),
64
+ ("scripts/test_mcp.py", [], False),
65
+ ("scripts/test_cli.py", [], False),
66
+ ("scripts/test_launcher.py", [], False),
67
+ ("scripts/test_server_json.py", [], False),
68
+ ("scripts/test_quota.py", [], False),
69
+ ("suite/test_score.py", [], False),
70
+ ("suite/test_mine.py", [], False),
71
+ ("suite/test_seed.py", [], False),
72
+ ("suite/test_rebench.py", [], False),
73
+ ("suite/test_pick.py", [], False),
74
+ ("scripts/test_client.py", [], True), # runs the llm CLI against a fake server
75
+ ]
76
+
77
+
78
+ def main() -> int:
79
+ sys.stdout.reconfigure(encoding="utf-8", errors="replace")
80
+ quick = "--quick" in sys.argv
81
+ env = {**os.environ, "PYTHONIOENCODING": "utf-8"}
82
+ if "--fixtures" in sys.argv:
83
+ tmp = pathlib.Path(tempfile.mkdtemp(prefix="bench-check-"))
84
+ shutil.copytree(ROOT / "tests" / "fixtures" / "data", tmp / "data")
85
+ (tmp / "llm").mkdir()
86
+ env.update(BENCHWARMERS_HOME=str(tmp / "data"), LLM_USER_PATH=str(tmp / "llm"))
87
+ print(f"data {tmp / 'data'} (a copy of tests/fixtures/data)")
88
+ failed = []
89
+ for script, args, slow in CHECKS:
90
+ if quick and slow:
91
+ print(f"skip {script} (--quick)")
92
+ continue
93
+ if not (ROOT / script).exists(): # the export gate stays in the private repo
94
+ print(f"skip {script} (not in this checkout)")
95
+ continue
96
+ started = time.monotonic()
97
+ try:
98
+ done = subprocess.run([sys.executable, script, *args], cwd=ROOT, capture_output=True,
99
+ text=True, encoding="utf-8", errors="replace", timeout=900, env=env)
100
+ ok, out = done.returncode == 0, (done.stdout + done.stderr).strip()
101
+ except subprocess.TimeoutExpired:
102
+ ok, out = False, "no result in 900 s"
103
+ print(f"{'ok ' if ok else 'FAIL '} {script} ({time.monotonic() - started:.0f}s)")
104
+ if not ok:
105
+ failed.append(script)
106
+ # 40: test_client's whole report, so a CI log names the failing scenario.
107
+ print("\n".join(" " + line for line in out.splitlines()[-40:]))
108
+ print(f"\n{len(failed)} failed: {', '.join(failed)}" if failed else "\nall checks pass")
109
+ return 1 if failed else 0
110
+
111
+
112
+ if __name__ == "__main__":
113
+ sys.exit(main())