Skip to content
17 changes: 14 additions & 3 deletions every_eval_ever/converters/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,18 @@ The exact command for converting an example evaluation log is:
uv run --extra inspect every_eval_ever convert inspect --log_path tests/data/inspect/2026-02-07T11-26-57+00-00_gaia_4V8zHbbRKpU5Yv2BMoBcjE.json
```

Optional: pass `--supplemental_eval_details path/to/supplemental_eval_details.json` to enrich converted output. `additional_details` maps are extend-only (existing keys are preserved), while synthetic `metric_config` defaults can be overridden for these fields: `evaluation_description`, `lower_is_better`, `score_type`, `level_names`, `level_metadata`, `has_unknown_level`, `min_score`, `max_score`. Use top-level fields (`model_info`, `source_data`, `generation_config`, `agentic_eval_config`) for shared details and `evaluation_results` for per-result metric/score details keyed by `evaluation_name`.
Optional: pass `--supplemental_eval_details path/to/supplemental_eval_details.json` to enrich converted output. `additional_details` maps are extend-only (existing keys are preserved), while synthetic `metric_config` defaults can be overridden for these fields: `evaluation_description`, `lower_is_better`, `score_type`, `level_names`, `level_metadata`, `has_unknown_level`, `min_score`, `max_score`. Use top-level fields (`model_info`, `source_data`, `generation_config`, `agentic_eval_config`) for shared details and `evaluation_results` for per-result metric/score details.

An `evaluation_results` entry selects which results it applies to by either key:

| Key | Selects |
|---|---|
| `evaluation_result_id` | one result — `"<scorer>:<metric>"`, e.g. `choice:accuracy` |
| `evaluation_name` | every result of that evaluation, e.g. `inspect_evals/pubmedqa` |

`evaluation_result_id` wins where both match. An entry with neither key applies
positionally. Convert once without a supplement to see the available keys — a key
that selects nothing is logged as a warning rather than applied.

Example `supplemental_eval_details.json`:

Expand Down Expand Up @@ -74,7 +85,7 @@ Example `supplemental_eval_details.json`:
},
"evaluation_results": [
{
"evaluation_name": "inspect_evals/pubmedqa - choice",
"evaluation_result_id": "choice:accuracy",
"score_details": {
"details": {
"notes": [
Expand All @@ -100,7 +111,7 @@ Example `supplemental_eval_details.json`:
Use it with:

```bash
uv run python -m eval_converters.inspect \
uv run --extra inspect every_eval_ever convert inspect \
--log_path tests/data/inspect/data_pubmedqa_gpt4o_mini.json \
--supplemental_eval_details path/to/supplemental_eval_details.json
```
Expand Down
19 changes: 6 additions & 13 deletions every_eval_ever/converters/helm/adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
HELMInstanceLevelDataAdapter,
_evaluation_result_id,
_score_from_stat,
_stat_name_part,
)
from every_eval_ever.converters.helm.metrics import is_core_metric
from every_eval_ever.converters.helm.utils import extract_reasoning
Expand Down Expand Up @@ -513,6 +514,7 @@ def _transform_single(

metric_config = MetricConfig(
evaluation_description=metric_name,
metric_name=metric_name,
lower_is_better=False, # TODO schema.json check
score_type=ScoreType.continuous,
min_score=0,
Expand All @@ -521,19 +523,12 @@ def _transform_single(

split = getattr(stat.name, 'split', None)
perturbation = getattr(stat.name, 'perturbation', None)
name_parts = [metric_name]
if split:
name_parts.append(str(split))
if perturbation:
name_parts.append(str(perturbation))
evaluation_name = (
f'{" ".join(name_parts)} on {source_data.dataset_name}'
)
perturbation_label = _stat_name_part(perturbation)

evaluation_results.append(
EvaluationResult(
evaluation_result_id=evaluation_result_id,
evaluation_name=evaluation_name,
evaluation_name=source_data.dataset_name,
source_data=source_data,
evaluation_timestamp=evaluation_timestamp,
metric_config=metric_config,
Expand All @@ -553,10 +548,8 @@ def _transform_single(
),
details={
'count': str(getattr(stat, 'count', '')),
'split': str(split) if split else '',
'perturbation': str(perturbation)
if perturbation
else '',
'split': _stat_name_part(split) or '',
'perturbation': perturbation_label or '',
},
),
generation_config=GenerationConfig(
Expand Down
55 changes: 36 additions & 19 deletions every_eval_ever/converters/inspect/adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ def _require_inspect_dependencies() -> None:
)
from every_eval_ever.converters.inspect.instance_level_adapter import (
InspectInstanceLevelDataAdapter,
evaluation_result_id,
)
from every_eval_ever.converters.inspect.utils import (
apply_supplemental_eval_details,
Expand Down Expand Up @@ -147,11 +148,15 @@ def _build_evaluation_result(
num_samples: int = 0,
) -> EvaluationResult:
return EvaluationResult(
evaluation_name=f'{metric_info.name} on {evaluation_task_name} for scorer {scorer_name}',
evaluation_result_id=evaluation_result_id(
scorer_name, metric_info.name
),
evaluation_name=evaluation_task_name,
source_data=source_data,
evaluation_timestamp=evaluation_timestamp,
metric_config=MetricConfig(
evaluation_description=metric_info.name,
evaluation_description=f'{metric_info.name} from scorer {scorer_name}',
metric_name=metric_info.name,
lower_is_better=False, # no metadata available
score_type=ScoreType.continuous,
min_score=0,
Expand All @@ -175,8 +180,15 @@ def _extract_evaluation_results(
generation_config: GenerationConfig,
num_samples: int,
timestamp: str,
) -> List[EvaluationResult]:
) -> Tuple[List[EvaluationResult], Dict[str, List[str]]]:
"""Convert Inspect's per-scorer metrics into aggregate results.

Returns the results plus a scorer name -> `evaluation_result_id` map,
which the instance-level converter needs to emit one row per aggregate
result a sample contributed to.
"""
results: List[EvaluationResult] = []
result_ids_by_scorer: Dict[str, List[str]] = {}

for scorer in scores:
llm_grader = None
Expand Down Expand Up @@ -220,22 +232,26 @@ def _extract_evaluation_results(

scorer_name = scorer.name or scorer.scorer

results.append(
self._build_evaluation_result(
evaluation_task_name=evaluation_task_name,
scorer_name=scorer_name,
metric_info=metric_info,
llm_grader=llm_grader,
source_data=source_data,
evaluation_timestamp=timestamp,
generation_config=generation_config,
stderr_value=stderr_value,
stddev_value=stddev_value,
num_samples=num_samples,
)
result = self._build_evaluation_result(
evaluation_task_name=evaluation_task_name,
scorer_name=scorer_name,
metric_info=metric_info,
llm_grader=llm_grader,
source_data=source_data,
evaluation_timestamp=timestamp,
generation_config=generation_config,
stderr_value=stderr_value,
stddev_value=stddev_value,
num_samples=num_samples,
)
results.append(result)

if scorer_name and result.evaluation_result_id:
result_ids_by_scorer.setdefault(scorer_name, []).append(
result.evaluation_result_id
)

return results
return results, result_ids_by_scorer

# A HuggingFace repo identifier: exactly `namespace/name` with no
# extra path segments, schemes, or path-unsafe prefixes. We use an
Expand Down Expand Up @@ -634,7 +650,7 @@ def _transform_single(

evaluation_task_name = eval_spec.task_display_name or eval_spec.task

evaluation_results = (
evaluation_results, result_ids_by_scorer = (
self._extract_evaluation_results(
evaluation_task_name,
results.scores if results else [],
Expand All @@ -644,7 +660,7 @@ def _transform_single(
evaluation_unix_timestamp,
)
if results and results.scores
else []
else ([], {})
)

supplemental_eval_details = parse_supplemental_eval_details(
Expand Down Expand Up @@ -690,6 +706,7 @@ def _transform_single(
model_info.id,
raw_eval_log.samples,
getattr(raw_eval_log, 'reductions', None),
result_ids_by_scorer,
)
)

Expand Down
Loading