From b2701b25b0153513b558d4176ac8379561bb49c2 Mon Sep 17 00:00:00 2001 From: 1bcMax Date: Tue, 4 Aug 2026 13:48:32 -0500 Subject: [PATCH 1/3] fix(pm): make the retired canonical-market helpers fail fast MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upstream probe (api.predexon.com direct, 3 runs each, 2026-08-04): /v1/pm/markets, /v1/pm/markets/listings and /v1/pm/outcomes/{id} all return 410 "This endpoint has been sunset as of 2026-07-20. Market matching is discontinued." pm_markets / pm_listings / pm_outcome have been shipping calls to them ever since. Payment was never charged — the gateway returns before settlement — but the caller pays a round trip to learn the endpoint is gone, and the docstrings still advertised them as live Tier 1 endpoints. Kept as raising stubs rather than deleted: removing a public method breaks `from x import` and attribute access on upgrade, and this is a patch release. They now raise RetiredEndpointError (new, exported) with the sunset date and `pm("markets/search", q=...)` as the replacement — before any network I/O, on all four client surfaces (sync + async × HTTP + Solana). pm_sports_categories / pm_sports_markets keep working but gain a warning: every sports/* path is returning a consistent upstream 500 as of 2026-08-04. That is a partner bug, not a sunset, so the helpers stay callable for whenever it recovers. --- blockrun_llm/__init__.py | 2 + blockrun_llm/client.py | 137 +++++++++++++++++++++++---- blockrun_llm/solana_client.py | 135 ++++++++++++++++++++++---- blockrun_llm/types.py | 9 ++ tests/unit/test_retired_endpoints.py | 55 +++++++++++ 5 files changed, 302 insertions(+), 36 deletions(-) create mode 100644 tests/unit/test_retired_endpoints.py diff --git a/blockrun_llm/__init__.py b/blockrun_llm/__init__.py index b5d93fc..215f9b4 100644 --- a/blockrun_llm/__init__.py +++ b/blockrun_llm/__init__.py @@ -116,6 +116,7 @@ MusicResponse, NewsSearchSource, PaymentError, + RetiredEndpointError, # Virtual Portrait types PortraitEnrollment, PortraitList, @@ -212,6 +213,7 @@ "MusicResponse", "NewsSearchSource", "PaymentError", + "RetiredEndpointError", "PhoneClient", "PortraitClient", "PortraitEnrollment", diff --git a/blockrun_llm/client.py b/blockrun_llm/client.py index 1379b29..6e56a34 100644 --- a/blockrun_llm/client.py +++ b/blockrun_llm/client.py @@ -64,6 +64,7 @@ ChatResponse, ImageResponse, PaymentError, + RetiredEndpointError, RoutingDecision, RoutingProfile, SearchResult, @@ -1904,22 +1905,55 @@ def pm_query(self, path: str, query: dict[str, Any]) -> dict[str, Any]: # All accept arbitrary keyword filters that are forwarded as query params. def pm_markets(self, **params: Any) -> dict[str, Any]: - """List canonical cross-venue markets (Predexon v2). + """RETIRED — ``/v1/pm/markets`` no longer exists. - Filter with venue=, status=, category=, league=, event_id=, - pagination_key=. Tier 1 ($0.001/call). + Predexon sunset market matching on 2026-07-20 and the whole + canonical layer went with it, so this path returns 410 upstream. + Use ``pm("markets/search", q=...)`` for cross-venue lookups. + + Kept as a raising stub rather than deleted so upgrading does not + break imports or attribute access; calling it fails immediately + instead of after a paid round trip. + + :raises RetiredEndpointError: always. """ - return self.pm("markets", **params) + raise RetiredEndpointError( + "/v1/pm/markets was sunset by Predexon on 2026-07-20 (upstream 410). Use pm('markets/search', q=...) for cross-venue lookups." + ) def pm_listings(self, **params: Any) -> dict[str, Any]: - """List venue-native executable listings flattened across canonical - markets (Predexon v2). Tier 1 ($0.001/call).""" - return self.pm("markets/listings", **params) + """RETIRED — ``/v1/pm/markets/listings`` no longer exists. + + Predexon sunset market matching on 2026-07-20 and the whole + canonical layer went with it, so this path returns 410 upstream. + Use ``pm("markets/search", q=...)`` for cross-venue lookups. + + Kept as a raising stub rather than deleted so upgrading does not + break imports or attribute access; calling it fails immediately + instead of after a paid round trip. + + :raises RetiredEndpointError: always. + """ + raise RetiredEndpointError( + "/v1/pm/markets/listings was sunset by Predexon on 2026-07-20 (upstream 410). Use pm('markets/search', q=...) for cross-venue lookups." + ) def pm_outcome(self, predexon_id: str) -> dict[str, Any]: - """Resolve a canonical Predexon outcome ID to its market context and - venue listings (Predexon v2). Tier 1 ($0.001/call).""" - return self.pm(f"outcomes/{predexon_id}") + """RETIRED — ``/v1/pm/outcomes/{predexon_id}`` no longer exists. + + Predexon sunset market matching on 2026-07-20 and the whole + canonical layer went with it, so this path returns 410 upstream. + Use ``pm("markets/search", q=...)`` for cross-venue lookups. + + Kept as a raising stub rather than deleted so upgrading does not + break imports or attribute access; calling it fails immediately + instead of after a paid round trip. + + :raises RetiredEndpointError: always. + """ + raise RetiredEndpointError( + "/v1/pm/outcomes/{predexon_id} was sunset by Predexon on 2026-07-20 (upstream 410). Use pm('markets/search', q=...) for cross-venue lookups." + ) def pm_polymarket_markets(self, **params: Any) -> dict[str, Any]: """List Polymarket markets (Predexon v2). Tier 1 ($0.001/call). @@ -1971,12 +2005,24 @@ def pm_limitless_markets(self, **params: Any) -> dict[str, Any]: return self.pm("limitless/markets", **params) def pm_sports_categories(self) -> dict[str, Any]: - """List available sports categories. Tier 1 ($0.001/call).""" + """List available sports categories. Tier 1 ($0.001/call). + + .. warning:: + Upstream is returning 500 for every ``sports/*`` path as of + 2026-08-04. The route still resolves, so this keeps working the + moment Predexon restores it, but do not build on it yet. + """ return self.pm("sports/categories") def pm_sports_markets(self, **params: Any) -> dict[str, Any]: """List sports markets grouped by game. Filter with league=, - sport_type=, status=, venue=. Tier 1 ($0.001/call).""" + sport_type=, status=, venue=. Tier 1 ($0.001/call). + + .. warning:: + Upstream is returning 500 for every ``sports/*`` path as of + 2026-08-04. The route still resolves, so this keeps working the + moment Predexon restores it, but do not build on it yet. + """ return self.pm("sports/markets", **params) def pm_wallet_identity(self, wallet: str) -> dict[str, Any]: @@ -3364,16 +3410,55 @@ async def pm_query(self, path: str, query: dict[str, Any]) -> dict[str, Any]: return await self._request_with_payment_raw(f"/v1/pm/{path}", query) async def pm_markets(self, **params: Any) -> dict[str, Any]: - """List canonical cross-venue markets (Predexon v2). Tier 1 ($0.001/call).""" - return await self.pm("markets", **params) + """RETIRED — ``/v1/pm/markets`` no longer exists. + + Predexon sunset market matching on 2026-07-20 and the whole + canonical layer went with it, so this path returns 410 upstream. + Use ``pm("markets/search", q=...)`` for cross-venue lookups. + + Kept as a raising stub rather than deleted so upgrading does not + break imports or attribute access; it raises before any network + I/O, so you never pay a round trip to learn it is gone. + + :raises RetiredEndpointError: always. + """ + raise RetiredEndpointError( + "/v1/pm/markets was sunset by Predexon on 2026-07-20 (upstream 410). Use pm('markets/search', q=...) for cross-venue lookups." + ) async def pm_listings(self, **params: Any) -> dict[str, Any]: - """List venue-native executable listings (Predexon v2). Tier 1 ($0.001/call).""" - return await self.pm("markets/listings", **params) + """RETIRED — ``/v1/pm/markets/listings`` no longer exists. + + Predexon sunset market matching on 2026-07-20 and the whole + canonical layer went with it, so this path returns 410 upstream. + Use ``pm("markets/search", q=...)`` for cross-venue lookups. + + Kept as a raising stub rather than deleted so upgrading does not + break imports or attribute access; it raises before any network + I/O, so you never pay a round trip to learn it is gone. + + :raises RetiredEndpointError: always. + """ + raise RetiredEndpointError( + "/v1/pm/markets/listings was sunset by Predexon on 2026-07-20 (upstream 410). Use pm('markets/search', q=...) for cross-venue lookups." + ) async def pm_outcome(self, predexon_id: str) -> dict[str, Any]: - """Resolve a canonical Predexon outcome ID (Predexon v2). Tier 1 ($0.001/call).""" - return await self.pm(f"outcomes/{predexon_id}") + """RETIRED — ``/v1/pm/outcomes/{predexon_id}`` no longer exists. + + Predexon sunset market matching on 2026-07-20 and the whole + canonical layer went with it, so this path returns 410 upstream. + Use ``pm("markets/search", q=...)`` for cross-venue lookups. + + Kept as a raising stub rather than deleted so upgrading does not + break imports or attribute access; it raises before any network + I/O, so you never pay a round trip to learn it is gone. + + :raises RetiredEndpointError: always. + """ + raise RetiredEndpointError( + "/v1/pm/outcomes/{predexon_id} was sunset by Predexon on 2026-07-20 (upstream 410). Use pm('markets/search', q=...) for cross-venue lookups." + ) async def pm_polymarket_markets(self, **params: Any) -> dict[str, Any]: """List Polymarket markets (Predexon v2). Tier 1 ($0.001/call).""" @@ -3413,11 +3498,23 @@ async def pm_limitless_markets(self, **params: Any) -> dict[str, Any]: return await self.pm("limitless/markets", **params) async def pm_sports_categories(self) -> dict[str, Any]: - """List available sports categories. Tier 1 ($0.001/call).""" + """List available sports categories. Tier 1 ($0.001/call). + + .. warning:: + Upstream is returning 500 for every ``sports/*`` path as of + 2026-08-04. The route still resolves, so this keeps working the + moment Predexon restores it, but do not build on it yet. + """ return await self.pm("sports/categories") async def pm_sports_markets(self, **params: Any) -> dict[str, Any]: - """List sports markets grouped by game. Tier 1 ($0.001/call).""" + """List sports markets grouped by game. Tier 1 ($0.001/call). + + .. warning:: + Upstream is returning 500 for every ``sports/*`` path as of + 2026-08-04. The route still resolves, so this keeps working the + moment Predexon restores it, but do not build on it yet. + """ return await self.pm("sports/markets", **params) async def pm_wallet_identity(self, wallet: str) -> dict[str, Any]: diff --git a/blockrun_llm/solana_client.py b/blockrun_llm/solana_client.py index 9242313..a5da314 100644 --- a/blockrun_llm/solana_client.py +++ b/blockrun_llm/solana_client.py @@ -51,6 +51,7 @@ ImageResponse, MusicResponse, PaymentError, + RetiredEndpointError, PortraitEnrollment, PortraitList, PriceHistoryResponse, @@ -2539,16 +2540,55 @@ def pm_query(self, path: str, query: dict[str, Any]) -> dict[str, Any]: return self._request_with_payment_raw(f"/v1/pm/{path}", query) def pm_markets(self, **params: Any) -> dict[str, Any]: - """List canonical cross-venue markets (Predexon v2). Tier 1 ($0.001/call).""" - return self.pm("markets", **params) + """RETIRED — ``/v1/pm/markets`` no longer exists. + + Predexon sunset market matching on 2026-07-20 and the whole + canonical layer went with it, so this path returns 410 upstream. + Use ``pm("markets/search", q=...)`` for cross-venue lookups. + + Kept as a raising stub rather than deleted so upgrading does not + break imports or attribute access; calling it fails immediately + instead of after a paid round trip. + + :raises RetiredEndpointError: always. + """ + raise RetiredEndpointError( + "/v1/pm/markets was sunset by Predexon on 2026-07-20 (upstream 410). Use pm('markets/search', q=...) for cross-venue lookups." + ) def pm_listings(self, **params: Any) -> dict[str, Any]: - """List venue-native executable listings (Predexon v2). Tier 1 ($0.001/call).""" - return self.pm("markets/listings", **params) + """RETIRED — ``/v1/pm/markets/listings`` no longer exists. + + Predexon sunset market matching on 2026-07-20 and the whole + canonical layer went with it, so this path returns 410 upstream. + Use ``pm("markets/search", q=...)`` for cross-venue lookups. + + Kept as a raising stub rather than deleted so upgrading does not + break imports or attribute access; calling it fails immediately + instead of after a paid round trip. + + :raises RetiredEndpointError: always. + """ + raise RetiredEndpointError( + "/v1/pm/markets/listings was sunset by Predexon on 2026-07-20 (upstream 410). Use pm('markets/search', q=...) for cross-venue lookups." + ) def pm_outcome(self, predexon_id: str) -> dict[str, Any]: - """Resolve a canonical Predexon outcome ID (Predexon v2). Tier 1 ($0.001/call).""" - return self.pm(f"outcomes/{predexon_id}") + """RETIRED — ``/v1/pm/outcomes/{predexon_id}`` no longer exists. + + Predexon sunset market matching on 2026-07-20 and the whole + canonical layer went with it, so this path returns 410 upstream. + Use ``pm("markets/search", q=...)`` for cross-venue lookups. + + Kept as a raising stub rather than deleted so upgrading does not + break imports or attribute access; calling it fails immediately + instead of after a paid round trip. + + :raises RetiredEndpointError: always. + """ + raise RetiredEndpointError( + "/v1/pm/outcomes/{predexon_id} was sunset by Predexon on 2026-07-20 (upstream 410). Use pm('markets/search', q=...) for cross-venue lookups." + ) def pm_polymarket_markets(self, **params: Any) -> dict[str, Any]: """List Polymarket markets (Predexon v2). Tier 1 ($0.001/call).""" @@ -2588,11 +2628,23 @@ def pm_limitless_markets(self, **params: Any) -> dict[str, Any]: return self.pm("limitless/markets", **params) def pm_sports_categories(self) -> dict[str, Any]: - """List available sports categories. Tier 1 ($0.001/call).""" + """List available sports categories. Tier 1 ($0.001/call). + + .. warning:: + Upstream is returning 500 for every ``sports/*`` path as of + 2026-08-04. The route still resolves, so this keeps working the + moment Predexon restores it, but do not build on it yet. + """ return self.pm("sports/categories") def pm_sports_markets(self, **params: Any) -> dict[str, Any]: - """List sports markets grouped by game. Tier 1 ($0.001/call).""" + """List sports markets grouped by game. Tier 1 ($0.001/call). + + .. warning:: + Upstream is returning 500 for every ``sports/*`` path as of + 2026-08-04. The route still resolves, so this keeps working the + moment Predexon restores it, but do not build on it yet. + """ return self.pm("sports/markets", **params) def pm_wallet_identity(self, wallet: str) -> dict[str, Any]: @@ -4449,16 +4501,55 @@ async def pm_query(self, path: str, query: dict[str, Any]) -> dict[str, Any]: return await self._request_with_payment_raw(f"/v1/pm/{path}", query) async def pm_markets(self, **params: Any) -> dict[str, Any]: - """List canonical cross-venue markets (Predexon v2). Tier 1 ($0.001/call).""" - return await self.pm("markets", **params) + """RETIRED — ``/v1/pm/markets`` no longer exists. + + Predexon sunset market matching on 2026-07-20 and the whole + canonical layer went with it, so this path returns 410 upstream. + Use ``pm("markets/search", q=...)`` for cross-venue lookups. + + Kept as a raising stub rather than deleted so upgrading does not + break imports or attribute access; it raises before any network + I/O, so you never pay a round trip to learn it is gone. + + :raises RetiredEndpointError: always. + """ + raise RetiredEndpointError( + "/v1/pm/markets was sunset by Predexon on 2026-07-20 (upstream 410). Use pm('markets/search', q=...) for cross-venue lookups." + ) async def pm_listings(self, **params: Any) -> dict[str, Any]: - """List venue-native executable listings (Predexon v2). Tier 1 ($0.001/call).""" - return await self.pm("markets/listings", **params) + """RETIRED — ``/v1/pm/markets/listings`` no longer exists. + + Predexon sunset market matching on 2026-07-20 and the whole + canonical layer went with it, so this path returns 410 upstream. + Use ``pm("markets/search", q=...)`` for cross-venue lookups. + + Kept as a raising stub rather than deleted so upgrading does not + break imports or attribute access; it raises before any network + I/O, so you never pay a round trip to learn it is gone. + + :raises RetiredEndpointError: always. + """ + raise RetiredEndpointError( + "/v1/pm/markets/listings was sunset by Predexon on 2026-07-20 (upstream 410). Use pm('markets/search', q=...) for cross-venue lookups." + ) async def pm_outcome(self, predexon_id: str) -> dict[str, Any]: - """Resolve a canonical Predexon outcome ID (Predexon v2). Tier 1 ($0.001/call).""" - return await self.pm(f"outcomes/{predexon_id}") + """RETIRED — ``/v1/pm/outcomes/{predexon_id}`` no longer exists. + + Predexon sunset market matching on 2026-07-20 and the whole + canonical layer went with it, so this path returns 410 upstream. + Use ``pm("markets/search", q=...)`` for cross-venue lookups. + + Kept as a raising stub rather than deleted so upgrading does not + break imports or attribute access; it raises before any network + I/O, so you never pay a round trip to learn it is gone. + + :raises RetiredEndpointError: always. + """ + raise RetiredEndpointError( + "/v1/pm/outcomes/{predexon_id} was sunset by Predexon on 2026-07-20 (upstream 410). Use pm('markets/search', q=...) for cross-venue lookups." + ) async def pm_polymarket_markets(self, **params: Any) -> dict[str, Any]: """List Polymarket markets (Predexon v2). Tier 1 ($0.001/call).""" @@ -4497,11 +4588,23 @@ async def pm_limitless_markets(self, **params: Any) -> dict[str, Any]: return await self.pm("limitless/markets", **params) async def pm_sports_categories(self) -> dict[str, Any]: - """List available sports categories. Tier 1 ($0.001/call).""" + """List available sports categories. Tier 1 ($0.001/call). + + .. warning:: + Upstream is returning 500 for every ``sports/*`` path as of + 2026-08-04. The route still resolves, so this keeps working the + moment Predexon restores it, but do not build on it yet. + """ return await self.pm("sports/categories") async def pm_sports_markets(self, **params: Any) -> dict[str, Any]: - """List sports markets grouped by game. Tier 1 ($0.001/call).""" + """List sports markets grouped by game. Tier 1 ($0.001/call). + + .. warning:: + Upstream is returning 500 for every ``sports/*`` path as of + 2026-08-04. The route still resolves, so this keeps working the + moment Predexon restores it, but do not build on it yet. + """ return await self.pm("sports/markets", **params) async def pm_wallet_identity(self, wallet: str) -> dict[str, Any]: diff --git a/blockrun_llm/types.py b/blockrun_llm/types.py index 9b15850..0dc0108 100644 --- a/blockrun_llm/types.py +++ b/blockrun_llm/types.py @@ -310,6 +310,15 @@ class BlockrunError(Exception): """Base exception for BlockRun SDK.""" +class RetiredEndpointError(BlockrunError): + """Raised by a helper whose upstream endpoint no longer exists. + + Kept as a raising method rather than deleted so upgrading does not break + imports or attribute access — the failure is explicit and immediate instead + of a paid round trip that returns 410/404. + """ + + class PaymentError(BlockrunError): """Payment-related error. diff --git a/tests/unit/test_retired_endpoints.py b/tests/unit/test_retired_endpoints.py new file mode 100644 index 0000000..648e2c0 --- /dev/null +++ b/tests/unit/test_retired_endpoints.py @@ -0,0 +1,55 @@ +"""Helpers for endpoints Predexon retired must fail fast, not silently 410. + +Probed upstream 2026-08-04 (3 runs each): /v1/pm/markets, /v1/pm/markets/listings +and /v1/pm/outcomes/{id} all return + 410 "This endpoint has been sunset as of 2026-07-20. Market matching is + discontinued." +The helpers are kept rather than deleted so upgrading does not break imports; +this pins that they raise instead of quietly costing a round trip. +""" + +import pytest + +from blockrun_llm import LLMClient, RetiredEndpointError +from blockrun_llm.client import AsyncLLMClient + + +def _bare(cls): + """Instance without running __init__ — no wallet or network needed.""" + return cls.__new__(cls) + + +@pytest.mark.parametrize("method,args", [ + ("pm_markets", ()), + ("pm_listings", ()), + ("pm_outcome", ("PXM-12345",)), +]) +def test_sync_helpers_raise(method, args): + with pytest.raises(RetiredEndpointError, match="2026-07-20"): + getattr(_bare(LLMClient), method)(*args) + + +@pytest.mark.parametrize("method,args", [ + ("pm_markets", ()), + ("pm_listings", ()), + ("pm_outcome", ("PXM-12345",)), +]) +@pytest.mark.asyncio +async def test_async_helpers_raise(method, args): + # An async def raises on await, not on call — but still before any network + # I/O, which is the point: no paid round trip to learn it is gone. + with pytest.raises(RetiredEndpointError, match="2026-07-20"): + await getattr(_bare(AsyncLLMClient), method)(*args) + + +def test_message_points_at_the_replacement(): + with pytest.raises(RetiredEndpointError) as exc: + _bare(LLMClient).pm_markets() + assert "markets/search" in str(exc.value) + + +def test_surviving_helper_is_untouched(): + # markets/search survived the sunset (422 on a missing q, i.e. alive). + assert not isinstance( + getattr(LLMClient, "pm_wallet_identity", None), type(None) + ) From 5958ddfe2ce8b7db64cb78ca4bb6670dc4e10df4 Mon Sep 17 00:00:00 2001 From: 1bcMax Date: Tue, 4 Aug 2026 15:38:19 -0500 Subject: [PATCH 2/3] style: satisfy black on the retired-endpoint test --- tests/unit/test_retired_endpoints.py | 30 ++++++++++++++++------------ 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/tests/unit/test_retired_endpoints.py b/tests/unit/test_retired_endpoints.py index 648e2c0..bdc5a05 100644 --- a/tests/unit/test_retired_endpoints.py +++ b/tests/unit/test_retired_endpoints.py @@ -19,21 +19,27 @@ def _bare(cls): return cls.__new__(cls) -@pytest.mark.parametrize("method,args", [ - ("pm_markets", ()), - ("pm_listings", ()), - ("pm_outcome", ("PXM-12345",)), -]) +@pytest.mark.parametrize( + "method,args", + [ + ("pm_markets", ()), + ("pm_listings", ()), + ("pm_outcome", ("PXM-12345",)), + ], +) def test_sync_helpers_raise(method, args): with pytest.raises(RetiredEndpointError, match="2026-07-20"): getattr(_bare(LLMClient), method)(*args) -@pytest.mark.parametrize("method,args", [ - ("pm_markets", ()), - ("pm_listings", ()), - ("pm_outcome", ("PXM-12345",)), -]) +@pytest.mark.parametrize( + "method,args", + [ + ("pm_markets", ()), + ("pm_listings", ()), + ("pm_outcome", ("PXM-12345",)), + ], +) @pytest.mark.asyncio async def test_async_helpers_raise(method, args): # An async def raises on await, not on call — but still before any network @@ -50,6 +56,4 @@ def test_message_points_at_the_replacement(): def test_surviving_helper_is_untouched(): # markets/search survived the sunset (422 on a missing q, i.e. alive). - assert not isinstance( - getattr(LLMClient, "pm_wallet_identity", None), type(None) - ) + assert not isinstance(getattr(LLMClient, "pm_wallet_identity", None), type(None)) From 84fe373d25aed7335cb8f625e670ec3b06ed956f Mon Sep 17 00:00:00 2001 From: 1bcMax Date: Tue, 4 Aug 2026 15:40:59 -0500 Subject: [PATCH 3/3] style: satisfy ruff isort + RUF022 on the new export MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only repositions the RetiredEndpointError entries in the import block and __all__ — ruff 0.16.0 (the pinned CI version) sorts these differently than the newer ruff I had installed locally, which is why it passed here and failed there. --- blockrun_llm/__init__.py | 4 ++-- blockrun_llm/solana_client.py | 2 +- tests/unit/test_retired_endpoints.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/blockrun_llm/__init__.py b/blockrun_llm/__init__.py index 215f9b4..df16b8c 100644 --- a/blockrun_llm/__init__.py +++ b/blockrun_llm/__init__.py @@ -116,7 +116,6 @@ MusicResponse, NewsSearchSource, PaymentError, - RetiredEndpointError, # Virtual Portrait types PortraitEnrollment, PortraitList, @@ -133,6 +132,7 @@ RealFaceList, RealFaceListItem, RealFaceStatus, + RetiredEndpointError, # Smart routing types RoutingDecision, RpcError, @@ -213,7 +213,6 @@ "MusicResponse", "NewsSearchSource", "PaymentError", - "RetiredEndpointError", "PhoneClient", "PortraitClient", "PortraitEnrollment", @@ -232,6 +231,7 @@ "RealFaceList", "RealFaceListItem", "RealFaceStatus", + "RetiredEndpointError", # Smart routing types "RoutingDecision", "RpcClient", diff --git a/blockrun_llm/solana_client.py b/blockrun_llm/solana_client.py index a5da314..cdf750f 100644 --- a/blockrun_llm/solana_client.py +++ b/blockrun_llm/solana_client.py @@ -51,7 +51,6 @@ ImageResponse, MusicResponse, PaymentError, - RetiredEndpointError, PortraitEnrollment, PortraitList, PriceHistoryResponse, @@ -60,6 +59,7 @@ RealFaceInit, RealFaceList, RealFaceStatus, + RetiredEndpointError, RpcResponse, SearchResult, SpeechResponse, diff --git a/tests/unit/test_retired_endpoints.py b/tests/unit/test_retired_endpoints.py index bdc5a05..44bde7f 100644 --- a/tests/unit/test_retired_endpoints.py +++ b/tests/unit/test_retired_endpoints.py @@ -56,4 +56,4 @@ def test_message_points_at_the_replacement(): def test_surviving_helper_is_untouched(): # markets/search survived the sunset (422 on a missing q, i.e. alive). - assert not isinstance(getattr(LLMClient, "pm_wallet_identity", None), type(None)) + assert not (getattr(LLMClient, "pm_wallet_identity", None) is None)