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.
- evalrx/__init__.py +139 -0
- evalrx/agent_assets/__init__.py +2 -0
- evalrx/agent_assets/skills/README.md +28 -0
- evalrx/agent_assets/skills/eval-chart-style/SKILL.md +172 -0
- evalrx/agent_assets/skills/evalrx-report-ui/SKILL.md +116 -0
- evalrx/agent_assets/skills/nature-figure/LICENSE +201 -0
- evalrx/agent_assets/skills/nature-figure/README.md +412 -0
- evalrx/agent_assets/skills/nature-figure/SKILL.md +60 -0
- evalrx/agent_assets/skills/nature-figure/manifest.yaml +59 -0
- evalrx/agent_assets/skills/nature-figure/references/api.md +436 -0
- evalrx/agent_assets/skills/nature-figure/references/backend-selection.md +100 -0
- evalrx/agent_assets/skills/nature-figure/references/chart-types.md +281 -0
- evalrx/agent_assets/skills/nature-figure/references/common-patterns.md +350 -0
- evalrx/agent_assets/skills/nature-figure/references/demos.md +65 -0
- evalrx/agent_assets/skills/nature-figure/references/design-theory.md +439 -0
- evalrx/agent_assets/skills/nature-figure/references/figure-contract.md +93 -0
- evalrx/agent_assets/skills/nature-figure/references/figure-legend-conventions.md +71 -0
- evalrx/agent_assets/skills/nature-figure/references/nature-2026-observations.md +112 -0
- evalrx/agent_assets/skills/nature-figure/references/qa-contract.md +119 -0
- evalrx/agent_assets/skills/nature-figure/references/r-template-index.md +66 -0
- evalrx/agent_assets/skills/nature-figure/references/r-workflow.md +161 -0
- evalrx/agent_assets/skills/nature-figure/references/tutorials.md +251 -0
- evalrx/agent_assets/skills/nature-figure/static/core/contract.md +29 -0
- evalrx/agent_assets/skills/nature-figure/static/core/stance.md +37 -0
- evalrx/agent_assets/skills/nature-figure/static/fragments/backend/python.md +37 -0
- evalrx/agent_assets/skills/nature-figure/static/fragments/backend/r.md +44 -0
- evalrx/agent_assets/skills/outcome-driver-analysis/SKILL.md +213 -0
- evalrx/agent_assets/skills/outcome-driver-analysis/assets/analysis_report_template.md +53 -0
- evalrx/agent_assets/skills/outcome-driver-analysis/references/model_selection.md +72 -0
- evalrx/agent_assets/skills/outcome-driver-analysis/scripts/explanatory_var_eda.R +130 -0
- evalrx/agent_assets/skills/outcome-driver-analysis/scripts/explanatory_var_eda.py +150 -0
- evalrx/agent_assets/skills/outcome-driver-analysis/scripts/fit_outcome_model.R +181 -0
- evalrx/agent_assets/skills/outcome-driver-analysis/scripts/fit_outcome_model.py +186 -0
- evalrx/agent_assets/skills/outcome-driver-analysis/scripts/univariate_eda.R +149 -0
- evalrx/agent_assets/skills/outcome-driver-analysis/scripts/univariate_eda.py +177 -0
- evalrx/agent_assets/skills.py +27 -0
- evalrx/agent_runtime/__init__.py +78 -0
- evalrx/agent_runtime/_docker_runner.py +89 -0
- evalrx/agent_runtime/cli_runtime.py +103 -0
- evalrx/agent_runtime/cli_transcript.py +138 -0
- evalrx/agent_runtime/cli_types.py +68 -0
- evalrx/agent_runtime/codegen/__init__.py +5 -0
- evalrx/agent_runtime/codegen/runner.py +94 -0
- evalrx/agent_runtime/experiment_harness.py +117 -0
- evalrx/agent_runtime/factory.py +102 -0
- evalrx/agent_runtime/json_shape.py +44 -0
- evalrx/agent_runtime/judges/__init__.py +28 -0
- evalrx/agent_runtime/judges/agy.py +179 -0
- evalrx/agent_runtime/judges/autodetect.py +135 -0
- evalrx/agent_runtime/judges/claude.py +159 -0
- evalrx/agent_runtime/judges/codex.py +120 -0
- evalrx/agent_runtime/providers/__init__.py +21 -0
- evalrx/agent_runtime/providers/antigravity.py +31 -0
- evalrx/agent_runtime/providers/base.py +145 -0
- evalrx/agent_runtime/providers/claude_code.py +49 -0
- evalrx/agent_runtime/providers/codex.py +37 -0
- evalrx/agent_runtime/providers/gemini_cli.py +26 -0
- evalrx/agent_runtime/providers/kimi_cli.py +27 -0
- evalrx/agent_runtime/providers/opencode.py +27 -0
- evalrx/agent_runtime/providers/registry.py +58 -0
- evalrx/agent_runtime/sandbox.py +517 -0
- evalrx/agent_runtime/skill_audit.py +143 -0
- evalrx/agent_runtime/skills/__init__.py +19 -0
- evalrx/agent_runtime/skills/installer.py +68 -0
- evalrx/agent_runtime/skills/prompt_policy.py +86 -0
- evalrx/agent_runtime/skills/resolver.py +19 -0
- evalrx/analysis/__init__.py +132 -0
- evalrx/analysis/adjudicate.py +154 -0
- evalrx/analysis/analysis_module.py +361 -0
- evalrx/analysis/api.py +171 -0
- evalrx/analysis/case_studio.py +651 -0
- evalrx/analysis/cli.py +114 -0
- evalrx/analysis/dashboard.py +350 -0
- evalrx/analysis/eval_case_matrix.py +118 -0
- evalrx/analysis/eval_viz_theme.py +833 -0
- evalrx/analysis/explore_run.py +333 -0
- evalrx/analysis/explorer.py +1276 -0
- evalrx/analysis/failure_modes.py +607 -0
- evalrx/analysis/fused_pipeline.py +489 -0
- evalrx/analysis/holdout.py +300 -0
- evalrx/analysis/hypothesis_agent.py +230 -0
- evalrx/analysis/narration.py +177 -0
- evalrx/analysis/operationalize.py +442 -0
- evalrx/analysis/plain_language.py +42 -0
- evalrx/analysis/planner.py +283 -0
- evalrx/analysis/probe_search.py +203 -0
- evalrx/analysis/profile.py +268 -0
- evalrx/analysis/prompts/__init__.py +0 -0
- evalrx/analysis/prompts/explorer.py +417 -0
- evalrx/analysis/prompts/failure_modes.py +33 -0
- evalrx/analysis/prompts/holdout.py +27 -0
- evalrx/analysis/prompts/hypothesis_agent.py +78 -0
- evalrx/analysis/prompts/run_codebase.py +47 -0
- evalrx/analysis/prompts/stats_agent.py +72 -0
- evalrx/analysis/prompts/stats_tool_generator.py +43 -0
- evalrx/analysis/result_marker.py +47 -0
- evalrx/analysis/run_codebase.py +242 -0
- evalrx/analysis/run_view.py +205 -0
- evalrx/analysis/stage_views.py +93 -0
- evalrx/analysis/stats_agent.py +944 -0
- evalrx/analysis/stats_tool_agent.py +261 -0
- evalrx/analysis/stats_tool_generator.py +415 -0
- evalrx/analysis/stats_tools.py +1153 -0
- evalrx/analysis/trajectory_records.py +193 -0
- evalrx/analysis/workbench.py +431 -0
- evalrx/analyzers/__init__.py +42 -0
- evalrx/analyzers/agent/__init__.py +25 -0
- evalrx/analyzers/agent/counterfactual.py +84 -0
- evalrx/analyzers/agent/first_error_judge.py +96 -0
- evalrx/analyzers/agent/ignored_obs.py +81 -0
- evalrx/analyzers/agent/loop_detect.py +79 -0
- evalrx/analyzers/agent/reliability.py +165 -0
- evalrx/analyzers/agent/tool_shap.py +225 -0
- evalrx/analyzers/agent/trajectory_rubric.py +168 -0
- evalrx/analyzers/attention/__init__.py +19 -0
- evalrx/analyzers/attention/relative_attn.py +610 -0
- evalrx/analyzers/attention/rollout.py +73 -0
- evalrx/analyzers/attention/sink.py +56 -0
- evalrx/analyzers/attention/summary.py +190 -0
- evalrx/analyzers/attribution/__init__.py +6 -0
- evalrx/analyzers/attribution/generic_attn.py +31 -0
- evalrx/analyzers/attribution/gradcam.py +30 -0
- evalrx/analyzers/base.py +12 -0
- evalrx/analyzers/geometry/__init__.py +6 -0
- evalrx/analyzers/geometry/cka.py +70 -0
- evalrx/analyzers/geometry/linear_probe.py +157 -0
- evalrx/analyzers/hallucination/__init__.py +9 -0
- evalrx/analyzers/hallucination/chair.py +78 -0
- evalrx/analyzers/hallucination/opera.py +29 -0
- evalrx/analyzers/hallucination/pope.py +119 -0
- evalrx/analyzers/hallucination/selfcheck.py +155 -0
- evalrx/analyzers/hallucination/vcd.py +29 -0
- evalrx/analyzers/lens/__init__.py +7 -0
- evalrx/analyzers/lens/layer_contrast.py +133 -0
- evalrx/analyzers/lens/logit_lens.py +138 -0
- evalrx/analyzers/lens/tuned_lens.py +30 -0
- evalrx/analyzers/patching/__init__.py +5 -0
- evalrx/analyzers/patching/causal_trace.py +30 -0
- evalrx/analyzers/perturbation/__init__.py +23 -0
- evalrx/analyzers/perturbation/_shapley.py +54 -0
- evalrx/analyzers/perturbation/context_shap.py +174 -0
- evalrx/analyzers/perturbation/cot_faithfulness.py +239 -0
- evalrx/analyzers/perturbation/format_sensitivity.py +237 -0
- evalrx/analyzers/perturbation/mm_shap.py +146 -0
- evalrx/analyzers/perturbation/modality_ablation.py +196 -0
- evalrx/analyzers/perturbation/perturbation_battery.py +274 -0
- evalrx/analyzers/perturbation/prompt_contrast.py +265 -0
- evalrx/analyzers/perturbation/rise.py +94 -0
- evalrx/analyzers/perturbation/vl_shap.py +102 -0
- evalrx/analyzers/reasoning/__init__.py +33 -0
- evalrx/analyzers/reasoning/_text.py +328 -0
- evalrx/analyzers/reasoning/answer_extraction_audit.py +327 -0
- evalrx/analyzers/reasoning/arith_audit.py +226 -0
- evalrx/analyzers/reasoning/contamination.py +214 -0
- evalrx/analyzers/reasoning/knowledge_split.py +253 -0
- evalrx/analyzers/reasoning/self_repair.py +246 -0
- evalrx/analyzers/reasoning/step_rollout_value.py +216 -0
- evalrx/analyzers/reasoning/termination_audit.py +258 -0
- evalrx/analyzers/uncertainty/__init__.py +18 -0
- evalrx/analyzers/uncertainty/calibration.py +174 -0
- evalrx/analyzers/uncertainty/coverage_gap.py +199 -0
- evalrx/analyzers/uncertainty/entropy.py +90 -0
- evalrx/analyzers/uncertainty/logprob_entropy.py +69 -0
- evalrx/analyzers/uncertainty/self_consistency.py +204 -0
- evalrx/analyzers/uncertainty/verbalized_conf.py +64 -0
- evalrx/cli.py +411 -0
- evalrx/config.py +77 -0
- evalrx/contract/__init__.py +179 -0
- evalrx/contract/common.py +452 -0
- evalrx/contract/emit.py +948 -0
- evalrx/contract/export.py +237 -0
- evalrx/contract/m1.py +325 -0
- evalrx/contract/m2.py +317 -0
- evalrx/contract/m3.py +165 -0
- evalrx/contract/m4.py +130 -0
- evalrx/contract/m5.py +292 -0
- evalrx/contract/methodology.py +76 -0
- evalrx/contract/pre_m1.py +58 -0
- evalrx/contract/typescript.py +140 -0
- evalrx/core/__init__.py +85 -0
- evalrx/core/analyzer.py +174 -0
- evalrx/core/capability.py +54 -0
- evalrx/core/case.py +443 -0
- evalrx/core/experiment.py +106 -0
- evalrx/core/model.py +198 -0
- evalrx/core/pipeline.py +42 -0
- evalrx/core/registry.py +142 -0
- evalrx/core/result.py +64 -0
- evalrx/core/spec.py +173 -0
- evalrx/core/tokentype.py +165 -0
- evalrx/core/tool.py +92 -0
- evalrx/datasets/__init__.py +41 -0
- evalrx/datasets/base.py +68 -0
- evalrx/datasets/gui_os.py +52 -0
- evalrx/datasets/llm_qa.py +57 -0
- evalrx/datasets/pure_qa.py +12 -0
- evalrx/datasets/vlm_qa.py +695 -0
- evalrx/datasets/web_search_qa.py +52 -0
- evalrx/eval_agent/__init__.py +341 -0
- evalrx/eval_agent/_tools.py +81 -0
- evalrx/eval_agent/ab_runner.py +50 -0
- evalrx/eval_agent/agentic/__init__.py +43 -0
- evalrx/eval_agent/agentic/actions.py +216 -0
- evalrx/eval_agent/agentic/board.py +107 -0
- evalrx/eval_agent/agentic/loop.py +190 -0
- evalrx/eval_agent/agentic/tools.py +538 -0
- evalrx/eval_agent/checkpoint.py +57 -0
- evalrx/eval_agent/cli_agent.py +59 -0
- evalrx/eval_agent/cli_skills.py +5 -0
- evalrx/eval_agent/evolution.py +396 -0
- evalrx/eval_agent/git_manager.py +215 -0
- evalrx/eval_agent/hypothesis.py +172 -0
- evalrx/eval_agent/label_quarantine.py +209 -0
- evalrx/eval_agent/legacy.py +530 -0
- evalrx/eval_agent/log_schema.py +497 -0
- evalrx/eval_agent/loop.py +2159 -0
- evalrx/eval_agent/loop_reports.py +116 -0
- evalrx/eval_agent/model_instrumentation.py +282 -0
- evalrx/eval_agent/narration.py +193 -0
- evalrx/eval_agent/nl_runner.py +460 -0
- evalrx/eval_agent/orchestrator.py +61 -0
- evalrx/eval_agent/preregister.py +93 -0
- evalrx/eval_agent/prompts/__init__.py +1 -0
- evalrx/eval_agent/prompts/agentic.py +46 -0
- evalrx/eval_agent/prompts/case_discovery.py +25 -0
- evalrx/eval_agent/prompts/diagnosis.py +125 -0
- evalrx/eval_agent/prompts/experiment_writer.py +265 -0
- evalrx/eval_agent/prompts/explore_step.py +37 -0
- evalrx/eval_agent/prompts/fix_agent.py +257 -0
- evalrx/eval_agent/prompts/hypothesis_tester.py +15 -0
- evalrx/eval_agent/prompts/nl_runner.py +38 -0
- evalrx/eval_agent/prompts/probe_agent.py +25 -0
- evalrx/eval_agent/prompts/probe_candidate_generator.py +14 -0
- evalrx/eval_agent/prompts/probe_generator.py +35 -0
- evalrx/eval_agent/prompts/whitebox_probe_generator.py +38 -0
- evalrx/eval_agent/report.py +58 -0
- evalrx/eval_agent/run_context.py +354 -0
- evalrx/eval_agent/run_log.schema.json +1215 -0
- evalrx/eval_agent/run_logger_v2.py +1764 -0
- evalrx/eval_agent/run_metadata.py +208 -0
- evalrx/eval_agent/stages/__init__.py +56 -0
- evalrx/eval_agent/stages/case_discovery.py +293 -0
- evalrx/eval_agent/stages/diagnosis.py +1017 -0
- evalrx/eval_agent/stages/experiment_writer.py +1634 -0
- evalrx/eval_agent/stages/fix_agent.py +3916 -0
- evalrx/eval_agent/stages/fix_internals.py +499 -0
- evalrx/eval_agent/stages/fix_pipeline.py +725 -0
- evalrx/eval_agent/stages/fix_tiers.py +187 -0
- evalrx/eval_agent/stages/fix_tools.py +1034 -0
- evalrx/eval_agent/stages/hypothesis_tester.py +1014 -0
- evalrx/eval_agent/stages/probe.py +439 -0
- evalrx/eval_agent/stages/probe_agent.py +1079 -0
- evalrx/eval_agent/stages/probe_candidate_generator.py +128 -0
- evalrx/eval_agent/stages/probe_generator.py +326 -0
- evalrx/eval_agent/stages/probe_search_agent.py +106 -0
- evalrx/eval_agent/stages/protocol.py +112 -0
- evalrx/eval_agent/stages/repair_catalog.py +273 -0
- evalrx/eval_agent/stages/surgery.py +524 -0
- evalrx/eval_agent/stages/whitebox_probe_generator.py +351 -0
- evalrx/eval_agent/store.py +231 -0
- evalrx/logging_utils.py +112 -0
- evalrx/models/__init__.py +161 -0
- evalrx/models/_discover.py +101 -0
- evalrx/models/agent.py +380 -0
- evalrx/models/backends/__init__.py +58 -0
- evalrx/models/backends/api.py +169 -0
- evalrx/models/backends/base.py +57 -0
- evalrx/models/backends/gemini_compat.py +579 -0
- evalrx/models/backends/hf_local.py +2074 -0
- evalrx/models/backends/openai_compat.py +301 -0
- evalrx/models/backends/vllm_offline.py +116 -0
- evalrx/models/base.py +24 -0
- evalrx/models/blackbox/__init__.py +4 -0
- evalrx/models/blackbox/agent.py +31 -0
- evalrx/models/blackbox/base.py +29 -0
- evalrx/models/blackbox/gemini.py +279 -0
- evalrx/models/blackbox/llm_api.py +17 -0
- evalrx/models/blackbox/vlm_api.py +17 -0
- evalrx/models/compose.py +66 -0
- evalrx/models/inference.py +88 -0
- evalrx/models/paper_methods/__init__.py +8 -0
- evalrx/models/paper_methods/aad.py +53 -0
- evalrx/models/paper_methods/ifcd.py +204 -0
- evalrx/models/paper_methods/pai.py +164 -0
- evalrx/models/paper_methods/tcd.py +202 -0
- evalrx/models/paper_methods/vcd.py +45 -0
- evalrx/models/paper_methods/vicrop.py +137 -0
- evalrx/models/toolcodec.py +143 -0
- evalrx/models/tools/__init__.py +20 -0
- evalrx/models/tools/perception.py +300 -0
- evalrx/models/tools/visual.py +174 -0
- evalrx/models/whitebox/__init__.py +26 -0
- evalrx/models/whitebox/agent.py +31 -0
- evalrx/models/whitebox/base.py +24 -0
- evalrx/models/whitebox/qwen.py +61 -0
- evalrx/models/whitebox/qwen2_5_omni.py +29 -0
- evalrx/models/whitebox/qwen2_audio.py +25 -0
- evalrx/models/whitebox/qwen_omni.py +53 -0
- evalrx/models/whitebox/qwen_vl.py +62 -0
- evalrx/observability/__init__.py +21 -0
- evalrx/observability/envelope.py +122 -0
- evalrx/observability/outbox.py +111 -0
- evalrx/observability/tracer.py +882 -0
- evalrx/reporting/__init__.py +28 -0
- evalrx/reporting/case_study.py +947 -0
- evalrx/reporting/compiler.py +587 -0
- evalrx/reporting/dynamic.py +1882 -0
- evalrx/reporting/html_report.py +2225 -0
- evalrx/reporting/langfuse_exporter.py +38 -0
- evalrx/reporting/langfuse_source.py +155 -0
- evalrx/reporting/model.py +151 -0
- evalrx/reporting/run_events.py +184 -0
- evalrx/reporting/server.py +557 -0
- evalrx/reporting/stages.py +58 -0
- evalrx/reporting/static_export.py +142 -0
- evalrx/reporting/web_dist/index.html +146 -0
- evalrx/specs.py +727 -0
- evalrx/stats/__init__.py +47 -0
- evalrx/stats/api.py +192 -0
- evalrx/stats/bootstrap.py +86 -0
- evalrx/stats/ebh.py +27 -0
- evalrx/stats/evalue.py +98 -0
- evalrx/stats/friedman.py +138 -0
- evalrx/stats/mcnemar.py +40 -0
- evalrx/stats/multiplicity.py +159 -0
- evalrx/stats/subset_sampling.py +55 -0
- evalrx/term_links.py +43 -0
- evalrx/viz/__init__.py +7 -0
- evalrx/viz/labels.py +77 -0
- evalrx/viz/prompts.py +39 -0
- evalrx/viz/renderer.py +590 -0
- evalrx/viz/schema.py +36 -0
- evalrx/viz/style.py +134 -0
- evalrx-0.1.2.dist-info/METADATA +532 -0
- evalrx-0.1.2.dist-info/RECORD +339 -0
- evalrx-0.1.2.dist-info/WHEEL +5 -0
- evalrx-0.1.2.dist-info/entry_points.txt +3 -0
- evalrx-0.1.2.dist-info/licenses/LICENSE +121 -0
- evalrx-0.1.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
"""Prompt templates and prompt policies for exploratory analysis."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from evalrx.agent_runtime.skills.prompt_policy import fences_hint, skills_hint
|
|
6
|
+
|
|
7
|
+
RECORDS_FILENAME = "records.json" # also read by explore_run.py / HTML report compiler
|
|
8
|
+
_RESULT_MARKER = "EXPLORATORY_RESULT_JSON="
|
|
9
|
+
|
|
10
|
+
_INTRO_AND_QUESTION = """\
|
|
11
|
+
You are an exploratory data-analysis agent (Lambda-style): given ANY tabular
|
|
12
|
+
dataset — with a binary outcome, a multi-class outcome, a continuous outcome,
|
|
13
|
+
or no outcome at all — you write Python that discovers and charts the
|
|
14
|
+
structure that actually matters, adapting the story to what the data is.
|
|
15
|
+
|
|
16
|
+
Question:
|
|
17
|
+
{question}
|
|
18
|
+
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
_DATA_ACCESS_RECORDS = """\
|
|
22
|
+
A JSON file named "{input_filename}" is in the current working directory.
|
|
23
|
+
It contains a list of row dictionaries. Data profile (the host already
|
|
24
|
+
inferred column roles/dtypes and classified the outcome below — trust this
|
|
25
|
+
over re-guessing from raw values):
|
|
26
|
+
{data_profile}
|
|
27
|
+
|
|
28
|
+
Write a self-contained Python script that performs a THOROUGH, Lambda-style
|
|
29
|
+
exploratory analysis and PRODUCES A RICH SET OF CHARTS BY DEFAULT.
|
|
30
|
+
|
|
31
|
+
Setup:
|
|
32
|
+
- reads "{input_filename}" from the current working directory
|
|
33
|
+
- may use only local Python packages (pandas / numpy / matplotlib are fine); no
|
|
34
|
+
network and no repo mutation
|
|
35
|
+
- the profile's "columns" block gives each column's role (id / outcome / group
|
|
36
|
+
/ time / predictor) and dtype; its "outcome" block ({{"present","column","kind"}})
|
|
37
|
+
tells you whether there is one and what kind it is. Do not invent an outcome
|
|
38
|
+
or a FAIL/PASS split when "outcome.present" is false.
|
|
39
|
+
|
|
40
|
+
{framing}
|
|
41
|
+
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
_DATA_ACCESS_RAW_FOLDER = """\
|
|
45
|
+
The RAW M1-style output is at "{raw_input_dir}/" in the current working
|
|
46
|
+
directory — nothing has been parsed, reshaped, or profiled for you. A
|
|
47
|
+
filesystem-level scan of what's on disk (file/dir counts, extensions, a
|
|
48
|
+
sample of entries — NOT parsed rows):
|
|
49
|
+
{folder_scan}
|
|
50
|
+
|
|
51
|
+
Write a self-contained Python script that performs a THOROUGH, Lambda-style
|
|
52
|
+
exploratory analysis and PRODUCES A RICH SET OF CHARTS BY DEFAULT.
|
|
53
|
+
|
|
54
|
+
Setup:
|
|
55
|
+
- FIRST, load and organize the raw data into ONE tidy table YOURSELF — this is
|
|
56
|
+
part of your job, not a solved input. The files under "{raw_input_dir}/" may
|
|
57
|
+
be a single file or many, and each file's JSON shape is not guaranteed: it
|
|
58
|
+
could already be a flat list of row dicts, JSONL (one JSON object per line),
|
|
59
|
+
or a dict holding scalar run/file metadata (e.g. "model", "seed") alongside
|
|
60
|
+
a list of per-case records under a conventional key such as "cases" /
|
|
61
|
+
"results" / "rows" / "items" / "data" / "examples" / "samples" — or
|
|
62
|
+
something else entirely. Inspect what is actually there before assuming a
|
|
63
|
+
shape. If a file wraps a list of per-case dicts alongside scalar metadata,
|
|
64
|
+
merge that metadata into every row it produces (e.g. a per-model file's
|
|
65
|
+
"model" field becomes a "model" column on each of that file's rows).
|
|
66
|
+
- a browser workbench bundle may also contain ``records.json`` (normalized
|
|
67
|
+
tabular rows), ``media_units.jsonl`` (file/page/time-segment metadata), and
|
|
68
|
+
a ``media/`` tree holding original images, PDFs, audio, or video. Start from
|
|
69
|
+
the normalized rows when present, join media units by source path when useful,
|
|
70
|
+
and inspect representative media only when your CLI can actually read it.
|
|
71
|
+
Do not invent semantic content for audio/video/PDF pages you could not open;
|
|
72
|
+
state the capability limitation in a caveat instead.
|
|
73
|
+
{outcome_hint}- after building the tidy table, determine whether it has a recognizable
|
|
74
|
+
outcome column (binary / categorical / continuous) or none at all — do NOT
|
|
75
|
+
invent a FAIL/PASS split when there is no such column.
|
|
76
|
+
- also write the tidy table you built to "{input_filename}" (a JSON list of
|
|
77
|
+
row dicts) in the current working directory, so it is available to whoever
|
|
78
|
+
reviews this analysis afterward.
|
|
79
|
+
- may use only local Python packages (pandas / numpy / matplotlib are fine); no
|
|
80
|
+
network and no repo mutation
|
|
81
|
+
|
|
82
|
+
{framing}
|
|
83
|
+
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
_GENERIC_FRAMING = """\
|
|
87
|
+
OUTCOME FRAMING — apply whichever case matches what you find after loading:
|
|
88
|
+
- BINARY outcome (2 distinct values in some column): call the two groups
|
|
89
|
+
FAIL and PASS and tell the FAIL-vs-PASS story — class balance; per numeric
|
|
90
|
+
signal vs FAIL/PASS (distribution view PNG + binned fail-rate curve spec);
|
|
91
|
+
a ranked bar of each signal's FAIL-vs-PASS separation; fail rate by
|
|
92
|
+
categorical group columns (group -> fail_rate, n, n_fail); signal
|
|
93
|
+
correlations; 1-2 scatter plots of the most discriminative pairs coloured
|
|
94
|
+
by outcome.
|
|
95
|
+
- CATEGORICAL outcome (3+ classes): tell the per-class story — do NOT
|
|
96
|
+
collapse it into a binary split. Class balance per class; per numeric
|
|
97
|
+
signal's distribution across classes (box/violin) plus a ranked
|
|
98
|
+
cross-class separation bar; class composition by categorical group
|
|
99
|
+
columns; signal correlations; 1-2 scatter plots coloured by class.
|
|
100
|
+
- CONTINUOUS outcome: a correlation/regression-style story — do not
|
|
101
|
+
binarize it unless the question explicitly asks for that. Outcome
|
|
102
|
+
distribution; per numeric signal vs outcome (scatter + trend line, plus a
|
|
103
|
+
binned mean-outcome curve); a ranked bar of correlation magnitude with the
|
|
104
|
+
outcome; outcome distribution by categorical group columns; predictor
|
|
105
|
+
correlation heatmap; 1-2 scatter plots of the most associated pairs.
|
|
106
|
+
- NO recognizable outcome/target column: unsupervised exploration — describe
|
|
107
|
+
structure, do NOT invent a label that isn't in the data. Missingness
|
|
108
|
+
overview; per-numeric-column distributions; per-categorical-column value
|
|
109
|
+
counts (skip columns with very high cardinality as a bar chart, note it in
|
|
110
|
+
caveats); correlation table/heatmap; 1-2 scatter plots of the most
|
|
111
|
+
correlated numeric pairs; if a group/time column exists, contrast numeric
|
|
112
|
+
distributions across it."""
|
|
113
|
+
|
|
114
|
+
_ANALYSIS_CONTRACT = """\
|
|
115
|
+
VISUAL ANALYSIS — before writing plotting code, make an explicit intermediate
|
|
116
|
+
visualization plan. The plan is part of the machine-readable output and should
|
|
117
|
+
show that YOU selected plot types from the data semantics, not from a fixed
|
|
118
|
+
template. Aim for 6-12 charts/plots that together tell the dataset's story.
|
|
119
|
+
|
|
120
|
+
First build a "visual_plan" list. Each item should be a dict:
|
|
121
|
+
{{
|
|
122
|
+
"name": "<stable artifact/chart name>",
|
|
123
|
+
"display_name": "<short human title, no raw generated/probe id>",
|
|
124
|
+
"question": "<what this visual answers>",
|
|
125
|
+
"data_shape": "<numeric-vs-binary | numeric-vs-categorical | numeric-vs-numeric | many-numeric | paired | unsupervised | ...>",
|
|
126
|
+
"plot_kind": "<chosen plot type, e.g. violin, box, strip, scatter, line, forest, heatmap, paired_slope, ECDF>",
|
|
127
|
+
"fallback_kind": "<bar|line|scatter|forest when a deterministic host chart is useful>",
|
|
128
|
+
"required_columns": ["..."],
|
|
129
|
+
"rationale": "<why this plot type fits the data and avoids misleading summaries>",
|
|
130
|
+
"disposition": "<primary|supporting|skipped>",
|
|
131
|
+
"not_promoted_reason": "<required when supporting; why this is context/diagnostic material rather than a ranked takeaway>"
|
|
132
|
+
}}
|
|
133
|
+
|
|
134
|
+
Use these decision principles (chart-type policy: a bar's filled area means
|
|
135
|
+
"amount accumulated from zero" — BARS ARE FOR COUNTS ONLY; never a rate, a
|
|
136
|
+
mean, a proportion, or an effect size — the host demotes such a bar to a line
|
|
137
|
+
or a forest plot):
|
|
138
|
+
- class balance (count per outcome class): a count table; the host draws it
|
|
139
|
+
as ONE composition strip, never two tall bars.
|
|
140
|
+
- a rate or a mean compared across a few groups (FAIL vs PASS, present vs
|
|
141
|
+
absent, ...): a group->value table WITH an "n" column — and for a RATE also
|
|
142
|
+
the numerator column (e.g. "n_fail") or explicit "ci_low"/"ci_high"; the
|
|
143
|
+
host draws <= 3 groups as a dot + 95% CI (a lollipop when no interval can
|
|
144
|
+
be formed), never as bars. A "mean_*" of per-case values gets no invented
|
|
145
|
+
interval — give ci_low/ci_high yourself if you have them.
|
|
146
|
+
- a rate/mean/effect over MORE than 3 groups or over bins: a line (binned
|
|
147
|
+
rates) or a ranked forest/dot plot (effect sizes), never bars.
|
|
148
|
+
- numeric predictor vs categorical/binary outcome: the deterministic spec is
|
|
149
|
+
the BINNED fail-rate LINE (bin -> fail_rate, with n per bin) — do NOT also
|
|
150
|
+
emit a two-group "mean of the signal by outcome" spec for it; the
|
|
151
|
+
distribution view (violin/box/strip by outcome) is a rich PNG you draw.
|
|
152
|
+
- binned numeric trend (event rate, or mean of a continuous outcome): line
|
|
153
|
+
over ordered bins/percentiles.
|
|
154
|
+
- numeric vs numeric: scatter, optionally colored/stratified by outcome or group.
|
|
155
|
+
- many numeric signals: ranked effect/association DOT plot (forest) plus
|
|
156
|
+
correlation heatmap — never green/grey effect bars.
|
|
157
|
+
- paired/intervention data: paired slope or discordant-count visual.
|
|
158
|
+
- no outcome column: prioritize distributions, missingness, correlation
|
|
159
|
+
structure, and group contrasts over any label-vs-label story.
|
|
160
|
+
- skip a planned visual when required columns are absent or sample size makes it
|
|
161
|
+
misleading; say so in caveats.
|
|
162
|
+
- A ``primary`` visual MUST be cited by at least one takeaway's ``chart_names``.
|
|
163
|
+
Use ``supporting`` only for context/diagnostic material and give a concrete
|
|
164
|
+
``not_promoted_reason``. Do not emit an artifact for a ``skipped`` visual.
|
|
165
|
+
|
|
166
|
+
For EVERY chart you report in "charts":
|
|
167
|
+
- write its plotted data as a CSV under "tables/<name>.csv"
|
|
168
|
+
- add a spec {{"name","display_name","kind","data","x","y","title"}} with data="tables/<name>.csv"
|
|
169
|
+
and kind in {{"bar","line","scatter","forest"}}. The HOST renders these deterministically,
|
|
170
|
+
so PRE-AGGREGATE distributions into the CSV (histogram = bin->count; outcome
|
|
171
|
+
rate or mean-outcome curve = bin->value plus n; group comparison =
|
|
172
|
+
group->value plus n, and for a rate its numerator or ci_low/ci_high) —
|
|
173
|
+
never rely on a raw dump. The host picks the chart FORM from the table
|
|
174
|
+
(composition strip for class counts, dot + CI for <= 3 groups, line for
|
|
175
|
+
bins, forest plot for ranked effects, bars only for raw counts — a
|
|
176
|
+
kind="bar" whose y is a rate/mean/effect is demoted automatically) and
|
|
177
|
+
colours FAIL/PASS with the house hues, so name outcome groups exactly
|
|
178
|
+
"FAIL" / "PASS".
|
|
179
|
+
ADDITIONALLY you MAY draw richer figures (box / violin / heatmap / scatter-matrix)
|
|
180
|
+
directly as PNG under "figures/" and list them in "plots"; a figure-styling skill
|
|
181
|
+
(when available) will make these publication-quality.
|
|
182
|
+
|
|
183
|
+
This is PURE EXPLORATORY DATA ANALYSIS. Describe what the data shows. Do NOT
|
|
184
|
+
propose causal explanations, do NOT claim anything is "confirmed" or
|
|
185
|
+
"validated", and do NOT frame findings as hypotheses to be tested — hypothesis
|
|
186
|
+
generation and validation are a different, separate step that this tool does
|
|
187
|
+
not perform. Stick to descriptive, evidence-grounded statements.
|
|
188
|
+
|
|
189
|
+
Plain-language framing of the question (the dashboard's page headline, so it
|
|
190
|
+
renders BEFORE any takeaway):
|
|
191
|
+
- "plain_question": restate the Question above in ONE everyday sentence — what
|
|
192
|
+
is actually being investigated, in plain words a non-technical reader would
|
|
193
|
+
understand, not a compressed research-question shorthand. The caller's own
|
|
194
|
+
question may itself be dense/technical (column names, stats jargon, a
|
|
195
|
+
numbered list of sub-asks); your job is to say in plain terms what it's
|
|
196
|
+
really asking, not to copy it. Same jargon/acronym/symbol ban as
|
|
197
|
+
"plain_title" below, and it is checked the same way.
|
|
198
|
+
|
|
199
|
+
Reader-friendly writing contract:
|
|
200
|
+
- Write for a user who may understand the evaluation problem but may NOT know
|
|
201
|
+
machine-learning or statistics terms. Prefer concrete, plain language over
|
|
202
|
+
terms like "rank-biserial", "AUC", "VIF", "collinearity", "effect size",
|
|
203
|
+
"bootstrap", or "regression" in reader-facing titles and summaries. If one of
|
|
204
|
+
those terms is unavoidable, define it immediately in the same sentence.
|
|
205
|
+
- Separate three ideas in every reader-facing explanation: what was observed,
|
|
206
|
+
why it matters for the user's question, and what remains uncertain.
|
|
207
|
+
- Use raw counts alongside percentages whenever you can, e.g. "24 of 30 cases
|
|
208
|
+
(80%)" rather than only "80%". For group comparisons, name both groups and
|
|
209
|
+
their sample sizes.
|
|
210
|
+
- Never imply that an observed relationship proves a cause. Use wording like
|
|
211
|
+
"is linked with", "appears more often with", or "is a candidate signal", not
|
|
212
|
+
"drives", "causes", or "explains", unless an intervention actually tested it.
|
|
213
|
+
- Clearly flag weak evidence in ordinary language: small samples, missing data,
|
|
214
|
+
uneven group sizes, repeated cases, class imbalance, wide uncertainty, or
|
|
215
|
+
thresholds chosen on the same exploration rows.
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
Takeaways (THE PRIMARY OUTPUT — this is what a reader sees first):
|
|
219
|
+
- "takeaways": a ranked list of 4-8 dicts, most important/surprising finding
|
|
220
|
+
first, each shaped exactly like:
|
|
221
|
+
{{"plain_title": "<the SAME finding as 'title' below, restated in ONE
|
|
222
|
+
everyday sentence a non-technical reader (a PM, not a
|
|
223
|
+
statistician) can understand at a glance. NO acronyms
|
|
224
|
+
(AUC, ROC, CI, ECDF...), NO statistics jargon
|
|
225
|
+
(collinear, logistic, coefficient, p-value, quantile,
|
|
226
|
+
monotonic, confound, variance, latent, mediator...),
|
|
227
|
+
NO symbols (→, ρ, σ). Numbers/percentages ARE
|
|
228
|
+
encouraged — plain language does not mean vague; keep
|
|
229
|
+
the evidence, drop the notation. This is the headline
|
|
230
|
+
a reader sees first; it is checked automatically and a
|
|
231
|
+
jargon-y or copy-pasted one is sent back for a
|
|
232
|
+
rewrite.>",
|
|
233
|
+
"title": "<one concise companion sentence with the precise technical
|
|
234
|
+
detail and real counts/percentages; statistics terms are fine
|
|
235
|
+
here when they add useful precision>",
|
|
236
|
+
|
|
237
|
+
"chart_names": ["<name(s) from 'charts' or 'plots' that support it>"],
|
|
238
|
+
"table_names": ["<key(s) from 'tables' that support it, if any>"],
|
|
239
|
+
"analysis": "<2-4 plain-language sentences: (1) what was observed, (2)
|
|
240
|
+
why it matters for the user's question, and (3) what
|
|
241
|
+
remains uncertain. Cite actual counts, percentages,
|
|
242
|
+
columns, and groups behind the chart(s).>",
|
|
243
|
+
"caveat": "<short plain-language note on what this does NOT show, or '' if nothing notable>"}}
|
|
244
|
+
EVERY important chart/plot you produce should be referenced by at least one
|
|
245
|
+
takeaway's "chart_names" — never leave a chart orphaned with no explanation,
|
|
246
|
+
and never write a takeaway with no supporting chart/table unless the data
|
|
247
|
+
genuinely has none to offer (rare).
|
|
248
|
+
|
|
249
|
+
Report/dashboard contract:
|
|
250
|
+
- Emit ONE "dashboard_storyboard" panel dict (a list with one entry) orienting
|
|
251
|
+
the reader on the data/question before the takeaways:
|
|
252
|
+
{{"id": "problem_setting", "title": "Problem Setting", "summary": "...",
|
|
253
|
+
"items": ["..."], "artifact_refs": ["data_profile"]}}
|
|
254
|
+
The problem-setting summary/items must state, in plain language:
|
|
255
|
+
* what is being studied;
|
|
256
|
+
* the user's question;
|
|
257
|
+
* the unit of analysis (one row = one case/batch/request/etc.);
|
|
258
|
+
* how many records were loaded and which groups/splits are relevant;
|
|
259
|
+
* what the outcome column means in practical terms (e.g. what FAIL/PASS
|
|
260
|
+
mean, or what a continuous outcome measures).
|
|
261
|
+
Do not add "analysis" or "hypotheses" panels — "takeaways" already covers
|
|
262
|
+
that ground, and this tool does not generate hypotheses.
|
|
263
|
+
|
|
264
|
+
Secondary fields (for programmatic consumers such as a downstream confirmatory
|
|
265
|
+
pipeline — NOT the primary reader-facing narrative; keep these terse):
|
|
266
|
+
- add "chart_readings": one short dict for EVERY emitted chart or plot, keyed
|
|
267
|
+
by its exact chart name or PNG stem, with
|
|
268
|
+
{{"chart": "<name/title>", "reading": "<what a human should see>",
|
|
269
|
+
"do_not_infer": "<what this chart cannot prove>"}}. This is the explanation
|
|
270
|
+
displayed immediately below that visual; never leave it generic or omit it.
|
|
271
|
+
The reading should explain the visible pattern in one or two simple
|
|
272
|
+
sentences, name the comparison groups and sample sizes when available, and
|
|
273
|
+
avoid merely restating the axes. The do_not_infer field should name the main
|
|
274
|
+
boundary, such as "does not prove causation", "small group", "chosen on
|
|
275
|
+
exploration rows", or "missing data may affect this comparison".
|
|
276
|
+
- add "claims" only for carefully worded descriptive/confirmable statements. Each
|
|
277
|
+
claim must cite chart/signal identifiers in "evidence_ids"; set status to
|
|
278
|
+
"descriptive" (never "supported" — this tool does not confirm anything).
|
|
279
|
+
- add "critique": agent self-audit notes about leakage, small n, double-dipping,
|
|
280
|
+
missingness, misleading plot choices, or alternative explanations.
|
|
281
|
+
- Never use raw internal IDs like "generated_probe1_false_detection" as user-facing
|
|
282
|
+
chart titles or claim text. Use display names such as "Sanity check: probe
|
|
283
|
+
false-detection flag", and demote probe-derived fields to sanity-check
|
|
284
|
+
evidence rather than explanatory findings.
|
|
285
|
+
- PREFERRED: for any composite / threshold / interaction signal that is a
|
|
286
|
+
DETERMINISTIC FUNCTION of the numeric columns, attach a "recipe" so a
|
|
287
|
+
downstream confirmatory pipeline can compute it on a HELD-OUT split later
|
|
288
|
+
(this tool itself does not run that confirmation):
|
|
289
|
+
"recipe": {{"name": "<new signal key>", "kind": "expr",
|
|
290
|
+
"expr": "<boolean/numeric expression over the numeric columns above>"}}
|
|
291
|
+
The expr may use the columns BY NAME, comparisons (< <= > >= == !=), and/or/not,
|
|
292
|
+
arithmetic (+ - * / %), and abs/min/max/float/int/len. It must NOT reference the
|
|
293
|
+
label/outcome column (a recipe is a PREDICTOR, never the answer). Example:
|
|
294
|
+
"recipe": {{"name": "small_and_peripheral", "kind": "expr", "expr": "(obj_size < 40) and (focus_share < 0.3)"}}
|
|
295
|
+
Emit a recipe rather than prose whenever the candidate is computable from the columns.
|
|
296
|
+
- ALTERNATIVELY, you MAY attach host-adjudicable "sufficient" statistics computed
|
|
297
|
+
from the rows, as ONE of these shapes:
|
|
298
|
+
{{"kind": "two_group", "a": [0/1, ...], "b": [0/1, ...]}} # is_fail indicators among signal-ABSENT (a) vs signal-PRESENT (b) cases
|
|
299
|
+
{{"kind": "paired_binary", "b": <int>, "c": <int>}} # discordant counts of a paired intervention (b = flips the good way, c = the bad way)
|
|
300
|
+
Do NOT emit "reject"/"e_value"/"p_value" anywhere — this tool never adjudicates
|
|
301
|
+
a verdict itself; a self-declared verdict is ignored. Omit both for
|
|
302
|
+
descriptive-only signals.
|
|
303
|
+
- prints the final result as the LAST stdout line exactly like (note "charts" is a
|
|
304
|
+
RICH list here, one entry per CSV you wrote). The example below illustrates the
|
|
305
|
+
JSON SHAPE using a binary-outcome dataset; KEEP THE SAME KEYS but replace the
|
|
306
|
+
FAIL/PASS/fail_rate wording with language that matches the ACTUAL outcome kind
|
|
307
|
+
from the profile above (categorical classes, a continuous outcome's mean/curve,
|
|
308
|
+
or plain unsupervised structure when there is no outcome):
|
|
309
|
+
{marker}{{
|
|
310
|
+
"plain_question": "Whether small objects are harder for the model to get right.",
|
|
311
|
+
"observations": ["..."],
|
|
312
|
+
"visual_plan": [
|
|
313
|
+
{{"name": "failrate_by_objsize",
|
|
314
|
+
"display_name": "Failure rate by object size",
|
|
315
|
+
"question": "Does object size change failure risk?",
|
|
316
|
+
"data_shape": "numeric-vs-binary",
|
|
317
|
+
"plot_kind": "line",
|
|
318
|
+
"fallback_kind": "line",
|
|
319
|
+
"required_columns": ["obj_size", "label"],
|
|
320
|
+
"rationale": "Ordered bins show risk trend without assuming linearity.",
|
|
321
|
+
"disposition": "primary",
|
|
322
|
+
"not_promoted_reason": ""}}
|
|
323
|
+
],
|
|
324
|
+
"takeaways": [
|
|
325
|
+
{{"plain_title": "Small objects trip up the model much more often than big ones.",
|
|
326
|
+
"title": "Small-object cases failed in 18 of 100 rows (18%), compared with 4 of 100 larger-object rows (4%).",
|
|
327
|
+
|
|
328
|
+
"chart_names": ["failrate_by_objsize"],
|
|
329
|
+
"table_names": [],
|
|
330
|
+
"analysis": "The chart compares small-object cases with larger-object cases. Small-object cases failed in 18 of 100 rows (18%), compared with 4 of 100 larger-object rows (4%). This matters because it points to a concrete group of cases to inspect next, but the chart does not show whether object size itself is the reason for the failures.",
|
|
331
|
+
"caveat": "Descriptive only — other differences between the two groups may be responsible, and this is not a causal finding."}}
|
|
332
|
+
],
|
|
333
|
+
"chart_readings": [
|
|
334
|
+
{{"chart": "failrate_by_objsize",
|
|
335
|
+
"reading": "The smallest object-size bins have visibly higher failure rates than the larger-object bins. Include the number of cases in each bin so the reader can see whether the comparison is based on enough data.",
|
|
336
|
+
"do_not_infer": "This chart does not prove object size causes the error; it only shows where failures are more common in these rows."}}
|
|
337
|
+
],
|
|
338
|
+
"claims": [
|
|
339
|
+
{{"id": "C1",
|
|
340
|
+
"text": "Small object size is a descriptive failure correlate.",
|
|
341
|
+
"status": "descriptive",
|
|
342
|
+
"evidence_ids": ["chart:failrate_by_objsize"],
|
|
343
|
+
"interpretation": "A candidate signal for downstream confirmatory analysis.",
|
|
344
|
+
"do_not_infer": "Not causal; not yet confirmed by any statistical test."}}
|
|
345
|
+
],
|
|
346
|
+
"dashboard_storyboard": [
|
|
347
|
+
{{"id": "problem_setting", "title": "Problem Setting",
|
|
348
|
+
"summary": "This run studies labeled model-evaluation cases to find which recorded signals are linked with failures.",
|
|
349
|
+
"items": ["User question: which case features are linked with FAIL outcomes?", "Unit of analysis: one row is one evaluated case.", "Outcome: FAIL means the model gave the wrong answer; PASS means it answered correctly.", "Report the number of loaded rows and the FAIL/PASS counts here."],
|
|
350
|
+
"artifact_refs": ["data_profile"]}}
|
|
351
|
+
],
|
|
352
|
+
"candidate_signals": [
|
|
353
|
+
{{"name": "...", "display_name": "<human-readable signal label>",
|
|
354
|
+
"rationale": "...", "suggested_test": "...",
|
|
355
|
+
"recipe": {{"name": "...", "kind": "expr",
|
|
356
|
+
"expr": "(col_a < 40) and (col_b < 0.3)"}}}}
|
|
357
|
+
],
|
|
358
|
+
"plots": ["figures/corr_heatmap.png"],
|
|
359
|
+
"tables": {{}},
|
|
360
|
+
"charts": [
|
|
361
|
+
{{"name": "class_balance", "kind": "bar",
|
|
362
|
+
"display_name": "FAIL/PASS case balance",
|
|
363
|
+
"data": "tables/class_balance.csv", "x": "outcome", "y": "count",
|
|
364
|
+
"title": "FAIL vs PASS"}},
|
|
365
|
+
{{"name": "failrate_by_objsize", "kind": "line",
|
|
366
|
+
"display_name": "Failure rate by object size",
|
|
367
|
+
"data": "tables/failrate_by_objsize.csv", "x": "obj_size_bin",
|
|
368
|
+
"y": "fail_rate", "title": "Fail rate by object size"}},
|
|
369
|
+
{{"name": "top_discriminators", "kind": "bar",
|
|
370
|
+
"data": "tables/top_discriminators.csv", "x": "signal",
|
|
371
|
+
"y": "separation", "title": "Top FAIL/PASS discriminators"}}
|
|
372
|
+
],
|
|
373
|
+
"caveats": ["..."],
|
|
374
|
+
"critique": ["..."],
|
|
375
|
+
"recommended_confirmatory_tests": ["..."]
|
|
376
|
+
}}
|
|
377
|
+
{skills_hint}
|
|
378
|
+
Return ONLY the Python code{fences_hint}."""
|
|
379
|
+
|
|
380
|
+
_GENERATE_PROMPT_RECORDS = _INTRO_AND_QUESTION + _DATA_ACCESS_RECORDS + _ANALYSIS_CONTRACT
|
|
381
|
+
_GENERATE_PROMPT_RAW_FOLDER = _INTRO_AND_QUESTION + _DATA_ACCESS_RAW_FOLDER + _ANALYSIS_CONTRACT
|
|
382
|
+
|
|
383
|
+
_REPAIR_PROMPT = """\
|
|
384
|
+
The exploratory analysis script failed or produced an invalid result.
|
|
385
|
+
|
|
386
|
+
Question:
|
|
387
|
+
{question}
|
|
388
|
+
|
|
389
|
+
Data profile:
|
|
390
|
+
{data_profile}
|
|
391
|
+
|
|
392
|
+
Previous code:
|
|
393
|
+
```python
|
|
394
|
+
{code}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
Sandbox stdout:
|
|
398
|
+
{stdout}
|
|
399
|
+
|
|
400
|
+
Sandbox stderr:
|
|
401
|
+
{stderr}
|
|
402
|
+
|
|
403
|
+
Parser/execution error:
|
|
404
|
+
{error}
|
|
405
|
+
|
|
406
|
+
Rewrite the script so it succeeds end-to-end and still prints a final
|
|
407
|
+
{marker} JSON line with the required keys, in the same format as before.
|
|
408
|
+
Return ONLY Python code{fences_hint}."""
|
|
409
|
+
|
|
410
|
+
RESULT_MARKER = _RESULT_MARKER
|
|
411
|
+
GENERIC_FRAMING = _GENERIC_FRAMING
|
|
412
|
+
GENERATE_PROMPT_RECORDS = _GENERATE_PROMPT_RECORDS
|
|
413
|
+
GENERATE_PROMPT_RAW_FOLDER = _GENERATE_PROMPT_RAW_FOLDER
|
|
414
|
+
REPAIR_PROMPT = _REPAIR_PROMPT
|
|
415
|
+
|
|
416
|
+
_fences_hint = fences_hint
|
|
417
|
+
_skills_hint = skills_hint
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""Prompt template for naming failure-mode clusters."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
NAME_CLUSTERS_PROMPT = """\
|
|
6
|
+
You are an ML failure-analysis expert. Below are groups of failing cases that
|
|
7
|
+
were clustered by similarity. For each cluster, propose a short, specific
|
|
8
|
+
failure-mode name and a one-sentence description of what these cases have in
|
|
9
|
+
common. Some clusters include a "boundary contrast" section: a failing case
|
|
10
|
+
paired with its nearest successful (non-failing) counterpart. When present,
|
|
11
|
+
use these pairs to pinpoint exactly where the model's behavior crosses from
|
|
12
|
+
correct to incorrect, rather than just describing the failing topic.
|
|
13
|
+
|
|
14
|
+
{clusters_block}
|
|
15
|
+
|
|
16
|
+
Reply with EXACTLY ONE JSON array, one object per cluster listed above:
|
|
17
|
+
[{{"cluster_id": <int>, "name": "<short_snake_case_tag>", "description": "<one sentence>"}}, ...]
|
|
18
|
+
|
|
19
|
+
Return ONLY the JSON array — no prose outside it."""
|
|
20
|
+
|
|
21
|
+
ERROR_SIGNAL_PROMPT = """\
|
|
22
|
+
You are an ML failure-analysis expert. Below are (expected, observed) pairs
|
|
23
|
+
from cases where a model's output was judged incorrect. For each pair, write
|
|
24
|
+
a short phrase (5-10 words) describing the *mechanism* of the mismatch (e.g.
|
|
25
|
+
"off-by-one count", "wrong entity substituted", "missing negation"), not just
|
|
26
|
+
that it is wrong.
|
|
27
|
+
|
|
28
|
+
{pairs_block}
|
|
29
|
+
|
|
30
|
+
Reply with EXACTLY ONE JSON array, one object per pair listed above:
|
|
31
|
+
[{{"index": <int>, "error": "<short phrase>"}}, ...]
|
|
32
|
+
|
|
33
|
+
Return ONLY the JSON array — no prose outside it."""
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Prompt template for the held-out hypothesis judge (`analysis.holdout`)."""
|
|
2
|
+
|
|
3
|
+
JUDGE_PROMPT = """You are adjudicating a proposed hypothesis about failure patterns
|
|
4
|
+
in a dataset, using HELD-OUT rows the proposer never saw.
|
|
5
|
+
|
|
6
|
+
HYPOTHESIS: {statement}
|
|
7
|
+
BASIS (from the exploration phase): {basis}
|
|
8
|
+
PROPOSED TEST DESIGN: {test_design}
|
|
9
|
+
|
|
10
|
+
HELD-OUT EVIDENCE (validate split, n={n_rows}; recipe thresholds frozen from the
|
|
11
|
+
exploration phase; REJECT H0 means the signal separated the outcome groups on
|
|
12
|
+
held-out data):
|
|
13
|
+
{evidence}
|
|
14
|
+
|
|
15
|
+
Grade the hypothesis STRICTLY against this held-out evidence:
|
|
16
|
+
- "supported": the held-out statistics directly back the hypothesis's claim.
|
|
17
|
+
- "partial": the correlational part holds up but the hypothesis claims more
|
|
18
|
+
(e.g. a mechanism or causal direction) than these statistics can establish.
|
|
19
|
+
- "refuted": the held-out statistics contradict the claim.
|
|
20
|
+
- "not_testable": these observational statistics cannot decide the claim at
|
|
21
|
+
all (e.g. causal direction); it needs an intervention/surgery experiment.
|
|
22
|
+
|
|
23
|
+
Reply with ONLY a JSON object:
|
|
24
|
+
{{"verdict": "supported|partial|refuted|not_testable",
|
|
25
|
+
"reasoning": "<2-3 sentences citing the held-out numbers>",
|
|
26
|
+
"needs_surgery": true/false}}
|
|
27
|
+
"""
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"""Prompt template for the standalone M3 HypothesisAgent."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
# Column-name markers that identify agent-trajectory records (produced by
|
|
6
|
+
# evalrx.analysis.trajectory_records / the agent M1 probes). When any of
|
|
7
|
+
# these appear in the report, AGENT_TRAJECTORY_HINT is appended to the propose
|
|
8
|
+
# prompt.
|
|
9
|
+
AGENT_COLUMN_MARKERS: tuple[str, ...] = (
|
|
10
|
+
"n_tool_calls", "n_calls_", "max_consecutive_repeat", "repeated_call_frac",
|
|
11
|
+
"tool_error_rate", "tool_seq_diversity", "n_images_returned",
|
|
12
|
+
"failure_mode", "shap_outcome_", "shap_answer_",
|
|
13
|
+
"success_rate", "pass_at_k", "pass_all_k", "trajectory",
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
AGENT_TRAJECTORY_HINT = """\
|
|
17
|
+
These records describe AGENT TRAJECTORIES (a model calling tools in a loop).
|
|
18
|
+
Extra guidance for this data:
|
|
19
|
+
- Prefer hypotheses that name an INTERVENABLE cause — something a prompt or
|
|
20
|
+
scaffold change could alter: the system-prompt wording, a tool's description
|
|
21
|
+
or argument conventions, which tools are available, or the loop/stop policy.
|
|
22
|
+
Fixes for agents are black-box only, so "this part of the agent's setup
|
|
23
|
+
causes failures" is repairable, while "failures correlate with X" alone is
|
|
24
|
+
not a mechanism.
|
|
25
|
+
- Column-family semantics, where present: shap_outcome_<tool> is the causal
|
|
26
|
+
contribution of that tool to passing (measured by re-running with tool
|
|
27
|
+
subsets); success_rate / flaky / pass_at_k come from repeated runs and
|
|
28
|
+
measure stability, not capability; failure_mode is a judge-assigned label —
|
|
29
|
+
itself a hypothesis to verify, never ground truth; total_*_tokens and
|
|
30
|
+
*_latency_ms are cost.
|
|
31
|
+
- A TEST line may propose re-running the agent with a changed prompt, tool
|
|
32
|
+
description, or tool subset on held-out cases — interventions are directly
|
|
33
|
+
testable here, not just observational splits."""
|
|
34
|
+
|
|
35
|
+
PROPOSE_PROMPT = """\
|
|
36
|
+
You are a data analyst explaining candidate explanations to a general
|
|
37
|
+
audience — mostly non-technical stakeholders, not statisticians. Based on
|
|
38
|
+
the exploratory analysis below, propose specific, falsifiable hypotheses
|
|
39
|
+
that could explain the patterns found. A hypothesis is a candidate
|
|
40
|
+
explanation or mechanism — not a restatement of a finding, and not a claim
|
|
41
|
+
you are asked to prove here.
|
|
42
|
+
|
|
43
|
+
Question investigated: {question}
|
|
44
|
+
|
|
45
|
+
Key takeaways from the exploratory analysis (title: analysis):
|
|
46
|
+
{takeaways_text}
|
|
47
|
+
|
|
48
|
+
Observations:
|
|
49
|
+
{observations_text}
|
|
50
|
+
|
|
51
|
+
Candidate signals already noted:
|
|
52
|
+
{signals_text}
|
|
53
|
+
|
|
54
|
+
Propose 1-3 hypotheses. For each write exactly four lines:
|
|
55
|
+
HYPOTHESIS: <one-sentence falsifiable claim explaining a pattern above; precise language and technical terms are fine here>
|
|
56
|
+
PLAIN: <the SAME claim restated in ONE everyday sentence a non-technical reader can understand at a glance — NO acronyms (AUC, CI...), NO statistics jargon (collinear, logistic, coefficient, p-value, latent, mediator...), NO symbols. Numbers/percentages are fine and encouraged>
|
|
57
|
+
BASIS: <which takeaway(s)/signal(s) above this is grounded in>
|
|
58
|
+
TEST: <what evidence/analysis would confirm or refute this claim>
|
|
59
|
+
|
|
60
|
+
Do not repeat a takeaway verbatim — propose a CAUSE or MECHANISM behind what
|
|
61
|
+
was observed. If the findings are too thin to support any falsifiable
|
|
62
|
+
hypothesis, respond with exactly: NO_HYPOTHESIS"""
|
|
63
|
+
|
|
64
|
+
PLAIN_REPAIR_PROMPT = """\
|
|
65
|
+
Your previous answer below proposed hypotheses correctly, but some PLAIN
|
|
66
|
+
lines fail a plain-language check: PLAIN must be a jargon-free, one-sentence,
|
|
67
|
+
everyday paraphrase of the matching HYPOTHESIS line — no statistics terms,
|
|
68
|
+
acronyms, or symbols. Numbers/percentages are fine.
|
|
69
|
+
|
|
70
|
+
Previous answer:
|
|
71
|
+
{raw}
|
|
72
|
+
|
|
73
|
+
Problems found:
|
|
74
|
+
{violations}
|
|
75
|
+
|
|
76
|
+
Rewrite the FULL set of hypotheses in the exact same
|
|
77
|
+
HYPOTHESIS/PLAIN/BASIS/TEST format, fixing only the flagged PLAIN lines. Do
|
|
78
|
+
not change the HYPOTHESIS, BASIS, or TEST lines."""
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""Prompt templates for the ``run_codebase`` entry: a CLI coding agent runs a
|
|
2
|
+
user's existing evaluation/inference codebase and harvests its per-case
|
|
3
|
+
results into the records-file output contract that
|
|
4
|
+
:func:`evalrx.analysis.run_codebase.run_codebase` reads.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
RUN_PROMPT_TEMPLATE = """\
|
|
10
|
+
You are working inside a copy of a user's evaluation/inference codebase, at
|
|
11
|
+
the current working directory. Your job:
|
|
12
|
+
|
|
13
|
+
1. Understand the codebase: find its evaluation or inference entry point
|
|
14
|
+
(a script, notebook-derived script, or main/run/eval module) and whatever
|
|
15
|
+
dependencies or config it needs.
|
|
16
|
+
2. Run it so it actually executes the evaluation over its dataset. Install
|
|
17
|
+
missing lightweight dependencies if needed. If it requires resources you
|
|
18
|
+
do not have (GPU, network, missing API keys), do the best you can and
|
|
19
|
+
report what happened in your final message.
|
|
20
|
+
3. Produce a file named "{records_name}" in this directory: a JSON array or
|
|
21
|
+
JSON-Lines file with ONE ROW PER EVALUATION CASE. Each row MUST include:
|
|
22
|
+
- a "label" field: "PASS"/"FAIL" (or another clear correctness verdict
|
|
23
|
+
for the task) for that case
|
|
24
|
+
- the case's input, prediction/output, and target/expected fields, using
|
|
25
|
+
whatever field names make sense for this task
|
|
26
|
+
If the codebase already writes per-case outputs (predictions, logs, a
|
|
27
|
+
results table), read them and CONVERT them into "{records_name}" in this
|
|
28
|
+
format rather than re-running everything from scratch when that is
|
|
29
|
+
faster and equally faithful.
|
|
30
|
+
|
|
31
|
+
Do not fabricate results. If the run genuinely fails, still write
|
|
32
|
+
"{records_name}" with whatever real per-case rows you were able to produce
|
|
33
|
+
(even from a partial run), and explain the failure in your final message.
|
|
34
|
+
|
|
35
|
+
Task context supplied by the user:
|
|
36
|
+
{question}
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
REPAIR_PROMPT_TEMPLATE = """\
|
|
40
|
+
Your previous attempt did not leave a usable "{records_name}" in this
|
|
41
|
+
directory ({reason}). Look at what actually happened (error output, partial
|
|
42
|
+
results, logs) and try again: get the evaluation to run and write
|
|
43
|
+
"{records_name}" as a JSON array or JSON-Lines file, one row per case, each
|
|
44
|
+
with a "label" field plus the case's input/prediction/target fields. If a
|
|
45
|
+
full run is not possible, write whatever real partial results you have
|
|
46
|
+
rather than nothing.
|
|
47
|
+
"""
|