evalrx 0.1.2__py3-none-any.whl

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 (339) hide show
  1. evalrx/__init__.py +139 -0
  2. evalrx/agent_assets/__init__.py +2 -0
  3. evalrx/agent_assets/skills/README.md +28 -0
  4. evalrx/agent_assets/skills/eval-chart-style/SKILL.md +172 -0
  5. evalrx/agent_assets/skills/evalrx-report-ui/SKILL.md +116 -0
  6. evalrx/agent_assets/skills/nature-figure/LICENSE +201 -0
  7. evalrx/agent_assets/skills/nature-figure/README.md +412 -0
  8. evalrx/agent_assets/skills/nature-figure/SKILL.md +60 -0
  9. evalrx/agent_assets/skills/nature-figure/manifest.yaml +59 -0
  10. evalrx/agent_assets/skills/nature-figure/references/api.md +436 -0
  11. evalrx/agent_assets/skills/nature-figure/references/backend-selection.md +100 -0
  12. evalrx/agent_assets/skills/nature-figure/references/chart-types.md +281 -0
  13. evalrx/agent_assets/skills/nature-figure/references/common-patterns.md +350 -0
  14. evalrx/agent_assets/skills/nature-figure/references/demos.md +65 -0
  15. evalrx/agent_assets/skills/nature-figure/references/design-theory.md +439 -0
  16. evalrx/agent_assets/skills/nature-figure/references/figure-contract.md +93 -0
  17. evalrx/agent_assets/skills/nature-figure/references/figure-legend-conventions.md +71 -0
  18. evalrx/agent_assets/skills/nature-figure/references/nature-2026-observations.md +112 -0
  19. evalrx/agent_assets/skills/nature-figure/references/qa-contract.md +119 -0
  20. evalrx/agent_assets/skills/nature-figure/references/r-template-index.md +66 -0
  21. evalrx/agent_assets/skills/nature-figure/references/r-workflow.md +161 -0
  22. evalrx/agent_assets/skills/nature-figure/references/tutorials.md +251 -0
  23. evalrx/agent_assets/skills/nature-figure/static/core/contract.md +29 -0
  24. evalrx/agent_assets/skills/nature-figure/static/core/stance.md +37 -0
  25. evalrx/agent_assets/skills/nature-figure/static/fragments/backend/python.md +37 -0
  26. evalrx/agent_assets/skills/nature-figure/static/fragments/backend/r.md +44 -0
  27. evalrx/agent_assets/skills/outcome-driver-analysis/SKILL.md +213 -0
  28. evalrx/agent_assets/skills/outcome-driver-analysis/assets/analysis_report_template.md +53 -0
  29. evalrx/agent_assets/skills/outcome-driver-analysis/references/model_selection.md +72 -0
  30. evalrx/agent_assets/skills/outcome-driver-analysis/scripts/explanatory_var_eda.R +130 -0
  31. evalrx/agent_assets/skills/outcome-driver-analysis/scripts/explanatory_var_eda.py +150 -0
  32. evalrx/agent_assets/skills/outcome-driver-analysis/scripts/fit_outcome_model.R +181 -0
  33. evalrx/agent_assets/skills/outcome-driver-analysis/scripts/fit_outcome_model.py +186 -0
  34. evalrx/agent_assets/skills/outcome-driver-analysis/scripts/univariate_eda.R +149 -0
  35. evalrx/agent_assets/skills/outcome-driver-analysis/scripts/univariate_eda.py +177 -0
  36. evalrx/agent_assets/skills.py +27 -0
  37. evalrx/agent_runtime/__init__.py +78 -0
  38. evalrx/agent_runtime/_docker_runner.py +89 -0
  39. evalrx/agent_runtime/cli_runtime.py +103 -0
  40. evalrx/agent_runtime/cli_transcript.py +138 -0
  41. evalrx/agent_runtime/cli_types.py +68 -0
  42. evalrx/agent_runtime/codegen/__init__.py +5 -0
  43. evalrx/agent_runtime/codegen/runner.py +94 -0
  44. evalrx/agent_runtime/experiment_harness.py +117 -0
  45. evalrx/agent_runtime/factory.py +102 -0
  46. evalrx/agent_runtime/json_shape.py +44 -0
  47. evalrx/agent_runtime/judges/__init__.py +28 -0
  48. evalrx/agent_runtime/judges/agy.py +179 -0
  49. evalrx/agent_runtime/judges/autodetect.py +135 -0
  50. evalrx/agent_runtime/judges/claude.py +159 -0
  51. evalrx/agent_runtime/judges/codex.py +120 -0
  52. evalrx/agent_runtime/providers/__init__.py +21 -0
  53. evalrx/agent_runtime/providers/antigravity.py +31 -0
  54. evalrx/agent_runtime/providers/base.py +145 -0
  55. evalrx/agent_runtime/providers/claude_code.py +49 -0
  56. evalrx/agent_runtime/providers/codex.py +37 -0
  57. evalrx/agent_runtime/providers/gemini_cli.py +26 -0
  58. evalrx/agent_runtime/providers/kimi_cli.py +27 -0
  59. evalrx/agent_runtime/providers/opencode.py +27 -0
  60. evalrx/agent_runtime/providers/registry.py +58 -0
  61. evalrx/agent_runtime/sandbox.py +517 -0
  62. evalrx/agent_runtime/skill_audit.py +143 -0
  63. evalrx/agent_runtime/skills/__init__.py +19 -0
  64. evalrx/agent_runtime/skills/installer.py +68 -0
  65. evalrx/agent_runtime/skills/prompt_policy.py +86 -0
  66. evalrx/agent_runtime/skills/resolver.py +19 -0
  67. evalrx/analysis/__init__.py +132 -0
  68. evalrx/analysis/adjudicate.py +154 -0
  69. evalrx/analysis/analysis_module.py +361 -0
  70. evalrx/analysis/api.py +171 -0
  71. evalrx/analysis/case_studio.py +651 -0
  72. evalrx/analysis/cli.py +114 -0
  73. evalrx/analysis/dashboard.py +350 -0
  74. evalrx/analysis/eval_case_matrix.py +118 -0
  75. evalrx/analysis/eval_viz_theme.py +833 -0
  76. evalrx/analysis/explore_run.py +333 -0
  77. evalrx/analysis/explorer.py +1276 -0
  78. evalrx/analysis/failure_modes.py +607 -0
  79. evalrx/analysis/fused_pipeline.py +489 -0
  80. evalrx/analysis/holdout.py +300 -0
  81. evalrx/analysis/hypothesis_agent.py +230 -0
  82. evalrx/analysis/narration.py +177 -0
  83. evalrx/analysis/operationalize.py +442 -0
  84. evalrx/analysis/plain_language.py +42 -0
  85. evalrx/analysis/planner.py +283 -0
  86. evalrx/analysis/probe_search.py +203 -0
  87. evalrx/analysis/profile.py +268 -0
  88. evalrx/analysis/prompts/__init__.py +0 -0
  89. evalrx/analysis/prompts/explorer.py +417 -0
  90. evalrx/analysis/prompts/failure_modes.py +33 -0
  91. evalrx/analysis/prompts/holdout.py +27 -0
  92. evalrx/analysis/prompts/hypothesis_agent.py +78 -0
  93. evalrx/analysis/prompts/run_codebase.py +47 -0
  94. evalrx/analysis/prompts/stats_agent.py +72 -0
  95. evalrx/analysis/prompts/stats_tool_generator.py +43 -0
  96. evalrx/analysis/result_marker.py +47 -0
  97. evalrx/analysis/run_codebase.py +242 -0
  98. evalrx/analysis/run_view.py +205 -0
  99. evalrx/analysis/stage_views.py +93 -0
  100. evalrx/analysis/stats_agent.py +944 -0
  101. evalrx/analysis/stats_tool_agent.py +261 -0
  102. evalrx/analysis/stats_tool_generator.py +415 -0
  103. evalrx/analysis/stats_tools.py +1153 -0
  104. evalrx/analysis/trajectory_records.py +193 -0
  105. evalrx/analysis/workbench.py +431 -0
  106. evalrx/analyzers/__init__.py +42 -0
  107. evalrx/analyzers/agent/__init__.py +25 -0
  108. evalrx/analyzers/agent/counterfactual.py +84 -0
  109. evalrx/analyzers/agent/first_error_judge.py +96 -0
  110. evalrx/analyzers/agent/ignored_obs.py +81 -0
  111. evalrx/analyzers/agent/loop_detect.py +79 -0
  112. evalrx/analyzers/agent/reliability.py +165 -0
  113. evalrx/analyzers/agent/tool_shap.py +225 -0
  114. evalrx/analyzers/agent/trajectory_rubric.py +168 -0
  115. evalrx/analyzers/attention/__init__.py +19 -0
  116. evalrx/analyzers/attention/relative_attn.py +610 -0
  117. evalrx/analyzers/attention/rollout.py +73 -0
  118. evalrx/analyzers/attention/sink.py +56 -0
  119. evalrx/analyzers/attention/summary.py +190 -0
  120. evalrx/analyzers/attribution/__init__.py +6 -0
  121. evalrx/analyzers/attribution/generic_attn.py +31 -0
  122. evalrx/analyzers/attribution/gradcam.py +30 -0
  123. evalrx/analyzers/base.py +12 -0
  124. evalrx/analyzers/geometry/__init__.py +6 -0
  125. evalrx/analyzers/geometry/cka.py +70 -0
  126. evalrx/analyzers/geometry/linear_probe.py +157 -0
  127. evalrx/analyzers/hallucination/__init__.py +9 -0
  128. evalrx/analyzers/hallucination/chair.py +78 -0
  129. evalrx/analyzers/hallucination/opera.py +29 -0
  130. evalrx/analyzers/hallucination/pope.py +119 -0
  131. evalrx/analyzers/hallucination/selfcheck.py +155 -0
  132. evalrx/analyzers/hallucination/vcd.py +29 -0
  133. evalrx/analyzers/lens/__init__.py +7 -0
  134. evalrx/analyzers/lens/layer_contrast.py +133 -0
  135. evalrx/analyzers/lens/logit_lens.py +138 -0
  136. evalrx/analyzers/lens/tuned_lens.py +30 -0
  137. evalrx/analyzers/patching/__init__.py +5 -0
  138. evalrx/analyzers/patching/causal_trace.py +30 -0
  139. evalrx/analyzers/perturbation/__init__.py +23 -0
  140. evalrx/analyzers/perturbation/_shapley.py +54 -0
  141. evalrx/analyzers/perturbation/context_shap.py +174 -0
  142. evalrx/analyzers/perturbation/cot_faithfulness.py +239 -0
  143. evalrx/analyzers/perturbation/format_sensitivity.py +237 -0
  144. evalrx/analyzers/perturbation/mm_shap.py +146 -0
  145. evalrx/analyzers/perturbation/modality_ablation.py +196 -0
  146. evalrx/analyzers/perturbation/perturbation_battery.py +274 -0
  147. evalrx/analyzers/perturbation/prompt_contrast.py +265 -0
  148. evalrx/analyzers/perturbation/rise.py +94 -0
  149. evalrx/analyzers/perturbation/vl_shap.py +102 -0
  150. evalrx/analyzers/reasoning/__init__.py +33 -0
  151. evalrx/analyzers/reasoning/_text.py +328 -0
  152. evalrx/analyzers/reasoning/answer_extraction_audit.py +327 -0
  153. evalrx/analyzers/reasoning/arith_audit.py +226 -0
  154. evalrx/analyzers/reasoning/contamination.py +214 -0
  155. evalrx/analyzers/reasoning/knowledge_split.py +253 -0
  156. evalrx/analyzers/reasoning/self_repair.py +246 -0
  157. evalrx/analyzers/reasoning/step_rollout_value.py +216 -0
  158. evalrx/analyzers/reasoning/termination_audit.py +258 -0
  159. evalrx/analyzers/uncertainty/__init__.py +18 -0
  160. evalrx/analyzers/uncertainty/calibration.py +174 -0
  161. evalrx/analyzers/uncertainty/coverage_gap.py +199 -0
  162. evalrx/analyzers/uncertainty/entropy.py +90 -0
  163. evalrx/analyzers/uncertainty/logprob_entropy.py +69 -0
  164. evalrx/analyzers/uncertainty/self_consistency.py +204 -0
  165. evalrx/analyzers/uncertainty/verbalized_conf.py +64 -0
  166. evalrx/cli.py +411 -0
  167. evalrx/config.py +77 -0
  168. evalrx/contract/__init__.py +179 -0
  169. evalrx/contract/common.py +452 -0
  170. evalrx/contract/emit.py +948 -0
  171. evalrx/contract/export.py +237 -0
  172. evalrx/contract/m1.py +325 -0
  173. evalrx/contract/m2.py +317 -0
  174. evalrx/contract/m3.py +165 -0
  175. evalrx/contract/m4.py +130 -0
  176. evalrx/contract/m5.py +292 -0
  177. evalrx/contract/methodology.py +76 -0
  178. evalrx/contract/pre_m1.py +58 -0
  179. evalrx/contract/typescript.py +140 -0
  180. evalrx/core/__init__.py +85 -0
  181. evalrx/core/analyzer.py +174 -0
  182. evalrx/core/capability.py +54 -0
  183. evalrx/core/case.py +443 -0
  184. evalrx/core/experiment.py +106 -0
  185. evalrx/core/model.py +198 -0
  186. evalrx/core/pipeline.py +42 -0
  187. evalrx/core/registry.py +142 -0
  188. evalrx/core/result.py +64 -0
  189. evalrx/core/spec.py +173 -0
  190. evalrx/core/tokentype.py +165 -0
  191. evalrx/core/tool.py +92 -0
  192. evalrx/datasets/__init__.py +41 -0
  193. evalrx/datasets/base.py +68 -0
  194. evalrx/datasets/gui_os.py +52 -0
  195. evalrx/datasets/llm_qa.py +57 -0
  196. evalrx/datasets/pure_qa.py +12 -0
  197. evalrx/datasets/vlm_qa.py +695 -0
  198. evalrx/datasets/web_search_qa.py +52 -0
  199. evalrx/eval_agent/__init__.py +341 -0
  200. evalrx/eval_agent/_tools.py +81 -0
  201. evalrx/eval_agent/ab_runner.py +50 -0
  202. evalrx/eval_agent/agentic/__init__.py +43 -0
  203. evalrx/eval_agent/agentic/actions.py +216 -0
  204. evalrx/eval_agent/agentic/board.py +107 -0
  205. evalrx/eval_agent/agentic/loop.py +190 -0
  206. evalrx/eval_agent/agentic/tools.py +538 -0
  207. evalrx/eval_agent/checkpoint.py +57 -0
  208. evalrx/eval_agent/cli_agent.py +59 -0
  209. evalrx/eval_agent/cli_skills.py +5 -0
  210. evalrx/eval_agent/evolution.py +396 -0
  211. evalrx/eval_agent/git_manager.py +215 -0
  212. evalrx/eval_agent/hypothesis.py +172 -0
  213. evalrx/eval_agent/label_quarantine.py +209 -0
  214. evalrx/eval_agent/legacy.py +530 -0
  215. evalrx/eval_agent/log_schema.py +497 -0
  216. evalrx/eval_agent/loop.py +2159 -0
  217. evalrx/eval_agent/loop_reports.py +116 -0
  218. evalrx/eval_agent/model_instrumentation.py +282 -0
  219. evalrx/eval_agent/narration.py +193 -0
  220. evalrx/eval_agent/nl_runner.py +460 -0
  221. evalrx/eval_agent/orchestrator.py +61 -0
  222. evalrx/eval_agent/preregister.py +93 -0
  223. evalrx/eval_agent/prompts/__init__.py +1 -0
  224. evalrx/eval_agent/prompts/agentic.py +46 -0
  225. evalrx/eval_agent/prompts/case_discovery.py +25 -0
  226. evalrx/eval_agent/prompts/diagnosis.py +125 -0
  227. evalrx/eval_agent/prompts/experiment_writer.py +265 -0
  228. evalrx/eval_agent/prompts/explore_step.py +37 -0
  229. evalrx/eval_agent/prompts/fix_agent.py +257 -0
  230. evalrx/eval_agent/prompts/hypothesis_tester.py +15 -0
  231. evalrx/eval_agent/prompts/nl_runner.py +38 -0
  232. evalrx/eval_agent/prompts/probe_agent.py +25 -0
  233. evalrx/eval_agent/prompts/probe_candidate_generator.py +14 -0
  234. evalrx/eval_agent/prompts/probe_generator.py +35 -0
  235. evalrx/eval_agent/prompts/whitebox_probe_generator.py +38 -0
  236. evalrx/eval_agent/report.py +58 -0
  237. evalrx/eval_agent/run_context.py +354 -0
  238. evalrx/eval_agent/run_log.schema.json +1215 -0
  239. evalrx/eval_agent/run_logger_v2.py +1764 -0
  240. evalrx/eval_agent/run_metadata.py +208 -0
  241. evalrx/eval_agent/stages/__init__.py +56 -0
  242. evalrx/eval_agent/stages/case_discovery.py +293 -0
  243. evalrx/eval_agent/stages/diagnosis.py +1017 -0
  244. evalrx/eval_agent/stages/experiment_writer.py +1634 -0
  245. evalrx/eval_agent/stages/fix_agent.py +3916 -0
  246. evalrx/eval_agent/stages/fix_internals.py +499 -0
  247. evalrx/eval_agent/stages/fix_pipeline.py +725 -0
  248. evalrx/eval_agent/stages/fix_tiers.py +187 -0
  249. evalrx/eval_agent/stages/fix_tools.py +1034 -0
  250. evalrx/eval_agent/stages/hypothesis_tester.py +1014 -0
  251. evalrx/eval_agent/stages/probe.py +439 -0
  252. evalrx/eval_agent/stages/probe_agent.py +1079 -0
  253. evalrx/eval_agent/stages/probe_candidate_generator.py +128 -0
  254. evalrx/eval_agent/stages/probe_generator.py +326 -0
  255. evalrx/eval_agent/stages/probe_search_agent.py +106 -0
  256. evalrx/eval_agent/stages/protocol.py +112 -0
  257. evalrx/eval_agent/stages/repair_catalog.py +273 -0
  258. evalrx/eval_agent/stages/surgery.py +524 -0
  259. evalrx/eval_agent/stages/whitebox_probe_generator.py +351 -0
  260. evalrx/eval_agent/store.py +231 -0
  261. evalrx/logging_utils.py +112 -0
  262. evalrx/models/__init__.py +161 -0
  263. evalrx/models/_discover.py +101 -0
  264. evalrx/models/agent.py +380 -0
  265. evalrx/models/backends/__init__.py +58 -0
  266. evalrx/models/backends/api.py +169 -0
  267. evalrx/models/backends/base.py +57 -0
  268. evalrx/models/backends/gemini_compat.py +579 -0
  269. evalrx/models/backends/hf_local.py +2074 -0
  270. evalrx/models/backends/openai_compat.py +301 -0
  271. evalrx/models/backends/vllm_offline.py +116 -0
  272. evalrx/models/base.py +24 -0
  273. evalrx/models/blackbox/__init__.py +4 -0
  274. evalrx/models/blackbox/agent.py +31 -0
  275. evalrx/models/blackbox/base.py +29 -0
  276. evalrx/models/blackbox/gemini.py +279 -0
  277. evalrx/models/blackbox/llm_api.py +17 -0
  278. evalrx/models/blackbox/vlm_api.py +17 -0
  279. evalrx/models/compose.py +66 -0
  280. evalrx/models/inference.py +88 -0
  281. evalrx/models/paper_methods/__init__.py +8 -0
  282. evalrx/models/paper_methods/aad.py +53 -0
  283. evalrx/models/paper_methods/ifcd.py +204 -0
  284. evalrx/models/paper_methods/pai.py +164 -0
  285. evalrx/models/paper_methods/tcd.py +202 -0
  286. evalrx/models/paper_methods/vcd.py +45 -0
  287. evalrx/models/paper_methods/vicrop.py +137 -0
  288. evalrx/models/toolcodec.py +143 -0
  289. evalrx/models/tools/__init__.py +20 -0
  290. evalrx/models/tools/perception.py +300 -0
  291. evalrx/models/tools/visual.py +174 -0
  292. evalrx/models/whitebox/__init__.py +26 -0
  293. evalrx/models/whitebox/agent.py +31 -0
  294. evalrx/models/whitebox/base.py +24 -0
  295. evalrx/models/whitebox/qwen.py +61 -0
  296. evalrx/models/whitebox/qwen2_5_omni.py +29 -0
  297. evalrx/models/whitebox/qwen2_audio.py +25 -0
  298. evalrx/models/whitebox/qwen_omni.py +53 -0
  299. evalrx/models/whitebox/qwen_vl.py +62 -0
  300. evalrx/observability/__init__.py +21 -0
  301. evalrx/observability/envelope.py +122 -0
  302. evalrx/observability/outbox.py +111 -0
  303. evalrx/observability/tracer.py +882 -0
  304. evalrx/reporting/__init__.py +28 -0
  305. evalrx/reporting/case_study.py +947 -0
  306. evalrx/reporting/compiler.py +587 -0
  307. evalrx/reporting/dynamic.py +1882 -0
  308. evalrx/reporting/html_report.py +2225 -0
  309. evalrx/reporting/langfuse_exporter.py +38 -0
  310. evalrx/reporting/langfuse_source.py +155 -0
  311. evalrx/reporting/model.py +151 -0
  312. evalrx/reporting/run_events.py +184 -0
  313. evalrx/reporting/server.py +557 -0
  314. evalrx/reporting/stages.py +58 -0
  315. evalrx/reporting/static_export.py +142 -0
  316. evalrx/reporting/web_dist/index.html +146 -0
  317. evalrx/specs.py +727 -0
  318. evalrx/stats/__init__.py +47 -0
  319. evalrx/stats/api.py +192 -0
  320. evalrx/stats/bootstrap.py +86 -0
  321. evalrx/stats/ebh.py +27 -0
  322. evalrx/stats/evalue.py +98 -0
  323. evalrx/stats/friedman.py +138 -0
  324. evalrx/stats/mcnemar.py +40 -0
  325. evalrx/stats/multiplicity.py +159 -0
  326. evalrx/stats/subset_sampling.py +55 -0
  327. evalrx/term_links.py +43 -0
  328. evalrx/viz/__init__.py +7 -0
  329. evalrx/viz/labels.py +77 -0
  330. evalrx/viz/prompts.py +39 -0
  331. evalrx/viz/renderer.py +590 -0
  332. evalrx/viz/schema.py +36 -0
  333. evalrx/viz/style.py +134 -0
  334. evalrx-0.1.2.dist-info/METADATA +532 -0
  335. evalrx-0.1.2.dist-info/RECORD +339 -0
  336. evalrx-0.1.2.dist-info/WHEEL +5 -0
  337. evalrx-0.1.2.dist-info/entry_points.txt +3 -0
  338. evalrx-0.1.2.dist-info/licenses/LICENSE +121 -0
  339. evalrx-0.1.2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,125 @@
