Skip to content

Commit 47f97d9

Browse files
committed
cleanup
1 parent 6e719f9 commit 47f97d9

3 files changed

Lines changed: 43 additions & 76 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ dependencies = [
2727
"langchain>=0.3.7",
2828
"openai>=1.58.1",
2929
"pydantic>=2.9.2",
30-
"og-x402==0.0.1.dev2"
30+
"og-x402==0.0.1.dev4"
3131
]
3232

3333
[project.scripts]

src/opengradient/client/llm.py

Lines changed: 38 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@ class _ChatParams:
5050
x402_settlement_mode: x402SettlementMode
5151

5252

53+
@dataclass
54+
class _ResolvedTEEState:
55+
"""Resolved TEE connection details used to configure the HTTP client."""
56+
57+
endpoint: str
58+
tls_verify: Union[ssl.SSLContext, bool]
59+
tee_id: Optional[str]
60+
tee_payment_address: Optional[str]
61+
62+
5363
class LLM:
5464
"""
5565
LLM inference namespace.
@@ -105,21 +115,8 @@ def __init__(
105115
self._tee_registry_address = tee_registry_address
106116
self._llm_server_url = llm_server_url
107117

108-
endpoint, tls_cert_der, tee_id, tee_payment_address = self._resolve_tee(
109-
llm_server_url,
110-
rpc_url,
111-
tee_registry_address,
112-
)
113-
114-
self._tee_id = tee_id
115-
self._tee_endpoint = endpoint
116-
self._tee_payment_address = tee_payment_address
117-
118-
ssl_ctx = build_ssl_context_from_der(tls_cert_der) if tls_cert_der else None
119-
# When connecting directly via llm_server_url, skip cert verification —
120-
# self-hosted TEE servers commonly use self-signed certificates.
121-
verify_ssl = llm_server_url is None
122-
self._tls_verify: Union[ssl.SSLContext, bool] = ssl_ctx if ssl_ctx else verify_ssl
118+
state = self._resolve_tee_state()
119+
self._apply_tee_state(state)
123120
self._reset_lock = threading.Lock()
124121

125122
# x402 client/signer/http stack
@@ -134,30 +131,30 @@ def _init_x402_stack(self) -> None:
134131
# httpx.AsyncClient subclass - construction is sync, connections open lazily
135132
self._http_client = x402HttpxClient(self._x402_client, verify=self._tls_verify)
136133

137-
async def _reset_x402_stack(self) -> None:
138-
"""Reset x402 state and underlying HTTP client."""
139-
with self._reset_lock:
140-
old_http_client = self._http_client
141-
self._init_x402_stack()
142-
143-
try:
144-
await old_http_client.aclose()
145-
except Exception:
146-
logger.debug("Failed to close previous x402 HTTP client during reset.", exc_info=True)
147-
148-
@staticmethod
149-
def _is_invalid_payment_required_error(exc: Exception) -> bool:
150-
"""Detect the known stale-session x402 failure mode."""
151-
visited: set[int] = set()
152-
current: Optional[BaseException] = exc
134+
def _resolve_tee_state(self) -> _ResolvedTEEState:
135+
"""Resolve current TEE metadata and derive the TLS verification config."""
136+
endpoint, tls_cert_der, tee_id, tee_payment_address = self._resolve_tee(
137+
self._llm_server_url,
138+
self._rpc_url,
139+
self._tee_registry_address,
140+
)
141+
ssl_ctx = build_ssl_context_from_der(tls_cert_der) if tls_cert_der else None
142+
# When connecting directly via llm_server_url, skip cert verification —
143+
# self-hosted TEE servers commonly use self-signed certificates.
144+
verify_ssl = self._llm_server_url is None
145+
return _ResolvedTEEState(
146+
endpoint=endpoint,
147+
tls_verify=ssl_ctx if ssl_ctx else verify_ssl,
148+
tee_id=tee_id,
149+
tee_payment_address=tee_payment_address,
150+
)
153151

154-
while current is not None and id(current) not in visited:
155-
visited.add(id(current))
156-
msg = str(current).lower()
157-
if "invalid payment required response" in msg:
158-
return True
159-
current = current.__cause__ or current.__context__
160-
return False
152+
def _apply_tee_state(self, state: _ResolvedTEEState) -> None:
153+
"""Apply resolved TEE metadata to the current client instance."""
154+
self._tee_id = state.tee_id
155+
self._tee_endpoint = state.endpoint
156+
self._tee_payment_address = state.tee_payment_address
157+
self._tls_verify = state.tls_verify
161158

162159
@staticmethod
163160
def _is_ssl_error(exc: Exception) -> bool:
@@ -189,21 +186,8 @@ async def _refresh_tee_and_reset(self) -> None:
189186
"""Re-resolve TEE from registry and rebuild the HTTP client with a fresh SSL context."""
190187
with self._reset_lock:
191188
old_http_client = self._http_client
192-
193-
endpoint, tls_cert_der, tee_id, tee_payment_address = self._resolve_tee(
194-
self._llm_server_url,
195-
self._rpc_url,
196-
self._tee_registry_address,
197-
)
198-
199-
self._tee_id = tee_id
200-
self._tee_endpoint = endpoint
201-
self._tee_payment_address = tee_payment_address
202-
203-
ssl_ctx = build_ssl_context_from_der(tls_cert_der) if tls_cert_der else None
204-
verify_ssl = self._llm_server_url is None
205-
self._tls_verify = ssl_ctx if ssl_ctx else verify_ssl
206-
189+
state = self._resolve_tee_state()
190+
self._apply_tee_state(state)
207191
self._init_x402_stack()
208192

209193
try:
@@ -216,7 +200,7 @@ async def _retry_once_on_recoverable_error(
216200
operation_name: str,
217201
call: Callable[[], Awaitable[T]],
218202
) -> T:
219-
"""Retry once after resetting state for recoverable payment or SSL errors."""
203+
"""Retry once after refreshing TEE state for recoverable SSL errors."""
220204
try:
221205
return await call()
222206
except Exception as first_error:
@@ -229,15 +213,6 @@ async def _retry_once_on_recoverable_error(
229213
await self._refresh_tee_and_reset()
230214
return await call()
231215

232-
if self._is_invalid_payment_required_error(first_error):
233-
logger.warning(
234-
"Recoverable x402 payment error during %s; resetting x402 client and retrying once: %s",
235-
operation_name,
236-
first_error,
237-
)
238-
await self._reset_x402_stack()
239-
return await call()
240-
241216
raise
242217

243218
# ── TEE resolution ──────────────────────────────────────────────────
@@ -583,14 +558,6 @@ async def _chat_stream(self, params: _ChatParams, messages: List[Dict]) -> Async
583558
# Re-read headers since endpoint may have changed
584559
headers = self._headers(params.x402_settlement_mode)
585560
continue
586-
if self._is_invalid_payment_required_error(e):
587-
retried = True
588-
logger.warning(
589-
"Recoverable x402 payment error during stream; resetting x402 client and retrying once: %s",
590-
e,
591-
)
592-
await self._reset_x402_stack()
593-
continue
594561
raise
595562

596563
async def _parse_sse_response(

uv.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)