Lyon_chatbox / scripts /sweep_providers.py
Jacid23's picture
Rebrand app as Lyon Chatbox
dfedf76
Raw
History Blame Contribute Delete
3.28 kB
#!/usr/bin/env python3
"""Sweep all cascade providers one at a time via --autotest.
For each provider type (ASR, LLM, TTS), iterates over every provider defined
in cascade.yaml and runs `lyon-chatbox --autotest --no-camera`
with that single override, keeping defaults for the other two types.
Usage:
uv run python scripts/sweep_providers.py
uv run python scripts/sweep_providers.py --test-file scripts/my_utterances.txt
"""
import sys
import argparse
import subprocess
from pathlib import Path
import yaml
def load_providers(yaml_path: Path) -> dict[str, list[str]]:
"""Load provider names from cascade.yaml, keyed by type."""
with open(yaml_path) as f:
cfg = yaml.safe_load(f)
return {
"asr": list(cfg["asr"]["providers"].keys()),
"llm": list(cfg["llm"]["providers"].keys()),
"tts": list(cfg["tts"]["providers"].keys()),
}
def run_one(provider_type: str, provider_name: str, test_file: str | None) -> tuple[bool, str]:
"""Run autotest with a single provider override. Returns (passed, stderr_tail)."""
cmd = [
sys.executable, "-m", "lyon_chatbox.main",
"--autotest",
"--no-camera",
f"--{provider_type}-provider", provider_name,
]
if test_file:
cmd[cmd.index("--autotest")] = "--autotest"
# Replace --autotest with --autotest <file>
idx = cmd.index("--autotest")
cmd.insert(idx + 1, test_file)
result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
stderr_tail = "\n".join(result.stderr.strip().splitlines()[-20:])
return result.returncode == 0, stderr_tail
def main() -> None:
"""Run the sweep."""
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--test-file", default=None, help="Custom utterances file for --autotest")
args = parser.parse_args()
yaml_path = Path("cascade.yaml")
if not yaml_path.exists():
print("ERROR: cascade.yaml not found. Run from project root.", file=sys.stderr)
sys.exit(1)
providers = load_providers(yaml_path)
results: list[tuple[str, str, bool, str]] = []
for ptype, names in providers.items():
for name in names:
label = f"{ptype.upper()}: {name}"
print(f"--- {label} ---")
try:
passed, stderr_tail = run_one(ptype, name, args.test_file)
except subprocess.TimeoutExpired:
passed, stderr_tail = False, "TIMEOUT (120s)"
results.append((ptype, name, passed, stderr_tail))
status = "PASS" if passed else "FAIL"
print(f" -> {status}\n")
# Summary table
print("\n=== SWEEP SUMMARY ===")
print(f"{'Type':<6} {'Provider':<30} {'Status':<6}")
print("-" * 44)
n_pass = 0
for ptype, name, passed, stderr_tail in results:
status = "PASS" if passed else "FAIL"
if passed:
n_pass += 1
print(f"{ptype.upper():<6} {name:<30} {status:<6}")
if not passed and stderr_tail:
for line in stderr_tail.splitlines()[-5:]:
print(f" {line}")
total = len(results)
print(f"\n{n_pass}/{total} passed")
sys.exit(0 if n_pass == total else 1)
if __name__ == "__main__":
main()