@wendellresearch-ai/benchwarmers 0.1.1 → 0.2.1

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 (96) hide show
  1. package/AGENTS.md +147 -147
  2. package/BENCHMARKS.md +262 -262
  3. package/GATEWAY.md +272 -271
  4. package/NOTICE +28 -28
  5. package/PRIVACY.md +46 -46
  6. package/README.md +368 -275
  7. package/SECURITY.md +83 -83
  8. package/TERMS.md +22 -22
  9. package/USAGE.md +170 -155
  10. package/VERSION +1 -1
  11. package/bin/benchwarmers.js +16 -72
  12. package/cli.py +666 -0
  13. package/examples/config/gateway.json +5 -5
  14. package/examples/config/model-roles.json +11 -11
  15. package/gateway.py +755 -712
  16. package/launcher.py +120 -0
  17. package/mcp_server.py +266 -0
  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 +295 -295
  22. package/metrics/client.py +394 -373
  23. package/metrics/cliproxy.py +191 -191
  24. package/metrics/connect.py +691 -691
  25. package/metrics/cost.py +152 -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/guard.py +617 -592
  30. package/metrics/learn.py +221 -221
  31. package/metrics/litellm_hub.py +206 -206
  32. package/metrics/model_roles.py +84 -84
  33. package/metrics/offload.py +166 -166
  34. package/metrics/owui.py +205 -205
  35. package/metrics/paths.py +60 -60
  36. package/metrics/route.py +579 -574
  37. package/metrics/scheduler.py +275 -275
  38. package/metrics/sources.py +167 -167
  39. package/metrics/wrong.py +144 -144
  40. package/package.json +68 -64
  41. package/perf/README.md +89 -89
  42. package/perf/run.py +261 -261
  43. package/scripts/auto_retire.py +367 -367
  44. package/scripts/check.py +108 -104
  45. package/scripts/check_deprecations.py +378 -378
  46. package/scripts/check_themes.py +103 -103
  47. package/scripts/init.py +124 -124
  48. package/scripts/list_served.py +78 -78
  49. package/scripts/notice.py +78 -78
  50. package/scripts/onboard.py +401 -331
  51. package/scripts/provider_tags.py +129 -129
  52. package/scripts/reprefix.py +136 -136
  53. package/scripts/sync_config.py +105 -105
  54. package/scripts/test_auth.py +255 -255
  55. package/scripts/test_cli.py +189 -0
  56. package/scripts/test_client.py +233 -233
  57. package/scripts/test_connect.py +222 -222
  58. package/scripts/test_first_run.py +180 -180
  59. package/scripts/test_hubs.py +328 -328
  60. package/scripts/test_launcher.py +67 -0
  61. package/scripts/test_llm_log.py +85 -0
  62. package/scripts/test_mcp.py +178 -0
  63. package/scripts/test_merged.py +214 -193
  64. package/scripts/test_no_owui.py +291 -291
  65. package/scripts/test_owui.py +90 -90
  66. package/scripts/test_serve_edit.py +448 -386
  67. package/scripts/test_verdict.py +98 -98
  68. package/scripts/test_vision.py +228 -228
  69. package/serve.py +3904 -3662
  70. package/suite/mine.py +154 -154
  71. package/suite/pace.py +145 -145
  72. package/suite/run.py +1046 -1040
  73. package/suite/seed.py +421 -421
  74. package/suite/tasks/claim-alias-unbound/fixtures/onboard.py +286 -286
  75. package/suite/tasks/claim-error-text-string/fixtures/decide.py +187 -187
  76. package/suite/tasks/claim-list-body/fixtures/gateway.py +235 -235
  77. package/suite/tasks/claim-member-nominated-twice/fixtures/gateway.py +284 -284
  78. package/suite/tasks/claim-nominee-uses-slot/fixtures/gateway.py +284 -284
  79. package/suite/tasks/claim-silent-exit/fixtures/gateway.py +235 -235
  80. package/suite/tasks/claim-sse-hang/fixtures/gateway.py +235 -235
  81. package/suite/tasks/claim-unknown-nominee-crash/fixtures/gateway.py +284 -284
  82. package/suite/tasks/rebench-matchms-809-bug/task.json +23 -23
  83. package/suite/tasks/rebench-matchms-809-control/task.json +27 -27
  84. package/suite/tasks/rebench-more-itertools-1028-bug/task.json +23 -23
  85. package/suite/tasks/rebench-more-itertools-1028-control/task.json +27 -27
  86. package/suite/tasks/rebench-narwhals-2864-bug/task.json +23 -23
  87. package/suite/tasks/rebench-narwhals-2864-control/task.json +27 -27
  88. package/suite/tasks/rebench-quantecon-py-769-bug/task.json +23 -23
  89. package/suite/tasks/rebench-quantecon-py-769-control/task.json +27 -27
  90. package/suite/tasks/rebench-scrapy-6867-bug/task.json +23 -23
  91. package/suite/tasks/rebench-scrapy-6867-control/task.json +27 -27
  92. package/ui/bench.css +430 -424
  93. package/ui/bench.js +1756 -1555
  94. package/ui/themes/dark.css +35 -35
  95. package/ui/themes/hardwood.css +52 -52
  96. package/ui/themes/rainforest.css +32 -32
