benchkit-cli 0.1.1__tar.gz → 0.2.0__tar.gz

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 (191) hide show
  1. {benchkit_cli-0.1.1/src/benchkit_cli.egg-info → benchkit_cli-0.2.0}/PKG-INFO +4 -1
  2. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/README.md +3 -0
  3. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/pyproject.toml +1 -1
  4. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/__init__.py +17 -1
  5. benchkit_cli-0.2.0/src/benchkit/benchmarks/cruxeval.py +380 -0
  6. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/downloads.py +11 -0
  7. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/evalplus.py +26 -4
  8. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/ruler_generator.py +47 -17
  9. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/datasets/README.md +14 -0
  10. benchkit_cli-0.2.0/src/benchkit/datasets/cruxeval.jsonl +800 -0
  11. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/executor.py +12 -2
  12. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0/src/benchkit_cli.egg-info}/PKG-INFO +4 -1
  13. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit_cli.egg-info/SOURCES.txt +3 -0
  14. benchkit_cli-0.2.0/tests/test_cruxeval.py +139 -0
  15. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_ruler.py +34 -0
  16. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/LICENSE +0 -0
  17. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/setup.cfg +0 -0
  18. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/__init__.py +0 -0
  19. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/_pi_proxy.py +0 -0
  20. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/answer_key_guard.ts +0 -0
  21. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/artifacts.py +0 -0
  22. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/aider_polyglot.py +0 -0
  23. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/arc.py +0 -0
  24. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/banking77.py +0 -0
  25. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/base.py +0 -0
  26. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/boolq.py +0 -0
  27. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/chartqa.py +0 -0
  28. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/code_verifier.py +0 -0
  29. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/git_surgery.py +0 -0
  30. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/gpqa.py +0 -0
  31. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/gsm8k.py +0 -0
  32. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/hellaswag.py +0 -0
  33. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/humaneval.py +0 -0
  34. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/ifeval.py +0 -0
  35. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/ifeval_instructions.py +0 -0
  36. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/mbpp.py +0 -0
  37. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/mc_arena.py +0 -0
  38. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/mcq.py +0 -0
  39. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/medfailbench.py +0 -0
  40. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/mmlu.py +0 -0
  41. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/mmlu_pro.py +0 -0
  42. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/mmvp.py +0 -0
  43. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/ocrbench.py +0 -0
  44. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/openbookqa.py +0 -0
  45. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/patcheval.py +0 -0
  46. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/piqa.py +0 -0
  47. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/ruler.py +0 -0
  48. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/sanity.py +0 -0
  49. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/treejs_arena.py +0 -0
  50. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/truthfulqa.py +0 -0
  51. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/utils.py +0 -0
  52. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/vision.py +0 -0
  53. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/vstar.py +0 -0
  54. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/winogrande.py +0 -0
  55. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/benchmarks/xstest.py +0 -0
  56. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/browser.py +0 -0
  57. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/catalog.py +0 -0
  58. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/cli.py +0 -0
  59. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/client.py +0 -0
  60. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/config.py +0 -0
  61. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/controls.py +0 -0
  62. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/datasets/MMLU_LICENSE.txt +0 -0
  63. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/datasets/arc_challenge.jsonl +0 -0
  64. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/datasets/banking77.jsonl +0 -0
  65. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/datasets/banking77_intents.json +0 -0
  66. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/datasets/boolq.jsonl +0 -0
  67. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/datasets/code_verifier.jsonl +0 -0
  68. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/datasets/gpqa_diamond.jsonl +0 -0
  69. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/datasets/gsm8k.jsonl +0 -0
  70. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/datasets/hellaswag.jsonl +0 -0
  71. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/datasets/humaneval.jsonl +0 -0
  72. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/datasets/ifeval.jsonl +0 -0
  73. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/datasets/mbpp.jsonl +0 -0
  74. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/datasets/mc_blocks_1_20_1.jsonl +0 -0
  75. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/datasets/medfailbench_hard30.jsonl +0 -0
  76. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/datasets/medfailbench_hard30.md +0 -0
  77. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/datasets/openbookqa.jsonl +0 -0
  78. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/datasets/piqa.jsonl +0 -0
  79. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/datasets/sanity_code.jsonl +0 -0
  80. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/datasets/truthfulqa.jsonl +0 -0
  81. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/datasets/winogrande.jsonl +0 -0
  82. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/datasets/xstest.csv +0 -0
  83. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/decision.py +0 -0
  84. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/demo.py +0 -0
  85. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/dockerfiles.py +0 -0
  86. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/engine.py +0 -0
  87. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/evaluation.py +0 -0
  88. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/events.py +0 -0
  89. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/git_surgery/backport-release-stack/setup.sh +0 -0
  90. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/git_surgery/backport-release-stack/verify.sh +0 -0
  91. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/git_surgery/bisect-the-regression/setup.sh +0 -0
  92. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/git_surgery/bisect-the-regression/verify.sh +0 -0
  93. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/git_surgery/rebase-conflict-chain/setup.sh +0 -0
  94. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/git_surgery/rebase-conflict-chain/verify.sh +0 -0
  95. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/git_surgery/recover-complex-stash/setup.sh +0 -0
  96. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/git_surgery/recover-complex-stash/verify.sh +0 -0
  97. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/git_surgery/recover-lost-work/setup.sh +0 -0
  98. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/git_surgery/recover-lost-work/verify.sh +0 -0
  99. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/git_surgery/repair-force-pushed-remote/setup.sh +0 -0
  100. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/git_surgery/repair-force-pushed-remote/verify.sh +0 -0
  101. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/git_surgery/revert-merge-with-followups/setup.sh +0 -0
  102. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/git_surgery/revert-merge-with-followups/verify.sh +0 -0
  103. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/git_surgery/secret-in-history/README.md +0 -0
  104. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/git_surgery/secret-in-history/setup.sh +0 -0
  105. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/git_surgery/secret-in-history/verify.sh +0 -0
  106. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/git_surgery/split-the-mega-commit/setup.sh +0 -0
  107. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/git_surgery/split-the-mega-commit/verify.sh +0 -0
  108. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/git_surgery/untangle-nested-submodules/setup.sh +0 -0
  109. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/git_surgery/untangle-nested-submodules/verify.sh +0 -0
  110. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/history.py +0 -0
  111. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/jobs.py +0 -0
  112. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/leakage.py +0 -0
  113. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/looping.py +0 -0
  114. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/mc_render.py +0 -0
  115. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/mc_viewer/dist/atlas.png +0 -0
  116. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/mc_viewer/dist/blockStates.json.gz +0 -0
  117. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/mc_viewer/dist/version.json +0 -0
  118. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/mc_viewer/dist/viewer.html +0 -0
  119. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/mc_viewer/dist/viewer.js +0 -0
  120. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/mc_viewer/dist/viewer.js.LICENSE.txt +0 -0
  121. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/mc_viewer/dist/worker.js +0 -0
  122. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/mc_viewer/dist/worker.js.LICENSE.txt +0 -0
  123. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/metrics.py +0 -0
  124. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/ollama.py +0 -0
  125. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/perf.py +0 -0
  126. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/perf_report.py +0 -0
  127. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/perturbations.py +0 -0
  128. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/pi_agent.py +0 -0
  129. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/pi_package/package-lock.json +0 -0
  130. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/pi_package/package.json +0 -0
  131. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/report.py +0 -0
  132. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/report_markdown.py +0 -0
  133. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/results.py +0 -0
  134. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/retry.py +0 -0
  135. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/runner.py +0 -0
  136. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/sandbox.py +0 -0
  137. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/template_check.py +0 -0
  138. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/templates/arena.html +0 -0
  139. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/templates/history.html +0 -0
  140. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/templates/perf.html +0 -0
  141. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/templates/report.html +0 -0
  142. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/tui/__init__.py +0 -0
  143. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/tui/app.py +0 -0
  144. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/tui/app.tcss +0 -0
  145. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/tui/formatting.py +0 -0
  146. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/tui/screens/__init__.py +0 -0
  147. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/tui/screens/connect.py +0 -0
  148. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/tui/screens/detail.py +0 -0
  149. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/tui/screens/help.py +0 -0
  150. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/tui/screens/modals.py +0 -0
  151. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/tui/screens/results.py +0 -0
  152. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/tui/screens/run.py +0 -0
  153. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/tui/screens/setup.py +0 -0
  154. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/tui/theme.py +0 -0
  155. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit/tui/widgets.py +0 -0
  156. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit_cli.egg-info/dependency_links.txt +0 -0
  157. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit_cli.egg-info/entry_points.txt +0 -0
  158. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit_cli.egg-info/requires.txt +0 -0
  159. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/src/benchkit_cli.egg-info/top_level.txt +0 -0
  160. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_aider_polyglot.py +0 -0
  161. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_banking77.py +0 -0
  162. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_code_verifier.py +0 -0
  163. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_concurrency.py +0 -0
  164. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_config.py +0 -0
  165. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_datasets.py +0 -0
  166. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_decision.py +0 -0
  167. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_evalplus.py +0 -0
  168. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_git_surgery.py +0 -0
  169. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_gsm8k.py +0 -0
  170. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_history.py +0 -0
  171. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_humaneval.py +0 -0
  172. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_looping.py +0 -0
  173. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_mc_arena.py +0 -0
  174. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_mcq.py +0 -0
  175. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_medfailbench.py +0 -0
  176. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_medfailbench_real_outputs.py +0 -0
  177. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_medfailbench_real_outputs_escalation.py +0 -0
  178. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_medfailbench_scoring_distortion.py +0 -0
  179. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_patcheval.py +0 -0
  180. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_perturbations.py +0 -0
  181. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_pi_harness.py +0 -0
  182. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_repair.py +0 -0
  183. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_report.py +0 -0
  184. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_retry.py +0 -0
  185. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_runner.py +0 -0
  186. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_sanity.py +0 -0
  187. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_treejs_arena.py +0 -0
  188. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_unload.py +0 -0
  189. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_utils.py +0 -0
  190. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_vision.py +0 -0
  191. {benchkit_cli-0.1.1 → benchkit_cli-0.2.0}/tests/test_xstest.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: benchkit-cli
