Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion simpleaudit/experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ async def _run_single_rep(
else:
fresh = {r.scenario_name: r for r in partial}
merged_results = [fresh.get(r.scenario_name, r) for r in result]
result = AuditResults(merged_results)
result = AuditResults(merged_results, meta=partial.meta)
result.timestamp = partial.timestamp
errored = [r.scenario_name for r in result if r.severity == "ERROR"]
if not errored:
Expand Down Expand Up @@ -524,6 +524,7 @@ async def run_streamed(
"judge_model": self.judge_model,
"judge_base_url": self.judge_base_url,
"judge_provider": self.judge_provider,
"judge_name": self.judge if isinstance(self.judge, str) else None,
}.items() if v is not None
} or None

Expand Down Expand Up @@ -696,6 +697,7 @@ async def run_async(
"judge_model": self.judge_model,
"judge_base_url": self.judge_base_url,
"judge_provider": self.judge_provider,
"judge_name": self.judge if isinstance(self.judge, str) else None,
}.items() if v is not None
} or None

Expand Down
25 changes: 24 additions & 1 deletion simpleaudit/model_auditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -1683,7 +1683,30 @@ async def _run_one(scenario: Dict) -> AuditResult:
if bar.total is not None and bar.n < bar.total:
bar.update(bar.total - bar.n)

return AuditResults(results)
return AuditResults(results, meta=self._run_meta(scenarios, max_turns, language))

def _run_meta(
self,
scenarios: Union[str, List[Dict]],
max_turns: Optional[int] = None,
language: str = "English",
) -> Dict[str, Any]:
"""Build the run-level metadata dict stored in the saved JSON."""
meta: Dict[str, Any] = {
"target_model": self.target_model,
"target_provider": self._target_client_config["provider"],
"judge_model": self.judge_model,
"judge_provider": self._judge_client_config["provider"],
"auditor_model": self.auditor_model,
"auditor_provider": self._auditor_client_config["provider"],
"max_turns": max_turns or self.max_turns,
"language": language,
}
if self.judge_name is not None:
meta["judge_name"] = self.judge_name
if isinstance(scenarios, str):
meta["scenario_pack"] = scenarios
return meta

def run(
self,
Expand Down
2 changes: 1 addition & 1 deletion simpleaudit/reframing.py
Original file line number Diff line number Diff line change
Expand Up @@ -1215,7 +1215,7 @@ async def grade(result: AuditResult):
target_output_tokens=result.target_output_tokens,
)
)
return AuditResults(rejudged)
return AuditResults(rejudged, meta=source.meta)


def rejudge(
Expand Down
12 changes: 9 additions & 3 deletions simpleaudit/results.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,12 @@ class AuditResults:
"pass": "🟢",
}

def __init__(self, results: List[AuditResult]):
def __init__(self, results: List[AuditResult], meta: Optional[Dict] = None):
self.results = results
self.timestamp = datetime.now().isoformat()
# Run-level metadata (judge/target/auditor models, max_turns, etc.).
# Populated by ModelAuditor.run_async / SingleTurnAuditor.run_async.
self.meta: Dict = meta or {}

def __len__(self) -> int:
return len(self.results)
Expand Down Expand Up @@ -273,7 +276,7 @@ def summary(self):
print()

def to_dict(self) -> Dict:
return {
d: Dict = {
"version": "1.0",
"timestamp": self.timestamp,
"summary": {
Expand All @@ -291,6 +294,9 @@ def to_dict(self) -> Dict:
"recommendations": self.all_recommendations,
"results": [r.to_dict() for r in self.results],
}
if self.meta:
d["meta"] = self.meta
return d

def save(self, filepath: str):
"""Save results to JSON file (atomically, so interrupts can't corrupt it)."""
Expand All @@ -309,7 +315,7 @@ def load(cls, filepath: str) -> "AuditResults":
AuditResult(**r) for r in data["results"]
]

instance = cls(results)
instance = cls(results, meta=data.get("meta"))
instance.timestamp = data.get("timestamp", instance.timestamp)
return instance

Expand Down
2 changes: 1 addition & 1 deletion simpleaudit/single_turn.py
Original file line number Diff line number Diff line change
Expand Up @@ -657,4 +657,4 @@ async def _run_one(scenario: Dict) -> AuditResult:
await asyncio.gather(*tasks, return_exceptions=True)
raise

return AuditResults(results)
return AuditResults(results, meta=self._run_meta(scenarios, max_turns, language))
Loading