package/scripts/check.py CHANGED
@@ -1,104 +1,108 @@
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
- ("suite/test_score.py", [], False),
61
- ("suite/test_mine.py", [], False),
62
- ("suite/test_seed.py", [], False),
63
- ("suite/test_rebench.py", [], False),
64
- ("suite/test_pick.py", [], False),
65
- ("scripts/test_client.py", [], True), # runs the llm CLI against a fake server
66
- ]
67
-
68
-
69
- def main() -> int:
70
- sys.stdout.reconfigure(encoding="utf-8", errors="replace")
71
- quick = "--quick" in sys.argv
72
- env = {**os.environ, "PYTHONIOENCODING": "utf-8"}
73
- if "--fixtures" in sys.argv:
74
- tmp = pathlib.Path(tempfile.mkdtemp(prefix="bench-check-"))
75
- shutil.copytree(ROOT / "tests" / "fixtures" / "data", tmp / "data")
76
- (tmp / "llm").mkdir()
77
- env.update(BENCHWARMERS_HOME=str(tmp / "data"), LLM_USER_PATH=str(tmp / "llm"))
78
- print(f"data {tmp / 'data'} (a copy of tests/fixtures/data)")
79
- failed = []
80
- for script, args, slow in CHECKS:
81
- if quick and slow:
82
- print(f"skip {script} (--quick)")
83
- continue
84
- if not (ROOT / script).exists(): # the export gate stays in the private repo
85
- print(f"skip {script} (not in this checkout)")
86
- continue
87
- started = time.monotonic()
88
- try:
89
- done = subprocess.run([sys.executable, script, *args], cwd=ROOT, capture_output=True,
90
- text=True, encoding="utf-8", errors="replace", timeout=900, env=env)
91
- ok, out = done.returncode == 0, (done.stdout + done.stderr).strip()
92
- except subprocess.TimeoutExpired:
93
- ok, out = False, "no result in 900 s"
94
- print(f"{'ok ' if ok else 'FAIL '} {script} ({time.monotonic() - started:.0f}s)")
95
- if not ok:
96
- failed.append(script)
97
- # 40: test_client's whole report, so a CI log names the failing scenario.
98
- print("\n".join(" " + line for line in out.splitlines()[-40:]))
99
- print(f"\n{len(failed)} failed: {', '.join(failed)}" if failed else "\nall checks pass")
100
- return 1 if failed else 0
101
-
102
-
103
- if __name__ == "__main__":
104
- 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/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
+ ("scripts/test_cli.py", [], False),
63
+ ("scripts/test_launcher.py", [], False),
64
+ ("suite/test_score.py", [], False),
65
+ ("suite/test_mine.py", [], False),
66
+ ("suite/test_seed.py", [], False),
67
+ ("suite/test_rebench.py", [], False),
68
+ ("suite/test_pick.py", [], False),
69
+ ("scripts/test_client.py", [], True), # runs the llm CLI against a fake server
70
+ ]
71
+
72
+
73
+ def main() -> int:
74
+ sys.stdout.reconfigure(encoding="utf-8", errors="replace")
75
+ quick = "--quick" in sys.argv
76
+ env = {**os.environ, "PYTHONIOENCODING": "utf-8"}
77
+ if "--fixtures" in sys.argv:
78
+ tmp = pathlib.Path(tempfile.mkdtemp(prefix="bench-check-"))
79
+ shutil.copytree(ROOT / "tests" / "fixtures" / "data", tmp / "data")
80
+ (tmp / "llm").mkdir()
81
+ env.update(BENCHWARMERS_HOME=str(tmp / "data"), LLM_USER_PATH=str(tmp / "llm"))
82
+ print(f"data {tmp / 'data'} (a copy of tests/fixtures/data)")
83
+ failed = []
84
+ for script, args, slow in CHECKS:
85
+ if quick and slow:
86
+ print(f"skip {script} (--quick)")
87
+ continue
88
+ if not (ROOT / script).exists(): # the export gate stays in the private repo
89
+ print(f"skip {script} (not in this checkout)")
90
+ continue
91
+ started = time.monotonic()
92
+ try:
93
+ done = subprocess.run([sys.executable, script, *args], cwd=ROOT, capture_output=True,
94
+ text=True, encoding="utf-8", errors="replace", timeout=900, env=env)
95
+ ok, out = done.returncode == 0, (done.stdout + done.stderr).strip()
96
+ except subprocess.TimeoutExpired:
97
+ ok, out = False, "no result in 900 s"
98
+ print(f"{'ok ' if ok else 'FAIL '} {script} ({time.monotonic() - started:.0f}s)")
99
+ if not ok:
100
+ failed.append(script)
101
+ # 40: test_client's whole report, so a CI log names the failing scenario.
102
+ print("\n".join(" " + line for line in out.splitlines()[-40:]))
103
+ print(f"\n{len(failed)} failed: {', '.join(failed)}" if failed else "\nall checks pass")
104
+ return 1 if failed else 0
105
+
106
+
107
+ if __name__ == "__main__":
108
+ sys.exit(main())