3
- Version: 0.1.1
3
+ Version: 0.2.0
4
4
  Summary: Benchmark your local LLMs with real eval suites
5
5
  License-Expression: Apache-2.0
6
6
  Requires-Python: >=3.11
@@ -136,8 +136,11 @@ uv run benchkit --help
136
136
  | Aider Polyglot | `aider-polyglot` | 225 | Repository editing across six languages with Pi |
137
137
  | HumanEval | `humaneval` | 164 | Python function completion |
138
138
  | HumanEval+ | `humaneval-plus` | 164 | HumanEval with expanded EvalPlus tests |
139
+ | HumanEval+ TR | `humaneval-plus-tr` | 164 | HumanEval+ fully translated to Turkish, function and variable names included |
139
140
  | MBPP | `mbpp` | 500 | Short Python programming tasks |
140
141
  | MBPP+ | `mbpp-plus` | 378 | MBPP with expanded EvalPlus tests |
142
+ | CRUXEval-O | `cruxeval-o` | 800 | Predict what a short Python function returns (`-cot` for the step-by-step prompt) |
143
+ | CRUXEval-I | `cruxeval-i` | 800 | Find an input that produces a given output, checked by running it (`-cot` too) |
141
144
  | GSM8K | `gsm8k` | 1,319 | Multi-step grade-school math |
