Files
wehub-resource-sync 6c9c7fe7f3
CI / integration tests (3.13) (push) Failing after 1s
Commit lint / pull request title (push) Has been skipped
Docs / links (push) Failing after 1s
CI / unit tests (3.13) (push) Failing after 1s
CI / lint (push) Failing after 1s
CI / integration tests (push) Failing after 1s
CI / package build (push) Failing after 1s
Commit lint / commit messages (push) Failing after 1s
CI / unit tests (push) Failing after 1s
chore: import upstream snapshot with attribution
2026-07-13 12:24:24 +08:00

158 lines
4.5 KiB
Python

"""Benchmark configuration.
Frozen Pydantic model providing all tunable parameters for the LoCoMo
benchmark pipeline. Defaults are aligned with the upstream evaluation
reference so that numbers are directly comparable.
"""
from __future__ import annotations
import tomllib
from pathlib import Path
from typing import Literal
from pydantic import BaseModel, ConfigDict
class BenchmarkConfig(BaseModel):
"""Immutable benchmark configuration.
Args:
cascade_timeout: Max seconds to wait for cascade queue to drain after flush.
batch_size: Messages per /add request.
methods: Comma-separated search methods.
top_k: Number of episodes to retrieve per question.
eval_owner: Which speaker's memory partition to query.
answer_model: LLM model for the Answer phase.
answer_temperature: Sampling temperature for answers.
answer_max_tokens: Max output tokens per answer call.
answer_timeout: Per-request timeout (seconds) for the answer LLM.
answer_max_retries: Retry budget for the answer phase.
judge_model: LLM model for the Judge phase.
judge_temperature: Sampling temperature for judging.
judge_timeout: Per-request timeout (seconds) for the judge LLM.
judge_max_retries: Retry budget for the judge phase.
judge_runs: Independent judge evaluations per question (majority vote).
conversations_concurrency: How many conversations run at the same time.
eval_concurrency: How many questions are processed in parallel within each conversation.
"""
model_config = ConfigDict(frozen=True)
# --- EverOS server ---
cascade_timeout: int = 7200
batch_size: int = 25
# --- Search ---
methods: str = "agentic"
top_k: int = 10
eval_owner: Literal["speaker_a", "speaker_b"] = "speaker_a"
# --- Answer LLM ---
answer_model: str = "gpt-4.1-mini"
answer_temperature: float = 0.0
answer_max_tokens: int = 32768
answer_timeout: float = 300.0
answer_max_retries: int = 5
# --- Judge LLM ---
judge_model: str = "gpt-4o-mini"
judge_temperature: float = 0.0
judge_timeout: float = 300.0
judge_max_retries: int = 5
judge_runs: int = 3
# --- Concurrency ---
conversations_concurrency: int = 10
eval_concurrency: int = 20
search_concurrency: int = 5
@property
def parsed_methods(self) -> list[str]:
"""Split comma-separated methods string into a list."""
return [m.strip() for m in self.methods.split(",") if m.strip()]
@classmethod
def from_toml(
cls, name: str = "config", *, config_dir: Path | None = None
) -> BenchmarkConfig:
"""Load config from a TOML file.
Args:
name: Config name without .toml extension.
config_dir: Directory containing config files.
Falls back to ``benchmarks/`` relative to the repo root.
Raises:
FileNotFoundError: When the TOML file does not exist.
"""
if config_dir is None:
config_dir = Path(__file__).parent
path = config_dir / f"{name}.toml"
if not path.exists():
raise FileNotFoundError(f"Config file not found: {path}")
with open(path, "rb") as f:
overrides = tomllib.load(f)
return cls(**overrides)
class SearchResult(BaseModel):
"""One QA pair's search stage output."""
model_config = ConfigDict(frozen=True)
index: int
question: str
golden_answer: str
category: int | None
evidence: list[str]
episodes: list[dict]
profiles: list[dict]
search_time_s: float
method: str
class AnswerResult(BaseModel):
"""One QA pair's answer stage output."""
model_config = ConfigDict(frozen=True)
index: int
question: str
golden_answer: str
category: int | None
generated_answer: str
answer_time_s: float
answer_attempts: int
answer_tokens: int = 0
class JudgeResult(BaseModel):
"""One QA pair's judge stage output."""
model_config = ConfigDict(frozen=True)
index: int
question: str
golden_answer: str
generated_answer: str
category: int | None
is_correct: bool
judgments: list[bool]
judge_tokens: int = 0
class RunSpec(BaseModel):
"""Reproducibility snapshot serialized at run start."""
model_config = ConfigDict(frozen=True)
run_name: str
config: dict
conversations: list[int]
stages: list[str]
git_hash: str
python_version: str
everos_version: str
started_at: str