1
+ """Prompt templates for M3 diagnosis."""
2
+
3
+ _DIAGNOSE_PROMPT = """\
4
+ You are an expert ML diagnostician. Based on the analysis report below, propose
5
+ specific, falsifiable hypotheses about the root cause of the model's failures.
6
+
7
+ Each hypothesis is written twice: once for a specialist (HYPOTHESIS, TEST) and
8
+ once for the person who will read the report. That reader builds and runs
9
+ evaluations but does not do statistics — they know what a benchmark, a prompt
10
+ and a failure case are, and they have never met an e-value, a McNemar test or a
11
+ multiple-comparisons correction. The PLAIN_STATEMENT line is written for them.
12
+ {prior_section}
13
+ Model: {model_name}
14
+ Overall severity (threshold rules): {severity}
15
+
16
+ Experiment protocol (authoritative task and response contract):
17
+ {protocol_section}
18
+
19
+ Analysis conclusion (the analyst's interpretation):
20
+ {conclusion}
21
+ {evidence_section}{stats_section}{explore_section}{failure_modes_section}
22
+ Raw findings (JSON):
23
+ {findings_json}
24
+
25
+ {available_signals_section}Propose 1-3 hypotheses. For each write:
26
+ HYPOTHESIS: <one-sentence falsifiable technical claim about the failure mode>
27
+ PLAIN_STATEMENT: <the SAME claim as HYPOTHESIS, restated in ONE everyday
28
+ sentence, written for the reader described above. State what the model is
29
+ doing wrong, not what statistic was computed. Numbers are welcome and make
30
+ it better — but a number must come with what it amounts to ("gets 45 of the
31
+ 125 wrong, nearly all of them lists longer than eight words"), never bare
32
+ ("fail rate 0.36"). No acronyms, no statistics jargon, no symbols (→, ρ, σ),
33
+ no bare metric identifiers as the subject of the sentence. Do not copy the
34
+ HYPOTHESIS line verbatim — this is checked, and a jargon-y or copy-pasted
35
+ line is sent back for a rewrite.>
36
+ FAILURE_MODE: <short snake_case tag naming the MECHANISM, not the symptom.
37
+ Vision/agent: attention_sink / hallucination / loop / ignored_obs / language_prior_bias
38
+ Text reasoning: computation_slip / chain_break / knowledge_gap / selection_failure /
39
+ overthinking / brittleness / memorization / self_correction_failure
40
+ Harness (suspect these before any mechanism): answer_extraction / truncation /
41
+ degenerate_repetition
42
+ Use a tag from these lists when one fits; invent one only when none does.>
43
+ TEST: <which evidence verifies this claim — name a signal/analyzer from the
44
+ available evidence list when one fits (e.g. "relative_attention.max_relative_weight
45
+ HIGHER on failing cases" or "prompt_contrast describe_first contrast"), and for a
46
+ per-case signal SAY whether it should be HIGHER or LOWER on failing cases — that
47
+ is the prediction the test checks. On a yes/no task a directional claim ("answers
48
+ Yes regardless of the evidence") is tested on the DIRECTION marginals
49
+ answer_extraction_audit.answered_yes (the answer's direction, e.g. HIGHER on
50
+ failing cases) and answer_extraction_audit.gold_yes (the question's), never on
51
+ extracted_answer, labelled_fail or a correctness flag — those are text or the
52
+ label itself and cannot be evidence; otherwise describe the analyzer or
53
+ intervention that should be run next cycle>
54
+ EXPECTED_ASSOCIATION: <higher_on_failures if larger/present values of the named
55
+ signal support the hypothesis, or lower_on_failures if smaller/absent values
56
+ support it. Pre-register this direction from the claim; do not infer it from an
57
+ observed effect. For an intervention expected to repair failures, use
58
+ higher_on_failures for a fixed_by_* signal.>
59
+
60
+ Base your hypotheses on the analysis conclusion and evidence above — an analyzer
61
+ can surface a real failure mode even when no numeric threshold fired, so do NOT
62
+ rely on the threshold severity alone.
63
+ Do NOT repeat hypotheses already listed in the prior cycles above.
64
+ If the conclusion and evidence genuinely show no problem, respond with: NO_ISSUE"""
65
+
66
+ _VALIDATE_PROMPT = """\
67
+ You are an adversarial ML reviewer. Your job is to find reasons to REJECT each
68
+ hypothesis below. Only approve a hypothesis if you cannot find a significant flaw.
69
+
70
+ Check each for:
71
+ 1. Unsupported claim — does the cited evidence actually imply this failure mode?
72
+ 2. Circular reasoning — does the hypothesis merely restate the symptom?
73
+ 3. Overgeneralisation — does it make a claim far broader than the evidence supports?
74
+ 4. Confounded alternative — is there a simpler explanation the hypothesis ignores?
75
+ {context_section}
76
+ Findings summary (the evidence the hypotheses were drawn from):
77
+ {findings_json}
78
+
79
+ Hypotheses to review:
80
+ {hypotheses_text}
81
+
82
+ For each hypothesis output two lines:
83
+ KEEP: <hypothesis statement> or REJECT: <hypothesis statement>
84
+ REASON: <one or two sentences naming the flaw you found, or why it survives>
85
+ REASON: <specific flaw, or "evidence directly supports this claim" if keeping>"""
86
+
87
+
88
+ _FORMAT_REPAIR_PROMPT = """\
89
+ Your previous answer below could not be read: it contains no line that starts
90
+ with the label HYPOTHESIS:. The hypotheses are only usable in the exact
91
+ line-labelled format.
92
+
93
+ Previous answer:
94
+ {raw}
95
+
96
+ Rewrite the SAME hypotheses (do not invent new ones) so that each one is a block
97
+ of these lines, in this order, each label at the start of its own line:
98
+ HYPOTHESIS: <one-sentence falsifiable technical claim>
99
+ PLAIN_STATEMENT: <the same claim in one everyday sentence, no jargon>
100
+ FAILURE_MODE: <short snake_case tag naming the mechanism>
101
+ TEST: <which signal/analyzer verifies the claim>
102
+ EXPECTED_ASSOCIATION: <higher_on_failures or lower_on_failures>
103
+
104
+ If your previous answer meant that there is no issue to report, reply with the
105
+ single word NO_ISSUE."""
106
+
107
+ _PLAIN_REPAIR_PROMPT = """\
108
+ Your previous answer below proposed hypotheses correctly, but some
109
+ PLAIN_STATEMENT lines fail a plain-language check.
110
+
111
+ PLAIN_STATEMENT must be a one-sentence everyday paraphrase of the matching
112
+ HYPOTHESIS line, written for an engineer who runs evaluations but does no
113
+ statistics: no statistics terms, no acronyms, no symbols, and not a verbatim
114
+ copy of the HYPOTHESIS line. Numbers are welcome, but each one must come with
115
+ what it amounts to rather than standing bare.
116
+
117
+ Previous answer:
118
+ {raw}
119
+
120
+ Problems found:
121
+ {violations}
122
+
123
+ Rewrite the FULL set of hypotheses in the exact same
124
+ HYPOTHESIS/PLAIN_STATEMENT/FAILURE_MODE/TEST/EXPECTED_ASSOCIATION format,
125
+ fixing only the flagged PLAIN_STATEMENT lines. Do not change any other line."""
@@ -0,0 +1,265 @@
1
+ """Prompt templates for the M5 experiment writer."""
2
+
3
+ from typing import Any
4
+
5
+ _BLUEPRINT_SYSTEM = """\
6
+ You are an expert ML debugging engineer. Plan the structure of a multi-file
7
+ Python diagnostic project that will test a specific hypothesis about a model's
8
+ behaviour.
9
+
10
+ Output a YAML specification with this structure:
11
+ ```yaml
12
+ description: one-line summary
13
+ files:
14
+ - name: main.py
15
+ generation_order: 3
16
+ description: entry point
17
+ pseudocode: |
18
+ 1. Load model
19
+ 2. Run cases
20
+ 3. Compute metrics
21
+ 4. Print metrics in name: value format
22
+ 5. Print verdict: 1.0 or verdict: 0.0
23
+ dependencies: [model_probe.py, utils.py]
24
+ - name: utils.py
25
+ generation_order: 1
26
+ description: shared helpers
27
+ pseudocode: |
28
+ - helper functions
29
+ dependencies: []
30
+ output_contract:
31
+ metrics: [mean_consistency, n_cases]
32
+ verdict: "1.0 = hypothesis SUPPORTED, 0.0 = REFUTED"
33
+ ```
34
+
35
+ Rules:
36
+ - Generate 2–4 files maximum
37
+ - main.py must be last in generation_order
38
+ - main.py MUST have `if __name__ == "__main__":` block
39
+ - The last printed line of the entire run MUST be `verdict: 1.0` or `verdict: 0.0`
40
+ - Stay under {timeout_sec} seconds total runtime\
41
+ """
42
+
43
+ _BLUEPRINT_USER = """\
44
+ ## Hypothesis to test
45
+ Statement : {statement}
46
+ Failure mode: {failure_mode}
47
+
48
+ ## Model setup
49
+ ```python
50
+ {import_expr}
51
+ model = {load_expr}
52
+ ```
53
+
54
+ Available capabilities: {capabilities}
55
+
56
+ ## Model access policy
57
+ {model_access_note}
58
+
59
+ ## Failure cases (JSON)
60
+ ```json
61
+ {cases_json_snippet}
62
+ ```
63
+
64
+ Write the YAML blueprint now:\
65
+ """
66
+
67
+ _GENERATE_FILE_SYSTEM = """\
68
+ You are an expert ML debugging engineer. Generate a single Python file
69
+ as part of a multi-file diagnostic experiment project.
70
+
71
+ Rules:
72
+ - Implement EXACTLY the pseudocode in the file spec
73
+ - Use only the evalrx APIs shown
74
+ - Output ONLY the Python code — no markdown prose before or after
75
+ - Code must be complete and immediately executable\
76
+ """
77
+
78
+ _GENERATE_FILE_USER = """\
79
+ ## File to generate: {file_name}
80
+
81
+ ### File spec
82
+ ```json
83
+ {file_spec}
84
+ ```
85
+
86
+ ### Blueprint (full project)
87
+ ```yaml
88
+ {blueprint}
89
+ ```
90
+
91
+ ### Dependencies already generated
92
+ {dep_summaries}
93
+
94
+ {dep_code}
95
+
96
+ ## Model access policy
97
+ {model_access_note}
98
+
99
+ ## EvalRX API reference
100
+ ```python
101
+ from evalrx.core.case import CaseBatch, FailureCase, Inputs
102
+ output: str = model.generate(case.inputs)
103
+ # logprobs (only if 'LOGPROBS' in capabilities)
104
+ lps = model.logprobs(case.inputs)
105
+ # internals (only if 'ATTENTION' or 'HIDDEN_STATES' in capabilities)
106
+ trace = model.forward(case.inputs, capture={{Capability.ATTENTION}})
107
+ ```
108
+
109
+ Write the complete `{file_name}` now (Python code only):\
110
+ """
111
+
112
+ _WRITE_SYSTEM = """\
113
+ You are an expert ML debugging engineer. Write a concise, self-contained Python
114
+ diagnostic script that gathers evidence for or against a specific hypothesis
115
+ about a model's behaviour.
116
+
117
+ RULES:
118
+ - Use ONLY the evalrx APIs shown in the user message.
119
+ - The script must be completely self-contained — no external files.
120
+ - Print ALL metrics in EXACTLY this format (one per line):
121
+ metric_name: float_value
122
+ - Print a final verdict line as the LAST output:
123
+ verdict: 1.0 # hypothesis is SUPPORTED by the evidence
124
+ verdict: 0.0 # hypothesis is REFUTED
125
+ - Never print anything after the verdict line.
126
+ - Catch exceptions and print error metrics rather than crashing silently.
127
+ - Stay under {timeout_sec} seconds total runtime.
128
+ - The script MUST have `if __name__ == "__main__":` block.\
129
+ """
130
+
131
+ _WRITE_USER = """\
132
+ ## Hypothesis to test
133
+ Statement : {statement}
134
+ Failure mode: {failure_mode}
135
+
136
+ ## Model setup (copy this verbatim)
137
+ ```python
138
+ {import_expr}
139
+ model = {load_expr}
140
+ ```
141
+
142
+ Available capabilities: {capabilities}
143
+
144
+ ## Model access policy
145
+ {model_access_note}
146
+
147
+ {blueprint_context}
148
+
149
+ ## EvalRX API reference
150
+ ```python
151
+ from evalrx.core.case import CaseBatch, FailureCase, Inputs
152
+ from evalrx.core.capability import Capability
153
+
154
+ # Text generation (always available)
155
+ output: str = model.generate(case.inputs)
156
+
157
+ # Token logprobs (only if 'LOGPROBS' in capabilities)
158
+ lps = model.logprobs(case.inputs) # list[TokenLogprob]; each has .token, .logprob
159
+
160
+ # Internals capture (only if 'ATTENTION' or 'HIDDEN_STATES' in capabilities)
161
+ trace = model.forward(case.inputs, capture={{Capability.ATTENTION}})
162
+ # trace.attentions list[Tensor] one per layer, shape [heads, seq, seq]
163
+ # trace.hidden_states list[Tensor] one per layer, shape [seq, hidden]
164
+ # trace.tokens list[str]
165
+ ```
166
+
167
+ ## Failure cases (JSON — deserialize inside your script)
168
+ ```json
169
+ {cases_json}
170
+ ```
171
+
172
+ ## Required output (EXACTLY this format)
173
+ ```
174
+ metric_a: 0.72
175
+ metric_b: 3.0
176
+ verdict: 1.0
177
+ ```
178
+
179
+ Write the complete Python script now:\
180
+ """
181
+
182
+ _REPAIR_SYSTEM = """\
183
+ You are a Python debugging expert. The script below crashed.
184
+ Return the COMPLETE corrected script — no explanations, just the fixed code.
185
+ Preserve all logic; fix only the error.\
186
+ """
187
+
188
+ _REPAIR_USER = """\
189
+ ## Error
190
+ ```
191
+ {error}
192
+ ```
193
+
194
+ ## Script to fix
195
+ ```python
196
+ {code}
197
+ ```\
198
+ """
199
+
200
+ _REVIEW_SYSTEM = """\
201
+ You are a senior code reviewer. Review this diagnostic experiment code and
202
+ return a JSON object with:
203
+ - "verdict": "APPROVE" or "REQUEST_CHANGES"
204
+ - "score": integer 1-10
205
+ - "critical_issues": list of strings (empty if APPROVE)
206
+
207
+ Focus on: correctness of hypothesis testing logic, metric computation,
208
+ verdict output format, and error handling. Do NOT flag style issues.\
209
+ """
210
+
211
+
212
+ def build_cli_prompt(
213
+ hypothesis: Any,
214
+ model_context: dict[str, Any],
215
+ timeout_sec: int,
216
+ n_images: int = 0,
217
+ ) -> str:
218
+ """Build the prompt used by external CLI coding agents."""
219
+ caps = ", ".join(model_context.get("capabilities", [])) or "GENERATE"
220
+ access_note = model_context.get("access_note", "")
221
+ image_note = (
222
+ f", and image_path (JPEG path for {n_images} case(s)).\n"
223
+ "Load images and build inputs like this:\n"
224
+ "```python\n"
225
+ "from PIL import Image\n"
226
+ "from evalrx.core.case import Inputs\n"
227
+ "img = Image.open(case['image_path'])\n"
228
+ "inputs = Inputs(prompt=case['prompt'], image=img)\n"
229
+ "# Then: model.generate(inputs) or model.forward(inputs, capture={Capability.ATTENTION})\n"
230
+ "```\n"
231
+ "Do NOT pass raw dicts or lists as inputs — always use Inputs().\n\n"
232
+ if n_images else ".\n\n"
233
+ )
234
+ return (
235
+ "You are an ML debugging engineer. Write a self-contained Python "
236
+ "diagnostic script that tests a specific hypothesis about a model.\n\n"
237
+ "## Hypothesis\n"
238
+ f"Statement : {hypothesis.statement}\n"
239
+ f"Failure mode: {hypothesis.predicted_failure_mode}\n\n"
240
+ "## Model setup (copy verbatim)\n"
241
+ "```python\n"
242
+ f"{model_context.get('import_expr', 'import evalrx')}\n"
243
+ f"model = {model_context.get('load_expr', '# model')}\n"
244
+ "```\n\n"
245
+ f"Available capabilities: {caps}\n\n"
246
+ "## Model access policy\n"
247
+ f"{access_note}\n\n"
248
+ "## Input data\n"
249
+ "Read `cases.json` from the current directory. "
250
+ "Each record has: prompt, label (PASS/FAIL), id, metadata"
251
+ + image_note
252
+ + "## Required output (print to stdout, EXACTLY this format)\n"
253
+ "```\n"
254
+ "metric_a: 0.72\n"
255
+ "metric_b: 3.0\n"
256
+ "verdict: 1.0 # 1.0=SUPPORTED 0.0=REFUTED\n"
257
+ "```\n\n"
258
+ "## Rules\n"
259
+ f"- Stay under {timeout_sec} seconds total runtime.\n"
260
+ "- Save the script as `experiment.py` in the current directory.\n"
261
+ "- Print all metrics as `name: float_value` lines.\n"
262
+ "- The last printed line must be `verdict: 1.0` or `verdict: 0.0`.\n"
263
+ "- Use only the evalrx APIs shown above.\n"
264
+ "- Do NOT make external network calls or read files other than `cases.json`.\n"
265
+ )
@@ -0,0 +1,37 @@
1
+ """Question template for the loop's optional in-cycle explore step.
2
+
3
+ The explorer (:class:`~evalrx.analysis.explorer.ExploratoryAnalysisAgent`)
4
+ is a free-form EDA coder: it only knows what the question tells it. This
5
+ template turns the run's :class:`~evalrx.eval_agent.stages.protocol.ExperimentProtocol`
6
+ into a question that (a) names the outcome column, (b) says what the columns
7
+ are (M1 analyzer per-case signals), and (c) asks for FROZEN, threshold-explicit
8
+ recipes — the only form a candidate signal can later be re-evaluated in.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from typing import Any
14
+
15
+ _EXPLORE_QUESTION = (
16
+ "Which per-case signals distinguish the FAIL cases (label=fail) from the "
17
+ "PASS cases (label=pass)?{context} Every other column is a per-case signal "
18
+ "an M1 analyzer computed on the model under diagnosis (column name = "
19
+ "analyzer.metric, sanitized). Compare each signal's distribution between "
20
+ "FAIL and PASS, look for interactions and thresholds, and make every "
21
+ "candidate signal a FROZEN, threshold-explicit recipe over the available "
22
+ "numeric columns (explicit numeric cut-offs, no re-fitting) so it can be "
23
+ "re-evaluated verbatim on held-out cases. Charts are leads for hypotheses, "
24
+ "not proof: this is the exploration half of a diagnosis loop, and a "
25
+ "separate confirmatory stage will test whatever you surface."
26
+ )
27
+
28
+
29
+ def default_explore_question(protocol: Any | None = None) -> str:
30
+ """Build the explore question from the run's protocol (or a generic one)."""
31
+ parts: list[str] = []
32
+ for attr in ("description", "task_domain", "failure_patterns"):
33
+ value = getattr(protocol, attr, None) if protocol is not None else None
34
+ if value:
35
+ parts.append(str(value).strip())
36
+ context = (" Context: " + " ".join(parts)) if parts else ""
37
+ return _EXPLORE_QUESTION.format(context=context)
@@ -0,0 +1,257 @@
1
+ """Prompt templates for fix candidate generation and repair."""
2
+
3
+ _L1_PROMPT = """\
4
+ You are designing PROMPT-LEVEL fixes (tier L1: the input space only) for a \
5
+ model failure. The model may be text-only or vision-language.
6
+
7
+ VERIFIED FAILURE HYPOTHESES:
8
+ {hypotheses}
9
+ {context}
10
+ EXAMPLE CASES — read the model's own outputs: what it does when it fails, what
11
+ it does when it succeeds, and the answer format the scorer expects:
12
+ {examples}
13
+
14
+ Propose up to {k} prompt rewrite strategies that could repair these failures
15
+ WITHOUT changing the model or adding pipeline steps. Each strategy is a
16
+ template applied to every case prompt; it MUST contain the literal placeholder
17
+ {{prompt}}. Keep the final-answer format the scorer expects recoverable; do
18
+ not ask the model to suppress its reasoning if the task needs it. If your
19
+ template asks the model to write intermediate work (a transcription, a list, a
20
+ check) that may not fit the baseline decode budget, add "generation_kwargs":
21
+ {{"max_tokens": <int>}} to that strategy — it can only RAISE the budget (a
22
+ lower value is raised to the baseline), and no other decoding control is
23
+ allowed at this tier.
24
+
25
+
26
+ "what_it_does" is shown to a reader who has never heard of this model, this
27
+ benchmark, or this field -- write it for a bright high-school student. One
28
+ sentence, present tense, plain words, saying what CHANGES for the model. Do
29
+ not name the tier, do not use metric or method jargon, and do not restate the
30
+ snake_case name in English.
31
+ Good: "Asks the model to describe what it hears before it answers."
32
+ Bad: "L1 audio-evidence-first prompt scaffold with deferred answering."
33
+
34
+ Reply with ONLY a JSON array (generation_kwargs is optional; omit it unless
35
+ the rewrite needs the extra room):
36
+ [{{"name": "<short_snake_case>", "what_it_does": "<one plain sentence>",
37
+ "prompt_template": "<template with {{prompt}}>",
38
+ "generation_kwargs": {{"max_tokens": <int>}}}}]"""
39
+
40
+ _L2_PROMPT = """\
41
+ You are designing SCAFFOLD-LEVEL fixes (tier L2: a pipeline around the \
42
+ unchanged model) for a model failure. The model may be text-only or
43
+ vision-language.
44
+
45
+ VERIFIED FAILURE HYPOTHESES:
46
+ {hypotheses}
47
+ {context}
48
+ EXAMPLE CASES — read the model's own outputs: what it does when it fails, what
49
+ it does when it succeeds, and the answer format the scorer expects:
50
+ {examples}
51
+
52
+ IMAGE TOOLS (only meaningful when the case has an image):
53
+ {catalog}
54
+
55
+ Propose up to {k} pipelines. Each may chain image tools, rewrite the prompt
56
+ (template MUST contain {{prompt}}), sample the model n_samples times (1..5;
57
+ applies to EVERY strategy — a multi-call strategy is repeated end-to-end and
58
+ its final answers vote on the extracted final answer), select one reviewed
59
+ multi-call strategy (direct, least_to_most, self_refine,
60
+ chain_of_verification), and set bounded decoding controls in
61
+ generation_kwargs (temperature, top_p, stop, max_tokens). max_tokens can only
62
+ RAISE the baseline budget — a value below it is raised to the baseline, so
63
+ never try to shorten the model's chain of thought; temperature 0 makes
64
+ n_samples>1 pointless. For structured answer tasks, output_key_pattern may be
65
+ a regex with one capture group used for answer-only voting; it must not
66
+ contain gold answers.
67
+
68
+ "what_it_does" is shown to a reader who has never heard of this model, this
69
+ benchmark, or this field -- write it for a bright high-school student. One
70
+ sentence, present tense, plain words, saying what CHANGES for the model. Do
71
+ not name the tier, do not use metric or method jargon, and do not restate the
72
+ snake_case name in English.
73
+ Good: "Asks the model to describe what it hears before it answers."
74
+ Bad: "L1 audio-evidence-first prompt scaffold with deferred answering."
75
+
76
+ Reply with ONLY a JSON array:
77
+ [{{"name": "<short_snake_case>", "what_it_does": "<one plain sentence>",
78
+ "image_ops": [{{"tool": "<catalog name>", "params": {{}}}}],
79
+ "prompt_template": "{{prompt}}", "n_samples": 1,
80
+ "generation_kwargs": {{}}, "strategy": "direct",
81
+ "output_key_pattern": ""}}]"""
82
+
83
+ _L2_CODE_PROMPT = """\
84
+ You are writing a PYTHON PIPELINE (tier L2: a scaffold around the unchanged \
85
+ model) that repairs the failures described below. Design any
86
+ pipeline you want — the only constraint is that the model itself is unchanged.
87
+
88
+ VERIFIED FAILURE HYPOTHESES:
89
+ {hypotheses}
90
+ {context}
91
+ EXAMPLE CASES — read the model's own outputs: what it does when it fails, what
92
+ it does when it succeeds, and the answer format the scorer expects:
93
+ {examples}
94
+
95
+ EXECUTION CONTRACT:
96
+ - "{cases_file}" in the current directory: {{"cases": [{{"id": str, "prompt": str,
97
+ "baseline_output": str|null}}]}} — baseline_output is the model's ORIGINAL
98
+ recorded answer to that prompt: the DIRECT BASELINE. It may be wrong; it is
99
+ NOT a label and carries no correctness information. Use it directly as the
100
+ baseline answer (compare against it, vote with it, ask the model to
101
+ double-check it) — you do NOT need to call model_generate(case_id) to
102
+ obtain it; a plain model_generate(case_id) is answered from this record.
103
+ - A function model_generate(case_id, prompt=None, image_ops=None,
104
+ generation_kwargs=None) -> str is ALREADY DEFINED in your namespace (do NOT
105
+ import or redefine it). It runs the ORIGINAL model on that case: optional
106
+ prompt override, optional image transforms applied to the case's image
107
+ first, optional bounded decoding controls (temperature, top_p, stop,
108
+ max_tokens — max_tokens can only RAISE the baseline budget; a lower value is
109
+ raised to it). IMPORTANT: ``prompt`` REPLACES the original prompt; it is
110
+ not prepended automatically. Every answer-producing override must include
111
+ ``case["prompt"]`` itself (for example, ``instruction + "\\n\\n" +
112
+ case["prompt"]``), or the model will never see the question. image_ops MUST
113
+ be a list of
114
+ {{"tool": "<name>", "params": {{...}}}} dicts using ONLY these tools
115
+ (anything else is rejected with an error):
116
+ {catalog}{attend_hint}
117
+ - You may call the model SEVERAL times per case, but keep it to at most
118
+ 4 calls per case that hit the model (genuinely independent enhanced/reasoned
119
+ passes: a different prompt and/or image_ops each); the host enforces this
120
+ per-case cap. A plain model_generate(case_id) (no prompt override, no
121
+ image_ops, no generation_kwargs) is answered from the recorded
122
+ baseline_output, costs nothing and does not count. Branch on outputs
123
+ within that budget — e.g. describe first, then decide; vote over
124
+ independent variants.
125
+ - model_generate is thread-safe and concurrent calls are serviced in
126
+ parallel: fan out over CASES with concurrent.futures.ThreadPoolExecutor
127
+ (max_workers=8) — a serial loop over every case x several calls is slow and
128
+ risks the wall-clock limit.
129
+ - SELECTION RULE (enforced by the host, without labels): for each case the
130
+ host anchors on baseline_output (or on your plain direct call when a case
131
+ has no record). Your final "output" may differ from that anchor only when
132
+ at least {min_support} of your enhanced calls with DISTINCT prompt/image_ops
133
+ returned the same answer; otherwise the host reverts that case to the
134
+ anchor. Return the model's own reply text (or the tagged answer you asked
135
+ it to emit, e.g. "FINAL: <answer>" — the host strips such tags when
136
+ matching); never rewrite, reformat or compute the answer yourself.
137
+ Pattern the host accepts:
138
+ base = case["baseline_output"] or ""
139
+ question = case["prompt"]
140
+ votes = [model_generate(cid, prompt=p1 + "\\n\\n" + question),
141
+ model_generate(cid, prompt=p2 + "\\n\\n" + question, image_ops=ops)]
142
+ final = the answer that >= {min_support} votes agree on if it differs from base, else base
143
+ {selection_guidance}
144
+ - The LAST line of stdout MUST be exactly:
145
+ {marker}{{"per_case": [{{"sample_id": "<case id>", "output": "<final answer text>"}}]}}
146
+ - Emit an entry for EVERY case. The "output" is scored externally against the
147
+ original question, so it must answer that question faithfully (e.g. contain
148
+ a clear yes/no for yes/no questions).
149
+ - Standard library + numpy only. No network, no file writes. Keep it under
150
+ ~80 lines.
151
+ - REPAIR THE MODEL, NOT THE TASK. Your code is re-run a second time with every
152
+ model_generate() call answered by the model's ORIGINAL recorded answer. Any
153
+ failing case your pipeline gets right in THAT run was solved by your code,
154
+ not the model, and is excluded from the fix score — a pipeline that computes
155
+ the answer itself (sorting, arithmetic, lookup, a hard-coded default) scores
156
+ zero. Verify, vote, re-ask, re-prompt, zoom: make the model get it right.
157
+
158
+ The FIRST line of your code must be a WHAT_IT_DOES comment, on ONE line, for a
159
+ reader who has never heard of this model, this benchmark, or this field: plain
160
+ words, present tense, saying what your pipeline makes the model do differently.
161
+ No jargon, no tier names, no restating the code. For example:
162
+ # WHAT_IT_DOES: Asks the model twice with different wording and keeps the answer both tries agree on.
163
+
164
+ Return ONLY the Python code{fences_hint}."""
165
+
166
+ _REPAIR_PROMPT_BODY = """\
167
+ Your previously written repair pipeline FAILED TO EXECUTE.
168
+
169
+ ERROR:
170
+ {error}
171
+
172
+ YOUR PREVIOUS CODE:
173
+ ```python
174
+ {code}
175
+ ```
176
+
177
+ Fix the code. Follow the execution contract EXACTLY:
178
+ - the ONLY model access is the predefined model_generate(case_id, prompt=None, \
179
+ image_ops=None, generation_kwargs=None){attend_clause} — do not import or redefine it;
180
+ - image_ops must be a list of {{"tool": "<name>", "params": {{...}}}} dicts \
181
+ using ONLY these tools:
182
+ {catalog}
183
+ - baseline_output in "{cases_file}" IS the direct baseline answer — use it as \
184
+ the baseline; a plain model_generate(case_id) is answered from that record and \
185
+ is free; the TOTAL number of enhanced model_generate(...) PLUS model_attend(...) \
186
+ calls must be at most 4 per case (model_attend is not free);
187
+ - the host's selection guard reverts a case to its baseline unless at least \
188
+ {min_support} DISTINCT enhanced calls returned your final answer (answer tags \
189
+ such as "FINAL: <answer>" are stripped when matching);
190
+ {selection_guidance}
191
+ - read "{cases_file}", emit an entry for EVERY case, and end stdout with \
192
+ exactly:
193
+ {marker}{{"per_case": [{{"sample_id": "<case id>", "output": "<final answer text>"}}]}}
194
+ - standard library + numpy only; no network, no file writes; under ~80 lines.
195
+ - overwrite pipeline.py with ONLY the corrected user pipeline; do not copy or \
196
+ modify fix_pipeline_exec.py and do not append the old program after the repair.
197
+ - repair the MODEL, not the task: the code is re-run with every model_generate() \
198
+ call answered by the model's original recorded answer, and failing cases it still \
199
+ gets right then are excluded from the score. If it timed out, make FEWER model \
200
+ calls per case — do not replace them with code that computes the answer itself.
201
+ - keep (or add) the one-line `# WHAT_IT_DOES: ...` first line describing, in \
202
+ plain words for a reader with no background, what your pipeline makes the model \
203
+ do differently.
204
+ """
205
+
206
+ _L3_PROMPT = """\
207
+ You are configuring WHITE-BOX intervention primitives (tier L3: the model's \
208
+ internals) against the failures below. The primitives are pre-audited host \
209
+ code — you choose which to run and with what parameters.
210
+
211
+ VERIFIED FAILURE HYPOTHESES:
212
+ {hypotheses}
213
+
214
+ AVAILABLE PRIMITIVES:
215
+ {catalog}
216
+
217
+ Propose up to {k} configurations. Reply with ONLY a JSON array:
218
+ [{{"primitive": "<name from the list>", "params": {{...}}}}]"""
219
+
220
+ _REPAIR_CATALOG_PROMPT = """\
221
+ You are selecting which REGISTERED repair capability, if any, applies to the \
222
+ failure(s) below. Each candidate is a specific, pre-audited \
223
+ intervention that targets ONE named failure mechanism — read what mechanism \
224
+ each one actually targets, then select it ONLY when the verified hypotheses \
225
+ describe that same mechanism, not merely because it is technically able to \
226
+ run on this model and task (that eligibility has already been checked for \
227
+ you; your only job is judging whether the mechanism matches).
228
+
229
+ VERIFIED FAILURE HYPOTHESES:
230
+ {hypotheses}
231
+
232
+ ELIGIBLE CANDIDATES (already filtered to what this model/task can run):
233
+ {catalog}
234
+
235
+ Propose up to {k} candidates whose targeted mechanism is genuinely \
236
+ consistent with the hypotheses above. A hypothesis naming a DIFFERENT \
237
+ mechanism (e.g. a flat knowledge gap, a positional/answer-choice bias, or a \
238
+ hallucination cause when the candidate targets something else entirely) is \
239
+ NOT a match, even if the candidate would run without error. If none of the \
240
+ candidates address the diagnosed mechanism, reply with an empty array — do \
241
+ not select one just because it is available. Reply with ONLY a JSON array:
242
+ [{{"name": "<name from the list>", "rationale": "<one sentence: how the hypothesis's mechanism matches this candidate's>"}}]"""
243
+
244
+ _L4_PROMPT = """\
245
+ You are writing a PARAMETER-SPACE repair recipe (tier L4: fine-tuning) for \
246
+ the failures below. The recipe is RECORDED for a human decision — it will \
247
+ not be executed automatically.
248
+
249
+ VERIFIED FAILURE HYPOTHESES:
250
+ {hypotheses}
251
+
252
+ Reply with ONLY a JSON object:
253
+ {{"dataset_recipe": "<how to build training data that generalises the failure
254
+ mechanism — never just the observed failing cases>",
255
+ "method": "lora|sft", "target": "vision_encoder|llm|projector|full",
256
+ "eval_protocol": "<held-out repair effect + regression battery>",
257
+ "rationale": "<why parameter-space change is the minimum effective tier>"}}"""