142
145
  | IFEval | `ifeval` | 541 | Verifiable instruction following |
143
146
  | RULER | `ruler` | 39 × 6 | Practical long-context retrieval from 4K to 128K |
@@ -118,8 +118,11 @@ uv run benchkit --help
118
118
  | Aider Polyglot | `aider-polyglot` | 225 | Repository editing across six languages with Pi |
119
119
  | HumanEval | `humaneval` | 164 | Python function completion |
120
120
  | HumanEval+ | `humaneval-plus` | 164 | HumanEval with expanded EvalPlus tests |
121
+ | HumanEval+ TR | `humaneval-plus-tr` | 164 | HumanEval+ fully translated to Turkish, function and variable names included |
121
122
  | MBPP | `mbpp` | 500 | Short Python programming tasks |
122
123
  | MBPP+ | `mbpp-plus` | 378 | MBPP with expanded EvalPlus tests |
124
+ | CRUXEval-O | `cruxeval-o` | 800 | Predict what a short Python function returns (`-cot` for the step-by-step prompt) |
125
+ | CRUXEval-I | `cruxeval-i` | 800 | Find an input that produces a given output, checked by running it (`-cot` too) |
123
126
  | GSM8K | `gsm8k` | 1,319 | Multi-step grade-school math |
124
127
  | IFEval | `ifeval` | 541 | Verifiable instruction following |
125
128
  | RULER | `ruler` | 39 × 6 | Practical long-context retrieval from 4K to 128K |
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "benchkit-cli"
3
- version = "0.1.1"
3
+ version = "0.2.0"
4
4
  description = "Benchmark your local LLMs with real eval suites"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -6,7 +6,13 @@ from benchkit.benchmarks.banking77 import Banking77
6
6
  from benchkit.benchmarks.boolq import BoolQ
7
7
  from benchkit.benchmarks.chartqa import ChartQA
8
8
  from benchkit.benchmarks.code_verifier import CodeVerifier
