# retoor import pytest from pydantic import ValidationError from devplacepy.services.openai_gateway import routing as r from devplacepy.services.openai_gateway.usage import pricing_from_cfg from tests.conftest import run_async class _FakeModelsResponse: def __init__(self, status_code, payload=None): self.status_code = status_code self._payload = payload def json(self): return self._payload class _FakeModelsClient: def __init__(self, status_code, payload=None, error=None): self.status_code = status_code self.payload = payload self.error = error self.requested_url = None self.headers = None async def __aenter__(self): return self async def __aexit__(self, *exc_info): return False async def get(self, url): self.requested_url = url if self.error is not None: raise self.error return _FakeModelsResponse(self.status_code, self.payload) def _patch_stealth_client(monkeypatch, fake_client): def _factory(**kwargs): fake_client.headers = kwargs.get("headers") return fake_client monkeypatch.setattr("devplacepy.stealth.stealth_async_client", _factory) def _cleanup(providers, models): for name in providers: r.provider_store.remove(name) for source in models: r.model_store.remove(source) def test_no_routes_pass_through(local_db): assert r.chat_overlay("ghost-model-xyz", {}) is None assert r.embed_overlay("ghost-embed-xyz", {}) is None assert r.image_overlay("ghost-image-xyz", {}) is None def test_chat_route_overlay_and_economy(local_db): r.provider_store.set( r.ProviderIn( name="utor", base_url="https://up.example/v1/chat/completions", api_key="k1", ) ) r.model_store.set( r.ModelRouteIn( source_model="ut-chat", provider="utor", target_model="vendor/big", kind="chat", context_window=64000, price_cache_hit_per_m=1.0, price_cache_miss_per_m=2.0, price_output_per_m=8.0, ) ) try: overlay = r.chat_overlay("ut-chat", {"gateway_model_context_map": "{}"}) assert overlay["gateway_force_model"] is True assert overlay["gateway_model"] == "vendor/big" assert overlay["gateway_upstream_url"] == "https://up.example/v1/chat/completions" assert overlay["gateway_api_key"] == "k1" assert overlay["gateway_price_output_per_m"] == 8.0 assert overlay["gateway_model_context_map"]["vendor/big"] == 64000 pricing = pricing_from_cfg(overlay) assert pricing.chat_output_per_m == 8.0 assert pricing.chat_cache_miss_per_m == 2.0 finally: _cleanup(["utor"], ["ut-chat"]) def test_resolve_fallback_returns_none_without_a_configured_fallback(local_db): r.model_store.set(r.ModelRouteIn(source_model="fb-primary", target_model="v/a")) try: assert r.resolve_fallback("fb-primary", "chat") is None finally: _cleanup([], ["fb-primary"]) def test_resolve_fallback_returns_none_for_an_unknown_source(local_db): assert r.resolve_fallback("ghost-fb-source", "chat") is None def test_resolve_fallback_rejects_self_reference(local_db): with pytest.raises(ValidationError): r.ModelRouteIn( source_model="fb-self", target_model="v/a", fallback_model="fb-self" ) def test_resolve_fallback_returns_the_configured_route(local_db): r.model_store.set( r.ModelRouteIn( source_model="fb-backup", target_model="v/backup", kind="chat" ) ) r.model_store.set( r.ModelRouteIn( source_model="fb-primary", target_model="v/primary", kind="chat", fallback_model="fb-backup", ) ) try: fallback = r.resolve_fallback("fb-primary", "chat") assert fallback is not None assert fallback.source_model == "fb-backup" assert fallback.target_model == "v/backup" finally: _cleanup([], ["fb-primary", "fb-backup"]) def test_resolve_fallback_ignores_an_inactive_fallback_route(local_db): r.model_store.set( r.ModelRouteIn( source_model="fb-backup-off", target_model="v/backup", kind="chat", is_active=False, ) ) r.model_store.set( r.ModelRouteIn( source_model="fb-primary-2", target_model="v/primary", kind="chat", fallback_model="fb-backup-off", ) ) try: assert r.resolve_fallback("fb-primary-2", "chat") is None finally: _cleanup([], ["fb-primary-2", "fb-backup-off"]) def test_resolve_fallback_ignores_a_fallback_of_a_different_kind(local_db): r.model_store.set( r.ModelRouteIn( source_model="fb-backup-embed", target_model="v/e", kind="embed" ) ) r.model_store.set( r.ModelRouteIn( source_model="fb-primary-3", target_model="v/primary", kind="chat", fallback_model="fb-backup-embed", ) ) try: assert r.resolve_fallback("fb-primary-3", "chat") is None finally: _cleanup([], ["fb-primary-3", "fb-backup-embed"]) def test_vision_merge_overlay(local_db): r.provider_store.set( r.ProviderIn( name="utvis", base_url="https://vis.example/v1/chat/completions", api_key="vk", ) ) r.model_store.set( r.ModelRouteIn( source_model="ut-vision", provider="utvis", target_model="vendor/vlm", kind="chat", vision_model="vendor/describe", price_input_per_m=0.5, ) ) try: overlay = r.chat_overlay("ut-vision", {}) assert overlay["gateway_vision_enabled"] is True assert overlay["gateway_vision_model"] == "vendor/describe" assert overlay["gateway_vision_url"] == "https://vis.example/v1/chat/completions" assert overlay["gateway_vision_key"] == "vk" assert overlay["gateway_vision_price_input_per_m"] == 0.5 finally: _cleanup(["utvis"], ["ut-vision"]) def test_image_route_and_kind_isolation(local_db): r.provider_store.set( r.ProviderIn( name="utimg", base_url="https://img.example/v1/chat/completions", api_key="ik", ) ) r.model_store.set( r.ModelRouteIn( source_model="ut-image", provider="utimg", target_model="vendor/flux", kind="image", price_input_per_m=0.05, ) ) try: overlay = r.image_overlay("ut-image", {}) assert overlay["gateway_image_model"] == "vendor/flux" assert overlay["gateway_image_url"] == "https://img.example/v1/images" assert overlay["gateway_image_key"] == "ik" assert overlay["gateway_image_price_per_call"] == 0.05 assert r.chat_overlay("ut-image", {}) is None assert r.embed_overlay("ut-image", {}) is None pricing = pricing_from_cfg(overlay) assert pricing.image_per_call == 0.05 finally: _cleanup(["utimg"], ["ut-image"]) def test_embed_route_and_kind_isolation(local_db): r.provider_store.set( r.ProviderIn( name="utemb", base_url="https://emb.example/v1/chat/completions", api_key="ek", ) ) r.model_store.set( r.ModelRouteIn( source_model="ut-embed", provider="utemb", target_model="vendor/embed", kind="embed", price_input_per_m=0.13, ) ) try: overlay = r.embed_overlay("ut-embed", {}) assert overlay["gateway_embed_model"] == "vendor/embed" assert overlay["gateway_embed_url"] == "https://emb.example/v1/embeddings" assert overlay["gateway_embed_key"] == "ek" assert overlay["gateway_embed_price_input_per_m"] == 0.13 assert r.chat_overlay("ut-embed", {}) is None finally: _cleanup(["utemb"], ["ut-embed"]) def test_inactive_route_ignored(local_db): r.model_store.set( r.ModelRouteIn( source_model="ut-off", target_model="vendor/x", kind="chat", is_active=False, ) ) try: assert r.chat_overlay("ut-off", {}) is None finally: _cleanup([], ["ut-off"]) def test_blank_provider_uses_default_upstream(local_db): r.model_store.set( r.ModelRouteIn( source_model="ut-default", target_model="vendor/def", kind="chat", price_output_per_m=3.0, ) ) try: overlay = r.chat_overlay("ut-default", {}) assert overlay["gateway_model"] == "vendor/def" assert "gateway_upstream_url" not in overlay assert "gateway_api_key" not in overlay assert overlay["gateway_price_output_per_m"] == 3.0 finally: _cleanup([], ["ut-default"]) def test_provider_with_a_client_profile_gets_extra_headers(local_db): r.provider_store.set( r.ProviderIn( name="zen", base_url="https://opencode.ai/zen/v1/chat/completions", api_key="public", client_profile="opencode", ) ) r.model_store.set( r.ModelRouteIn(source_model="ut-zen", provider="zen", target_model="kimi-k3") ) try: overlay = r.chat_overlay("ut-zen", {}) headers = overlay["gateway_extra_request_headers"] assert headers["x-opencode-client"] assert "User-Agent" in headers finally: _cleanup(["zen"], ["ut-zen"]) def test_provider_without_a_client_profile_gets_no_extra_headers(local_db): r.provider_store.set( r.ProviderIn(name="plainprov", base_url="https://up.example/v1/chat/completions") ) r.model_store.set( r.ModelRouteIn(source_model="ut-plain", provider="plainprov", target_model="vendor/x") ) try: overlay = r.chat_overlay("ut-plain", {}) assert "gateway_extra_request_headers" not in overlay finally: _cleanup(["plainprov"], ["ut-plain"]) def test_client_profile_rejects_unknown_value(): with pytest.raises(ValidationError): r.ProviderIn(name="badprofile", client_profile="not-a-real-profile") def test_tier2_and_off_peak_fields_propagate_through_overlay(local_db): r.model_store.set( r.ModelRouteIn( source_model="ut-tiered", target_model="vendor/tiered", kind="chat", price_cache_hit_per_m=0.0028, price_cache_miss_per_m=0.14, price_output_per_m=0.28, context_tier_threshold_tokens=128_000, price_output_per_m_tier2=0.56, off_peak_start_minute=990, off_peak_end_minute=30, off_peak_discount_pct=25.0, ) ) try: overlay = r.chat_overlay("ut-tiered", {}) assert overlay["gateway_context_tier_threshold_tokens"] == 128_000 assert overlay["gateway_price_output_per_m_tier2"] == 0.56 assert overlay["gateway_price_cache_hit_per_m_tier2"] is None assert overlay["gateway_off_peak_start_minute"] == 990 assert overlay["gateway_off_peak_end_minute"] == 30 assert overlay["gateway_off_peak_discount_pct"] == 25.0 pricing = pricing_from_cfg(overlay) assert pricing.context_tier_threshold_tokens == 128_000 assert pricing.chat_output_per_m_tier2 == 0.56 assert pricing.chat_cache_hit_per_m_tier2 is None assert pricing.off_peak_start_minute == 990 finally: _cleanup([], ["ut-tiered"]) def test_unrouted_request_never_gains_tier_or_off_peak_keys(local_db): assert r.chat_overlay("ghost-model-untiered", {}) is None pricing = pricing_from_cfg({}) assert pricing.context_tier_threshold_tokens == 0 assert pricing.off_peak_start_minute is None assert pricing.off_peak_end_minute is None assert pricing.chat_output_per_m_tier2 is None def test_off_peak_window_requires_both_start_and_end(): with pytest.raises(ValidationError): r.ModelRouteIn( source_model="ut-bad-window", target_model="vendor/x", off_peak_start_minute=60, ) with pytest.raises(ValidationError): r.ModelRouteIn( source_model="ut-bad-window", target_model="vendor/x", off_peak_end_minute=120, ) def test_seed_default_image_routes_is_idempotent(local_db): r.model_store.remove(r.IMAGE_SOURCE_MODEL) r.seed_default_image_routes() route = r.model_store.get(r.IMAGE_SOURCE_MODEL) assert route is not None assert route.kind == "image" assert route.target_model == r.FLUX_TARGET_MODEL r.seed_default_image_routes() assert r.model_store.get(r.IMAGE_SOURCE_MODEL).target_model == r.FLUX_TARGET_MODEL def test_seed_default_deepseek_routes_is_idempotent_and_preserves_customization( local_db, ): r.seed_default_deepseek_routes() flash = r.model_store.get("deepseek-v4-flash") pro = r.model_store.get("deepseek-v4-pro") assert flash is not None and pro is not None assert flash.price_cache_hit_per_m == 0.0028 assert flash.price_cache_miss_per_m == 0.14 assert flash.price_output_per_m == 0.28 assert flash.context_window == 1_048_576 assert pro.price_cache_hit_per_m == 0.003625 assert pro.price_cache_miss_per_m == 0.435 assert pro.price_output_per_m == 0.87 r.model_store.set( r.ModelRouteIn( source_model="deepseek-v4-pro", target_model="deepseek-v4-pro", price_output_per_m=1.23, ) ) try: r.seed_default_deepseek_routes() assert r.model_store.get("deepseek-v4-pro").price_output_per_m == 1.23 finally: r.model_store.set( r.ModelRouteIn( source_model="deepseek-v4-pro", target_model="deepseek-v4-pro", price_cache_hit_per_m=0.003625, price_cache_miss_per_m=0.435, price_output_per_m=0.87, context_window=1_048_576, ) ) def test_seed_publishes_molodetz_aliases(local_db): r.seed_default_deepseek_routes() try: molodetz = r.model_store.resolve("molodetz", "chat") molodetz_pro = r.model_store.resolve("molodetz-pro", "chat") assert molodetz is not None assert molodetz.target_model == "deepseek-v4-flash" assert molodetz_pro is not None assert molodetz_pro.target_model == "deepseek-v4-pro" sources = {row["source_model"] for row in r.model_store.list()} assert {"molodetz", "molodetz-pro"} <= sources finally: r.model_store.remove("molodetz") r.model_store.remove("molodetz-pro") def test_models_url_from_base_swaps_chat_completions(): assert ( r._models_url_from_base("https://x.example/v1/chat/completions") == "https://x.example/v1/models" ) def test_models_url_from_base_appends_when_no_chat_completions_suffix(): assert r._models_url_from_base("https://x.example/v1") == "https://x.example/v1/models" assert r._models_url_from_base("https://x.example/v1/") == "https://x.example/v1/models" def test_models_url_from_base_blank_is_blank(): assert r._models_url_from_base("") == "" assert r._models_url_from_base(" ") == "" def test_fetch_provider_models_returns_ids_on_success(local_db, monkeypatch): r.provider_store.set( r.ProviderIn( name="probeprov", base_url="https://x.example/v1/chat/completions", api_key="sk-probe", ) ) fake_client = _FakeModelsClient(200, {"data": [{"id": "vendor/a"}, {"id": "vendor/b"}]}) _patch_stealth_client(monkeypatch, fake_client) try: models = run_async(r.fetch_provider_models("probeprov")) assert models == ["vendor/a", "vendor/b"] assert fake_client.requested_url == "https://x.example/v1/models" assert fake_client.headers == {"authorization": "Bearer sk-probe"} finally: r.provider_store.remove("probeprov") def test_fetch_provider_models_uses_default_provider_when_blank(local_db, monkeypatch): monkeypatch.setattr( r, "_default_provider_credentials", lambda: ("https://default.example/v1/chat/completions", "sk-default"), ) fake_client = _FakeModelsClient(200, {"data": [{"id": "default/model"}]}) _patch_stealth_client(monkeypatch, fake_client) models = run_async(r.fetch_provider_models("")) assert models == ["default/model"] assert fake_client.requested_url == "https://default.example/v1/models" def test_fetch_provider_models_none_for_unknown_provider(local_db): assert run_async(r.fetch_provider_models("no-such-provider")) is None def test_fetch_provider_models_none_on_non_200(local_db, monkeypatch): r.provider_store.set( r.ProviderIn(name="probeprov404", base_url="https://x.example/v1/chat/completions") ) fake_client = _FakeModelsClient(404, {}) _patch_stealth_client(monkeypatch, fake_client) try: assert run_async(r.fetch_provider_models("probeprov404")) is None finally: r.provider_store.remove("probeprov404") def test_fetch_provider_models_none_on_malformed_payload(local_db, monkeypatch): r.provider_store.set( r.ProviderIn(name="probeprovbad", base_url="https://x.example/v1/chat/completions") ) fake_client = _FakeModelsClient(200, {"not_data": []}) _patch_stealth_client(monkeypatch, fake_client) try: assert run_async(r.fetch_provider_models("probeprovbad")) is None finally: r.provider_store.remove("probeprovbad") def test_fetch_provider_models_none_on_empty_list(local_db, monkeypatch): r.provider_store.set( r.ProviderIn(name="probeprovempty", base_url="https://x.example/v1/chat/completions") ) fake_client = _FakeModelsClient(200, {"data": []}) _patch_stealth_client(monkeypatch, fake_client) try: assert run_async(r.fetch_provider_models("probeprovempty")) is None finally: r.provider_store.remove("probeprovempty") def test_fetch_provider_models_none_on_network_error(local_db, monkeypatch): r.provider_store.set( r.ProviderIn(name="probeprovdown", base_url="https://x.example/v1/chat/completions") ) fake_client = _FakeModelsClient(200, error=RuntimeError("connection refused")) _patch_stealth_client(monkeypatch, fake_client) try: assert run_async(r.fetch_provider_models("probeprovdown")) is None finally: r.provider_store.remove("probeprovdown") def test_fetch_provider_models_none_when_provider_has_no_base_url(local_db): r.provider_store.set(r.ProviderIn(name="probeprovnourl", base_url="")) try: assert run_async(r.fetch_provider_models("probeprovnourl")) is None finally: r.provider_store.remove("probeprovnourl")