Spaces:
Paused
Paused
File size: 11,498 Bytes
d861091 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | """The model calls, with Inference Providers replaced by a fake: backup, budget, and billing."""
from __future__ import annotations
import io
import json
import sys
from pathlib import Path
from types import SimpleNamespace
import numpy as np
import pytest
import soundfile as sf
import contract
import engine
import judges
PANEL = list(judges.DEFAULT_PANEL)
REVIEW = json.dumps({**{seat: {"quote": 0, "strength": "Real.", "concern": "Untested.",
"improvement": "Test it.", "score": 7} for seat in contract.SEATS},
**{field: "A line." for field, _ in contract.DISCUSSION}})
PRIMARY, BACKUP, LAST = (f"{route.provider}/{route.model}" for route in engine.ROUTES)
def chat_reply(content=REVIEW):
return SimpleNamespace(choices=[SimpleNamespace(message=SimpleNamespace(content=content))])
class FakeClient:
"""Stands in for InferenceClient. `script` maps a model to a reply, or to an exception to raise."""
def __init__(self, calls, script, provider=None):
self.calls, self.script, self.provider = calls, script, provider
def chat_completion(self, messages, model, **options):
route = f"{self.provider}/{model}"
self.calls.append({"model": route, "messages": messages, **options})
outcome = self.script.get(route, chat_reply())
if isinstance(outcome, Exception):
raise outcome
return outcome
def text_to_speech(self, text, model, extra_body):
self.calls.append({"model": model, "text": text, "provider": self.provider, **extra_body})
if isinstance(self.script.get(self.provider), Exception):
raise self.script[self.provider]
buffer = io.BytesIO()
sf.write(buffer, np.ones(2400, dtype="float32") * 0.1, 24000, format="WAV")
return buffer.getvalue()
def automatic_speech_recognition(self, audio, model):
self.calls.append({"model": model, "audio": audio})
outcome = self.script.get(model, SimpleNamespace(text=f" Hello from {model}. "))
if isinstance(outcome, Exception):
raise outcome
return outcome
@pytest.fixture
def providers(monkeypatch, tmp_path):
calls, script = [], {}
monkeypatch.setattr(engine, "_client", lambda provider, timeout=None: FakeClient(calls, script, provider))
monkeypatch.setattr(engine.config, "HF_TOKEN", "hf_test")
monkeypatch.setattr(engine, "BUDGET", engine.Budget(tmp_path / "spend.json", 1.80))
return calls, script
def spent(tmp_path):
return json.loads((tmp_path / "spend.json").read_text())["usd"]
# ---------------------------------------------------------------- the review
def test_the_primary_model_writes_the_review(providers):
calls, _ = providers
assert engine.review(judges.EXAMPLE_PITCH, PANEL).seats[0].score == 7
assert [c["model"] for c in calls] == [PRIMARY]
@pytest.mark.parametrize("failure", [RuntimeError("429 rate limited"), TimeoutError(), chat_reply("not json")])
def test_the_backup_answers_when_the_primary_cannot(providers, failure):
calls, script = providers
script[PRIMARY] = failure
assert engine.review(judges.EXAMPLE_PITCH, PANEL).seats[0].score == 7
assert [c["model"] for c in calls] == [PRIMARY, BACKUP]
def test_when_nobody_can_answer_the_visitor_is_told_kindly(providers):
_, script = providers
script[PRIMARY] = script[BACKUP] = script[LAST] = RuntimeError("busy")
with pytest.raises(ValueError, match="swamped"):
engine.review(judges.EXAMPLE_PITCH, PANEL)
def test_thinking_is_kept_short_on_every_route():
"""Left on, it spends the whole token budget thinking and never writes the review."""
for route in engine.ROUTES:
options = route.options
assert options.get("chat_template_kwargs", {}).get("enable_thinking") is False \
or options.get("reasoning_effort") == "low"
def test_glm_leads_and_every_route_asks_for_json():
assert engine.ROUTES[0].model == "zai-org/GLM-5.3-Flash"
formats = [route.options["response_format"]["type"] for route in engine.ROUTES]
assert all(f in ("json_object", "json_schema") for f in formats)
assert all(route.schema_in_prompt for route, f in zip(engine.ROUTES, formats) if f == "json_object")
def test_the_pitch_is_sent_as_data_not_instructions(providers):
calls, _ = providers
engine.review(judges.EXAMPLE_PITCH, PANEL)
system, user = calls[0]["messages"]
assert judges.EXAMPLE_PITCH not in system["content"]
assert json.loads(user["content"])["pitch"] == judges.EXAMPLE_PITCH
# ---------------------------------------------------------------- speech
def test_each_judge_is_voiced_in_their_own_voice_with_pauses(providers):
calls, _ = providers
rate, audio, starts = engine.speak([("investor", "One."), ("builder", "Two.")])
assert [c["voice"] for c in calls] == [judges.JUDGES["investor"].voice, judges.JUDGES["builder"].voice]
assert rate == 24000 and len(audio) == 2 * (2400 + int(engine.config.GAP_SECONDS * 24000))
assert starts == [0.0, round(0.1 + engine.config.GAP_SECONDS, 2)], "the second line starts after the first and its pause"
def test_voices_fall_back_to_the_backup_provider_with_its_own_voices(providers):
calls, script = providers
script["deepinfra"] = TimeoutError()
engine.speak([("investor", "One."), ("customer", "Two.")])
backup = [c for c in calls if c["provider"] == "fal-ai"]
assert [c["voice"] for c in backup] == [judges.JUDGES["investor"].backup_voice, judges.JUDGES["customer"].backup_voice]
def test_first_prefers_the_first_attempt_when_it_is_healthy():
assert engine._first([lambda: "primary", lambda: "backup"], head_start=1) == "primary"
def test_first_starts_the_backup_at_once_when_the_primary_fails():
def broken():
raise TimeoutError()
started = engine.time.perf_counter()
assert engine._first([broken, lambda: "backup"], head_start=30) == "backup"
assert engine.time.perf_counter() - started < 1, "a failure must not wait out the head start"
def test_first_lets_the_backup_overtake_a_stalled_primary():
def stalled():
engine.time.sleep(3)
return "primary"
started = engine.time.perf_counter()
assert engine._first([stalled, lambda: "backup"], head_start=0.2) == "backup"
assert engine.time.perf_counter() - started < 1
def test_first_raises_when_everything_fails():
def broken():
raise TimeoutError()
with pytest.raises(TimeoutError):
engine._first([broken, broken], head_start=0.1)
def test_every_judge_has_their_own_voice_and_a_backup_voice_the_backup_provider_offers():
assert len({j.voice for j in judges.JUDGES.values()}) == len(judges.JUDGES)
american = {j.backup_voice for j in judges.JUDGES.values()}
assert len(american) == len(judges.JUDGES) and all(v[:3] in ("af_", "am_") for v in american)
def test_transcription_uses_whisper_and_leaves_the_backup_idle_when_it_is_quick(providers):
calls, _ = providers
assert engine.transcribe(np.zeros(16000, dtype="float32")) == "Hello from openai/whisper-large-v3-turbo."
assert [c["model"] for c in calls] == ["openai/whisper-large-v3-turbo"], "no second bill when the first is quick"
assert str(calls[0]["audio"]).endswith(".flac")
def test_a_long_recording_gives_whisper_a_longer_head_start(providers, monkeypatch):
head_starts = []
monkeypatch.setattr(engine, "_first", lambda attempts, head_start: head_starts.append(head_start) or "Hi")
engine.transcribe(np.zeros(16000 * 60 * 4, dtype="float32"))
assert head_starts == [engine.config.ASR_HEAD_START + 4 * engine.config.ASR_SECONDS_PER_MINUTE]
def test_transcription_survives_whisper_failing(providers):
_, script = providers
script["openai/whisper-large-v3-turbo"] = TimeoutError()
assert engine.transcribe(np.zeros(16000, dtype="float32")) == "Hello from Qwen/Qwen3-ASR-1.7B."
def test_transcription_failing_everywhere_is_explained(providers):
_, script = providers
for _, model in engine.ASR:
script[model] = TimeoutError()
with pytest.raises(ValueError, match="couldn't transcribe"):
engine.transcribe(np.zeros(16000, dtype="float32"))
# ---------------------------------------------------------------- spending
def test_voices_never_run_the_backup_alongside_a_healthy_provider(providers):
calls, _ = providers
engine.speak([("investor", "One."), ("builder", "Two.")])
assert {c["provider"] for c in calls} == {"deepinfra"}
def test_audio_is_billed_by_the_second_even_when_it_fails(providers, tmp_path, monkeypatch):
clock = iter([100.0, 110.0]) # a request that hangs for ten seconds
monkeypatch.setattr(engine.time, "perf_counter", lambda: next(clock))
with pytest.raises(TimeoutError):
engine._billed("deepinfra", lambda: (_ for _ in ()).throw(TimeoutError()))
assert spent(tmp_path) == pytest.approx(10 * engine.PER_SECOND["deepinfra"])
def test_every_review_attempt_is_counted_at_its_route_price(providers, tmp_path):
_, script = providers
engine.review(judges.EXAMPLE_PITCH, PANEL)
assert spent(tmp_path) == pytest.approx(engine.ROUTES[0].cost)
script[PRIMARY] = chat_reply("") # paid for, but unreadable
engine.review(judges.EXAMPLE_PITCH + " Again.", PANEL)
assert spent(tmp_path) == pytest.approx(2 * engine.ROUTES[0].cost + engine.ROUTES[1].cost)
def test_the_den_stops_at_the_budget(providers, monkeypatch, tmp_path):
calls, _ = providers
monkeypatch.setattr(engine, "BUDGET", engine.Budget(tmp_path / "spend.json", 0.015))
engine.review(judges.EXAMPLE_PITCH, PANEL)
engine.review(judges.EXAMPLE_PITCH, PANEL) # two cents: over the limit
for call in (lambda: engine.review(judges.EXAMPLE_PITCH, PANEL), lambda: engine.speak([("investor", "Hi.")]),
lambda: engine.transcribe(np.zeros(160, dtype="float32"))):
with pytest.raises(ValueError, match="budget"):
call()
assert len(calls) == 2, "nothing is sent once the budget is spent"
def test_an_account_out_of_credit_is_explained_and_unbilled(providers, tmp_path):
_, script = providers
refused = RuntimeError("402")
refused.response = SimpleNamespace(status_code=402)
for route in (PRIMARY, BACKUP, LAST):
script[route] = refused
with pytest.raises(ValueError, match="budget"):
engine.review(judges.EXAMPLE_PITCH, PANEL)
assert not (tmp_path / "spend.json").exists(), "a refused request costs nothing"
def test_spending_survives_a_restart_and_resets_each_month(providers, tmp_path):
path = tmp_path / "spend.json"
engine.Budget(path, 1.0).add(0.4)
assert engine.Budget(path, 1.0).add(0.1) == pytest.approx(0.5)
path.write_text(json.dumps({"month": "1999-01", "usd": 5}))
engine.Budget(path, 1.0).check()
def test_no_token_is_a_friendly_message_and_sends_nothing(providers, monkeypatch):
calls, _ = providers
monkeypatch.setattr(engine.config, "HF_TOKEN", "")
with pytest.raises(ValueError, match="isn't connected"):
engine.review(judges.EXAMPLE_PITCH, PANEL)
assert calls == []
|