9
- from benchkit.benchmarks.evalplus import HumanEvalPlus, MBPPPlus
9
+ from benchkit.benchmarks.cruxeval import (
10
+ CRUXEvalInput,
11
+ CRUXEvalInputCoT,
12
+ CRUXEvalOutput,
13
+ CRUXEvalOutputCoT,
14
+ )
15
+ from benchkit.benchmarks.evalplus import HumanEvalPlus, HumanEvalPlusTR, MBPPPlus
10
16
  from benchkit.benchmarks.git_surgery import GitSurgery
11
17
  from benchkit.benchmarks.gpqa import GPQA
12
18
  from benchkit.benchmarks.gsm8k import GSM8K
@@ -41,8 +47,13 @@ REGISTRY: dict[str, type] = {
41
47
  "treejs-arena": TreeJSArena,
42
48
  "humaneval": HumanEval,
43
49
  "humaneval-plus": HumanEvalPlus,
50
+ "humaneval-plus-tr": HumanEvalPlusTR,
44
51
  "mbpp": MBPP,
45
52
  "mbpp-plus": MBPPPlus,
53
+ "cruxeval-o": CRUXEvalOutput,
54
+ "cruxeval-i": CRUXEvalInput,
55
+ "cruxeval-o-cot": CRUXEvalOutputCoT,
56
+ "cruxeval-i-cot": CRUXEvalInputCoT,
46
57
  "gsm8k": GSM8K,
47
58
  "ifeval": IFEval,
48
59
  "ruler": RULER,
@@ -78,8 +89,13 @@ DESCRIPTIONS: dict[str, str] = {
78
89
  "sanity": "25 curated checks across code, math, instructions, science, and commonsense",
79
90
  "humaneval": "Python function completions with the original unit tests",
80
91
  "humaneval-plus": "HumanEval with 122k+ tougher EvalPlus test inputs",
92
+ "humaneval-plus-tr": "HumanEval+ fully translated to Turkish, names included",
81
93
  "mbpp": "short Python functions from natural-language specifications",
82
94
  "mbpp-plus": "sanitized MBPP tasks with 39k+ EvalPlus test inputs",
95
+ "cruxeval-o": "predict what a short Python function returns for a given input",
96
+ "cruxeval-i": "find an input that makes a short Python function return a given output",
97
+ "cruxeval-o-cot": "CRUXEval output prediction with the step-by-step prompt",
98
+ "cruxeval-i-cot": "CRUXEval input prediction with the step-by-step prompt",
83
99
  "gsm8k": "multi-step grade-school math problems with exact numeric answers",
84
100
  "ifeval": "prompts with code-checkable instruction-following constraints",
85
101
  "ruler": "practical long-context retrieval across all 13 RULER task families",
@@ -0,0 +1,380 @@
1
+ """CRUXEval - predict what a short Python function returns, or what it was given.
2
+
3
+ 800 functions, each with one input and the output running it produces. The
4
+ output task (``cruxeval-o``) shows the input and asks for the output; the input
5
+ task (``cruxeval-i``) shows the output and asks for any input that produces it.
6
+ Both come in the upstream direct and chain-of-thought prompts, as separate
7
+ registry keys so the gap between them shows up as two jobs side by side.
8
+
9
+ Scoring needs no judge. A predicted output is parsed with ``ast.literal_eval``
10
+ and compared with ``==`` against the recorded output, so ``'abc'`` and
11
+ ``"abc"``, or ``(1, 2)`` written with odd spacing, all match. The one fallback:
12
+ when the recorded output is a string and the prediction is not a literal at
13
+ all, the bare text is compared with that string, so ``== abc`` counts for
14
+ ``'abc'``. Anything else that is not a literal - an unsimplified expression, a
15
+ call - is wrong, which is stricter than upstream (it evaluates expressions)
16
+ and keeps model-written code out of output scoring entirely.
17
+
18
+ A predicted input is never string-matched, because many inputs can produce
19
+ the same output: the call is run against the function in the sandbox and
20
+ passes when it returns the recorded output.
21
+ """
22
+
23
+ import ast
24
+ import json
25
+ import re
26
+ import secrets
27
+ from pathlib import Path
28
+
29
+ from benchkit.benchmarks.base import Task
30
+ from benchkit.benchmarks.utils import strip_think_tags
31
+ from benchkit.evaluation import EvaluationResult
32
+ from benchkit.executor import execute_with_feedback
33
+
34
+ DATASET = Path(__file__).parent.parent / "datasets" / "cruxeval.jsonl"
35
+
36
+ # Prompts are the upstream ones from facebookresearch/cruxeval (MIT), verbatim.
37
+ DIRECT_OUTPUT = """You are given a Python function and an assertion containing an input to the function. Complete the assertion with a literal (no unsimplified expressions, no function calls) containing the output when executing the provided code on the given input, even if the function is incorrect or incomplete. Do NOT output any extra information. Provide the full assertion with the correct output in [ANSWER] and [/ANSWER] tags, following the examples.
38
+
39
+ [PYTHON]
40
+ def f(n):
41
+ return n
42
+ assert f(17) == ??
43
+ [/PYTHON]
44
+ [ANSWER]
45
+ assert f(17) == 17
46
+ [/ANSWER]
47
+
48
+ [PYTHON]
49
+ def f(s):
50
+ return s + "a"
51
+ assert f("x9j") == ??
52
+ [/PYTHON]
53
+ [ANSWER]
54
+ assert f("x9j") == "x9ja"
55
+ [/ANSWER]
56
+
57
+ [PYTHON]
58
+ {code}
59
+ assert f({input}) == ??
60
+ [/PYTHON]
61
+ [ANSWER]
62
+ """
63
+
64
+ COT_OUTPUT = """You are given a Python function and an assertion containing an input to the function. Complete the assertion with a literal (no unsimplified expressions, no function calls) containing the output when executing the provided code on the given input, even if the function is incorrect or incomplete. Do NOT output any extra information. Execute the program step by step before arriving at an answer, and provide the full assertion with the correct output in [ANSWER] and [/ANSWER] tags, following the examples.
65
+
66
+ [PYTHON]
67
+ def f(s):
68
+ s = s + s
69
+ return "b" + s + "a"
70
+ assert f("hi") == ??
71
+ [/PYTHON]
72
+ [THOUGHT]
73
+ Let's execute the code step by step:
74
+
75
+ 1. The function f is defined, which takes a single argument s.
76
+ 2. The function is called with the argument "hi", so within the function, s is initially "hi".
77
+ 3. Inside the function, s is concatenated with itself, so s becomes "hihi".
78
+ 4. The function then returns a new string that starts with "b", followed by the value of s (which is now "hihi"), and ends with "a".
79
+ 5. The return value of the function is therefore "bhihia".
80
+ [/THOUGHT]
81
+ [ANSWER]
82
+ assert f("hi") == "bhihia"
83
+ [/ANSWER]
84
+
85
+ [PYTHON]
86
+ {code}
87
+ assert f({input}) == ??
88
+ [/PYTHON]
89
+ [THOUGHT]
90
+ """
91
+
92
+ DIRECT_INPUT = """You will be given a function f and an output in the form f(??) == output. Find any input such that executing f on the input leads to the given output. There may be multiple answers, but you should only output one. In [ANSWER] and [/ANSWER] tags, complete the assertion with one such input that will produce the output when executing the function.
93
+
94
+ [PYTHON]
95
+ def f(my_list):
96
+ count = 0
97
+ for i in my_list:
98
+ if len(i) % 2 == 0:
99
+ count += 1
100
+ return count
101
+ assert f(??) == 3
102
+ [/PYTHON]
103
+ [ANSWER]
104
+ assert f(["mq", "px", "zy"]) == 3
105
+ [/ANSWER]
106
+
107
+ [PYTHON]
108
+ def f(s1, s2):
109
+ return s1 + s2
110
+ assert f(??) == "banana"
111
+ [/PYTHON]
112
+ [ANSWER]
113
+ assert f("ba", "nana") == "banana"
114
+ [/ANSWER]
115
+
116
+ [PYTHON]
117
+ {code}
118
+ assert f(??) == {output}
119
+ [/PYTHON]
120
+ [ANSWER]
121
+ """
122
+
123
+ COT_INPUT = """You will be given a function f and an output in the form f(??) == output. Your task is to find any input such that executing f on the input leads to the given output. There may be multiple answers, but only output one. First, think step by step. You MUST surround the answer with [ANSWER] and [/ANSWER] tags. Express your answer as a passing assertion containing the input and the given output.
124
+
125
+ [PYTHON]
126
+ def f(x):
127
+ return x + 1
128
+ assert f(??) == 17
129
+ [/PYTHON]
130
+ [THOUGHT]
131
+ To find an input such that executing f on the input leads to the given output, we can work backwards from the given assertion. We know that f(??) == 17.
132
+
133
+ Since the function f(x) returns x + 1, for f(??) to be equal to 17, the value of ?? should be 16.
134
+ [/THOUGHT]
135
+ [ANSWER]
136
+ assert f(16) == 17
137
+ [/ANSWER]
138
+
139
+ [PYTHON]
140
+ {code}
141
+ assert f(??) == {output}
142
+ [/PYTHON]
143
+ [THOUGHT]
144
+ """
145
+
146
+ TEMPLATES = {
147
+ ("output", "direct"): DIRECT_OUTPUT,
148
+ ("output", "cot"): COT_OUTPUT,
149
+ ("input", "direct"): DIRECT_INPUT,
150
+ ("input", "cot"): COT_INPUT,
151
+ }
152
+
153
+ NO_ASSERTION = (
154
+ "No assertion of the form assert f(...) == ... was found in the answer. "
155
+ "Reply with one such assertion inside [ANSWER] and [/ANSWER] tags."
156
+ )
157
+
158
+
159
+ def _answer_block(response: str) -> str:
160
+ """The text the model meant as its answer.
161
+
162
+ The prompt itself opens ``[ANSWER]`` (direct) or ``[THOUGHT]`` (CoT), so a
163
+ response may carry both tags, only the closing one, or neither. The last
164
+ complete block wins; a Markdown fence inside it is unwrapped.
165
+ """
166
+ text = strip_think_tags(response)
167
+ if "[ANSWER]" in text:
168
+ text = text.rsplit("[ANSWER]", 1)[1].split("[/ANSWER]", 1)[0]
169
+ elif "[/ANSWER]" in text:
170
+ text = text.rsplit("[/ANSWER]", 1)[0]
171
+ text = text.rsplit("[/THOUGHT]", 1)[-1]
172
+ fences = re.findall(r"```[\w-]*\n?(.*?)```", text, re.DOTALL)
173
+ if fences:
174
+ text = fences[-1]
175
+ return text.strip()
176
+
177
+
178
+ def _assertion(block: str) -> str | None:
179
+ """The last ``assert`` statement in the block, if any."""
180
+ lines = block.splitlines()
181
+ for index in range(len(lines) - 1, -1, -1):
182
+ if lines[index].lstrip().startswith("assert"):
183
+ tail = "\n".join(line.strip() for line in lines[index:])
184
+ return tail if _parses(tail) else lines[index].strip()
185
+ return None
186
+
187
+
188
+ def _parses(source: str) -> bool:
189
+ try:
190
+ ast.parse(source)
191
+ except SyntaxError:
192
+ return False
193
+ return True
194
+
195
+
196
+ def _is_f_call(node: ast.expr) -> bool:
197
+ return (
198
+ isinstance(node, ast.Call)
199
+ and isinstance(node.func, ast.Name)
200
+ and node.func.id == "f"
201
+ )
202
+
203
+
204
+ def _equality(source: str) -> tuple[str, ast.expr, ast.expr] | None:
205
+ """Split ``[assert] left == right`` into its parsed sides."""
206
+ text = source.strip()
207
+ if text.startswith("assert"):
208
+ text = text[len("assert") :].strip()
209
+ try:
210
+ node = ast.parse(text, mode="eval").body
211
+ except SyntaxError:
212
+ return None
213
+ if (
214
+ isinstance(node, ast.Compare)
215
+ and len(node.ops) == 1
216
+ and isinstance(node.ops[0], ast.Eq)
217
+ ):
218
+ return text, node.left, node.comparators[0]
219
+ return None
220
+
221
+
222
+ def predicted_output(response: str) -> str | None:
223
+ """The output the model predicted, as source text."""
224
+ block = _answer_block(response)
225
+ candidate = _assertion(block) or block
226
+ split = _equality(candidate)
227
+ if split is not None:
228
+ text, left, right = split
229
+ side = left if _is_f_call(right) and not _is_f_call(left) else right
230
+ return ast.get_source_segment(text, side)
231
+ # Not parseable: a bare word after ``==`` is still a usable prediction.
232
+ if "==" in candidate:
233
+ candidate = candidate.rsplit("==", 1)[1]
234
+ candidate = candidate.split("#", 1)[0].strip()
235
+ return candidate or None
236
+
237
+
238
+ def predicted_call(response: str) -> str | None:
239
+ """The ``f(...)`` call the model proposed, as source text."""
240
+ block = _answer_block(response)
241
+ candidate = _assertion(block) or block
242
+ split = _equality(candidate)
243
+ if split is not None:
244
+ text, left, right = split
245
+ for side in (left, right):
246
+ if _is_f_call(side):
247
+ return ast.get_source_segment(text, side)
248
+ return None
249
+ try:
250
+ node = ast.parse(candidate, mode="eval").body
251
+ except SyntaxError:
252
+ return None
253
+ if _is_f_call(node):
254
+ return ast.get_source_segment(candidate, node)
255
+ # A bare input, such as ``"ba", "nana"``, is the argument list itself.
256
+ return f"f({candidate})"
257
+
258
+
259
+ def outputs_match(predicted: str | None, expected: str) -> bool:
260
+ """Literal comparison of a predicted output with the recorded one."""
261
+ if predicted is None:
262
+ return False
263
+ target = ast.literal_eval(expected)
264
+ try:
265
+ value = ast.literal_eval(predicted)
266
+ except (ValueError, TypeError, SyntaxError, MemoryError, RecursionError):
267
+ return isinstance(target, str) and predicted.strip() == target
268
+ try:
269
+ return bool(value == target)
270
+ except Exception:
271
+ return False
272
+
273
+
274
+ class _CRUXEval:
275
+ name: str
276
+ task: str # "output" or "input"
277
+ style: str # "direct" or "cot"
278
+ task_count = 800
279
+
280
+ def load_tasks(self) -> list[Task]:
281
+ tasks = []
282
+ with open(DATASET, encoding="utf-8") as f:
283
+ for line in f:
284
+ d = json.loads(line)
285
+ tasks.append(
286
+ Task(
287
+ id=d["task_id"],
288
+ prompt=d["function"],
289
+ metadata={
290
+ "input": d["input"],
291
+ "output": d["output"],
292
+ # The demo client answers with this.
293
+ "canonical_solution": (
294
+ f"[ANSWER]\nassert f({d['input']}) == "
295
+ f"{d['output']}\n[/ANSWER]"
296
+ ),
297
+ },
298
+ )
299
+ )
300
+ return tasks
301
+
302
+ def build_prompt(self, task: Task) -> str:
303
+ template = TEMPLATES[(self.task, self.style)]
304
+ return template.format(
305
+ code=task.prompt,
306
+ input=task.metadata["input"],
307
+ output=task.metadata["output"],
308
+ )
309
+
310
+ def evaluate(self, task: Task, response: str) -> bool:
311
+ return self.evaluate_with_feedback(task, response).passed
312
+
313
+ def summary_fields(self, records: list[object]) -> dict:
314
+ """Record which half and which prompt style a score came from."""
315
+ return {"cruxeval_task": self.task, "cruxeval_prompt": self.style}
316
+
317
+
318
+ class _OutputPrediction(_CRUXEval):
319
+ task = "output"
320
+
321
+ def evaluate_with_feedback(self, task: Task, response: str) -> EvaluationResult:
322
+ predicted = predicted_output(response)
323
+ if predicted is None:
324
+ return EvaluationResult(0.0, NO_ASSERTION)
325
+ if outputs_match(predicted, task.metadata["output"]):
326
+ return EvaluationResult(1.0)
327
+ return EvaluationResult(
328
+ 0.0,
329
+ "The predicted output does not equal the value the function returns. "
330
+ "Trace the code again; the answer must be a Python literal.",
331
+ )
332
+
333
+
334
+ class _InputPrediction(_CRUXEval):
335
+ task = "input"
336
+ evaluation_activity = "running the predicted input"
337
+
338
+ def evaluate_with_feedback(self, task: Task, response: str) -> EvaluationResult:
339
+ call = predicted_call(response)
340
+ if call is None:
341
+ return EvaluationResult(0.0, NO_ASSERTION)
342
+ # Same check as upstream, ``assert output == f(input)``. The input is
343
+ # model-written code, so a pass also needs a fresh sentinel printed
344
+ # after the assertion: an input that exits early cannot fake one.
345
+ sentinel = secrets.token_hex(16)
346
+ program = (
347
+ f"{task.prompt}\n\n"
348
+ f"assert {task.metadata['output']} == {call}\n"
349
+ f"print({sentinel!r})\n"
350
+ )
351
+ result = execute_with_feedback(program, timeout=5, sentinel=sentinel)
352
+ if result.passed:
353
+ return EvaluationResult(1.0)
354
+ if "assertion failed" in result.feedback:
355
+ return EvaluationResult(
356
+ 0.0,
357
+ "The proposed input ran, but the function returned a different "
358
+ "value than the given output.",
359
+ )
360
+ return EvaluationResult(0.0, result.feedback)
361
+
362
+
363
+ class CRUXEvalOutput(_OutputPrediction):
364
+ name = "cruxeval-o"
365
+ style = "direct"
366
+
367
+
368
+ class CRUXEvalOutputCoT(_OutputPrediction):
369
+ name = "cruxeval-o-cot"
370
+ style = "cot"
371
+
372
+
373
+ class CRUXEvalInput(_InputPrediction):
374
+ name = "cruxeval-i"
375
+ style = "direct"
376
+
377
+
378
+ class CRUXEvalInputCoT(_InputPrediction):
379
+ name = "cruxeval-i-cot"
380
+ style = "cot"
@@ -164,3 +164,14 @@ MMLU_PRO = RemoteFile(
164
164
  sha256="92ec532d9e2bae342ec7256005c20b6e5defbed76504280df775fb77068f077e",
165
165
  size=10_260_787,
166
166
  )
167
+
168
+ # Pinned to a dataset commit on the Hub; the sha256 covers the exact bytes.
169
+ HUMANEVAL_PLUS_TR = RemoteFile(
170
+ name="humanevalplus_tr.jsonl",
171
+ url=(
172
+ "https://huggingface.co/datasets/DogukanUrker/HumanEvalPlus-TR/resolve/"
173
+ "e424171b8934581819fcdeddace2af28a664966f/humanevalplus_tr.jsonl"
174
+ ),
175
+ sha256="072172a4d7934b8ce27d8ad0c83b139b80296876bd2f8a8afad1476bdaa97955",
176
+ size=7_635_249,
177
+ )
@@ -3,6 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import contextlib
6
+ import json
6
7
  import multiprocessing
7
8
  import os
8
9
  import platform
@@ -14,7 +15,7 @@ from pathlib import Path
14
15
  from typing import Any
15
16
 
16
17
  from benchkit.benchmarks.base import Task
17
- from benchkit.benchmarks.downloads import Dataset
18
+ from benchkit.benchmarks.downloads import HUMANEVAL_PLUS_TR, Dataset
18
19
  from benchkit.benchmarks.utils import strip_think_tags
19
20
  from benchkit.executor import sandbox_env
20
21
 
@@ -23,6 +24,12 @@ HUMANEVAL_SYSTEM = (
23
24
  "Output ONLY the function body. "
24
25
  "No markdown fences, no explanation, no examples."
25
26
  )
27
+ # Full Turkish translation, ASCII only like the dataset itself.
28
+ HUMANEVAL_TR_SYSTEM = (
29
+ "Asagidaki Python fonksiyonunu tamamla. "
30
+ "YALNIZCA fonksiyon govdesini yaz. "
31
+ "Markdown blogu, aciklama veya ornek ekleme."
32
+ )
26
33
  MBPP_SYSTEM = (
27
34
  "Write a Python function to solve the following task. "
28
35
  "Output ONLY the function. "
@@ -118,9 +125,14 @@ def _evalplus_api():
118
125
  )
119
126
 
120
127
 
121
- @lru_cache(maxsize=2)
128
+ @lru_cache(maxsize=3)
122
129
  def _problems(dataset: str) -> dict[str, dict[str, Any]]:
123
130
  get_human_eval_plus, get_mbpp_plus, *_ = _evalplus_api()
131
+ if dataset == "humaneval-tr":
132
+ # Same schema as HumanEvalPlus.jsonl: translated prompt, entry point,
133
+ # canonical solution and contract, original inputs and tolerances.
134
+ rows = HUMANEVAL_PLUS_TR.ensure().read_text(encoding="utf-8").splitlines()
135
+ return {row["task_id"]: row for row in map(json.loads, filter(None, rows))}
124
136
  if dataset == "humaneval":
125
137
  return get_human_eval_plus()
126
138
  if dataset == "mbpp":
@@ -275,14 +287,14 @@ class _EvalPlusBenchmark:
275
287
  def evaluate(self, task: Task, response: str) -> bool:
276
288
  *_, pass_status, _, check_correctness, _ = _evalplus_api()
277
289
  problem = _problems(self.dataset)[task.id]
278
- if self.dataset == "humaneval":
290
+ if self.dataset.startswith("humaneval"):
279
291
  solution = _human_solution(problem, response)
280
292
  else:
281
293
  solution = _extract_code(response)
282
294
 
283
295
  with _fork_multiprocessing():
284
296
  result = check_correctness(
285
- self.dataset,
297
+ "mbpp" if self.dataset == "mbpp" else "humaneval",
286
298
  completion_id=0,
287
299
  problem=problem,
288
300
  solution=solution,
@@ -302,6 +314,16 @@ class HumanEvalPlus(_EvalPlusBenchmark):
302
314
  )
303
315
 
304
316
 
317
+ class HumanEvalPlusTR(_EvalPlusBenchmark):
318
+ name = "humaneval-plus-tr"
319
+ dataset = "humaneval-tr"
320
+ task_count = 164
321
+ system = HUMANEVAL_TR_SYSTEM
322
+ data_source = HUMANEVAL_PLUS_TR.source(
323
+ "HumanEval+ fully translated to Turkish (docstrings and identifiers)"
324
+ )
325
+
326
+
305
327
  class MBPPPlus(_EvalPlusBenchmark):
306
328
  name = "mbpp-plus"
307
329
  dataset = "mbpp"