1212
1313class _FakeModel :
1414 """Mimics mini-swe-agent's LitellmModel low-level path used by preflight: _query returns
15- a litellm-shaped response with a .usage block."""
16- def __init__ (self , prompt = 6 , completion = 4 , raise_exc = None ):
15+ a litellm-shaped response with a .usage block; _calculate_cost is the per-call pricing ."""
16+ def __init__ (self , prompt = 6 , completion = 4 , raise_exc = None , cost_exc = None ):
1717 self ._usage = SimpleNamespace (prompt_tokens = prompt , completion_tokens = completion ,
1818 prompt_tokens_details = None )
1919 self ._raise = raise_exc
20+ self ._cost_exc = cost_exc
2021
2122 def _prepare_messages_for_api (self , messages ):
2223 return messages
@@ -27,6 +28,11 @@ def _query(self, messages):
2728 return SimpleNamespace (usage = self ._usage ,
2829 choices = [SimpleNamespace (message = SimpleNamespace (content = "OK" ))])
2930
31+ def _calculate_cost (self , response ):
32+ if self ._cost_exc is not None :
33+ raise self ._cost_exc
34+ return {"cost" : 0.001 }
35+
3036
3137def _patch (monkeypatch , * , ver = "0.6.0" , rules = ("a" , "b" ), model = None , build_exc = None ):
3238 monkeypatch .setattr (pf , "verify_pred_version" , lambda * a , ** k : ver )
@@ -43,7 +49,7 @@ class TestRunChecks:
4349 def test_all_pass (self , monkeypatch ):
4450 _patch (monkeypatch )
4551 results = pf .run_checks ("anthropic/x" , repo_dir = "/repo" )
46- assert [ok for _ , ok , _ in results ] == [True , True , True ]
52+ assert [ok for _ , ok , _ in results ] == [True , True , True , True ]
4753 assert pf .format_report (results ) is True
4854
4955 def test_pred_failure_reported (self , monkeypatch ):
@@ -71,3 +77,17 @@ def test_model_call_tokens_shown(self, monkeypatch):
7177 results = pf .run_checks ("anthropic/x" , repo_dir = "/repo" )
7278 detail = dict ((n , d ) for n , _ , d in results )["model call" ]
7379 assert "2000000 tokens" in detail
80+
81+ def test_cost_tracking_failure_fails (self , monkeypatch ):
82+ """A model missing from litellm's price map passes _query but kills the real run —
83+ preflight must catch that (the openai/kimi-for-coding failure mode)."""
84+ _patch (monkeypatch , model = _FakeModel (cost_exc = RuntimeError ("model isn't mapped yet" )))
85+ results = pf .run_checks ("anthropic/x" , repo_dir = "/repo" )
86+ call = dict ((n , (ok , d )) for n , ok , d in results )["cost tracking" ]
87+ assert call [0 ] is False and "ignore_errors" in call [1 ]
88+ assert pf .format_report (results ) is False
89+
90+ def test_no_cost_check_when_model_call_fails (self , monkeypatch ):
91+ _patch (monkeypatch , model = _FakeModel (raise_exc = RuntimeError ("401" )))
92+ results = pf .run_checks ("anthropic/x" , repo_dir = "/repo" )
93+ assert [n for n , _ , _ in results ] == ["pred binary" , "library rules" , "model call" ]
0 commit comments