pi-sidecar-client 0.1.0.dev3__tar.gz → 0.1.0.dev4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pi_sidecar_client-0.1.0.dev3 → pi_sidecar_client-0.1.0.dev4}/PKG-INFO +1 -1
- {pi_sidecar_client-0.1.0.dev3 → pi_sidecar_client-0.1.0.dev4}/pi_sidecar_client/__init__.py +21 -10
- {pi_sidecar_client-0.1.0.dev3 → pi_sidecar_client-0.1.0.dev4}/pi_sidecar_client.egg-info/PKG-INFO +1 -1
- {pi_sidecar_client-0.1.0.dev3 → pi_sidecar_client-0.1.0.dev4}/pyproject.toml +1 -1
- {pi_sidecar_client-0.1.0.dev3 → pi_sidecar_client-0.1.0.dev4}/LICENSE +0 -0
- {pi_sidecar_client-0.1.0.dev3 → pi_sidecar_client-0.1.0.dev4}/README.md +0 -0
- {pi_sidecar_client-0.1.0.dev3 → pi_sidecar_client-0.1.0.dev4}/pi_sidecar_client.egg-info/SOURCES.txt +0 -0
- {pi_sidecar_client-0.1.0.dev3 → pi_sidecar_client-0.1.0.dev4}/pi_sidecar_client.egg-info/dependency_links.txt +0 -0
- {pi_sidecar_client-0.1.0.dev3 → pi_sidecar_client-0.1.0.dev4}/pi_sidecar_client.egg-info/requires.txt +0 -0
- {pi_sidecar_client-0.1.0.dev3 → pi_sidecar_client-0.1.0.dev4}/pi_sidecar_client.egg-info/top_level.txt +0 -0
- {pi_sidecar_client-0.1.0.dev3 → pi_sidecar_client-0.1.0.dev4}/setup.cfg +0 -0
|
@@ -50,7 +50,8 @@ _usage_recorder: Callable | None = None
|
|
|
50
50
|
def set_usage_recorder(callback: Callable) -> None:
|
|
51
51
|
"""Register a callback for recording AI token usage.
|
|
52
52
|
|
|
53
|
-
The callback
|
|
53
|
+
The callback may be sync or async:
|
|
54
|
+
def recorder(*, request_id, result, call_type, prompt_chars, ai_provider, ai_model)
|
|
54
55
|
async def recorder(*, request_id, result, call_type, prompt_chars, ai_provider, ai_model)
|
|
55
56
|
"""
|
|
56
57
|
global _usage_recorder
|
|
@@ -117,6 +118,7 @@ class SidecarClient:
|
|
|
117
118
|
def __init__(self, base_url: str = SIDECAR_URL):
|
|
118
119
|
self._base_url = base_url.rstrip("/")
|
|
119
120
|
self._client = httpx.AsyncClient(base_url=self._base_url, timeout=600.0)
|
|
121
|
+
self._closed = False
|
|
120
122
|
|
|
121
123
|
async def health(self) -> dict:
|
|
122
124
|
"""Check sidecar health."""
|
|
@@ -204,6 +206,7 @@ class SidecarClient:
|
|
|
204
206
|
async def close(self) -> None:
|
|
205
207
|
"""Close the HTTP client."""
|
|
206
208
|
await self._client.aclose()
|
|
209
|
+
self._closed = True
|
|
207
210
|
|
|
208
211
|
|
|
209
212
|
# Singleton client
|
|
@@ -213,7 +216,7 @@ _client: SidecarClient | None = None
|
|
|
213
216
|
def get_sidecar_client() -> SidecarClient:
|
|
214
217
|
"""Get the singleton sidecar client."""
|
|
215
218
|
global _client
|
|
216
|
-
if _client is None:
|
|
219
|
+
if _client is None or _client._closed:
|
|
217
220
|
_client = SidecarClient()
|
|
218
221
|
return _client
|
|
219
222
|
|
|
@@ -291,9 +294,10 @@ async def call_ai_once(
|
|
|
291
294
|
) -> AIResult:
|
|
292
295
|
"""Single-shot AI call with automatic session cleanup.
|
|
293
296
|
|
|
294
|
-
Creates a session, sends the prompt, and
|
|
295
|
-
|
|
296
|
-
|
|
297
|
+
Creates a session, sends the prompt, and deletes the session.
|
|
298
|
+
Cleanup is best-effort — if deletion fails, result.session_id is
|
|
299
|
+
preserved so the caller can retry cleanup.
|
|
300
|
+
Use ``call_ai`` directly for multi-turn conversations.
|
|
297
301
|
"""
|
|
298
302
|
result = await call_ai(
|
|
299
303
|
prompt,
|
|
@@ -329,13 +333,20 @@ async def check_sidecar_available() -> tuple[bool, str]:
|
|
|
329
333
|
"""Check if the sidecar service is available and ready."""
|
|
330
334
|
try:
|
|
331
335
|
client = get_sidecar_client()
|
|
332
|
-
|
|
333
|
-
data
|
|
334
|
-
if resp.status_code == 200 and data.get("status") == "ok":
|
|
336
|
+
data = await client.health()
|
|
337
|
+
if data.get("status") == "ok":
|
|
335
338
|
return True, "Sidecar is ready"
|
|
336
|
-
if
|
|
339
|
+
if data.get("status") == "starting":
|
|
337
340
|
return False, f"Sidecar starting: {data.get('message', 'model discovery in progress')}"
|
|
338
|
-
return False, f"Sidecar unhealthy
|
|
341
|
+
return False, f"Sidecar unhealthy: {data}"
|
|
342
|
+
except httpx.HTTPStatusError as e:
|
|
343
|
+
if e.response.status_code == 503:
|
|
344
|
+
try:
|
|
345
|
+
data = e.response.json()
|
|
346
|
+
return False, f"Sidecar starting: {data.get('message', 'model discovery in progress')}"
|
|
347
|
+
except ValueError:
|
|
348
|
+
pass
|
|
349
|
+
return False, f"Sidecar unhealthy (HTTP {e.response.status_code})"
|
|
339
350
|
except Exception as e:
|
|
340
351
|
return False, f"Sidecar unavailable: {e}"
|
|
341
352
|
|
|
File without changes
|
|
File without changes
|
{pi_sidecar_client-0.1.0.dev3 → pi_sidecar_client-0.1.0.dev4}/pi_sidecar_client.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|