openvidia 2.2.0__py3-none-any.whl
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.
- openvidia/__init__.py +30 -0
- openvidia/__main__.py +827 -0
- openvidia/_upstream_utils.py +57 -0
- openvidia/anthropic_shim.py +714 -0
- openvidia/compaction.py +851 -0
- openvidia/config.py +513 -0
- openvidia/embedding_cache.py +69 -0
- openvidia/graph_engine.py +466 -0
- openvidia/provider_fallback.py +98 -0
- openvidia/proxy_app.py +863 -0
- openvidia/proxy_state.py +1010 -0
- openvidia/redis_sync.py +93 -0
- openvidia/responses_shim.py +1374 -0
- openvidia/safe_file.py +100 -0
- openvidia/server_manager.py +106 -0
- openvidia/upstream_router.py +50 -0
- openvidia/web/assets/32x32.ico +0 -0
- openvidia/web/assets/64x64.ico +0 -0
- openvidia/web/assets/dashboard.gif +0 -0
- openvidia/web/assets/favicon.ico +0 -0
- openvidia/web/assets/logo.png +0 -0
- openvidia/web/favicon.ico +0 -0
- openvidia/web/index.html +166 -0
- openvidia/web/logo.png +0 -0
- openvidia/web/main.js +732 -0
- openvidia/web/styles.css +425 -0
- openvidia/webui.py +532 -0
- openvidia-2.2.0.dist-info/METADATA +814 -0
- openvidia-2.2.0.dist-info/RECORD +33 -0
- openvidia-2.2.0.dist-info/WHEEL +5 -0
- openvidia-2.2.0.dist-info/entry_points.txt +2 -0
- openvidia-2.2.0.dist-info/licenses/LICENSE +21 -0
- openvidia-2.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""Shared upstream utilities: concurrency semaphore and error detection.
|
|
2
|
+
|
|
3
|
+
Kept in a separate module to avoid circular imports between proxy_app
|
|
4
|
+
(which imports responses_shim) and responses_shim (which needs these
|
|
5
|
+
helpers from proxy_app).
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import asyncio
|
|
11
|
+
import json
|
|
12
|
+
|
|
13
|
+
# ── Global upstream concurrency cap ─────────────────────────────────────
|
|
14
|
+
# NVIDIA free-tier workers reject with:
|
|
15
|
+
# "ResourceExhausted: Worker local total request limit reached (32/32)"
|
|
16
|
+
# when >32 concurrent requests hit the same worker worldwide. Stay under the ceiling
|
|
17
|
+
# by capping total in-flight upstream sends to 14.
|
|
18
|
+
_UPSTREAM_CONCURRENCY_LIMIT = 14
|
|
19
|
+
_upstream_sem: asyncio.Semaphore | None = None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def get_upstream_sem() -> asyncio.Semaphore:
|
|
23
|
+
"""Return (creating if needed) the shared upstream concurrency semaphore."""
|
|
24
|
+
global _upstream_sem
|
|
25
|
+
if _upstream_sem is None:
|
|
26
|
+
_upstream_sem = asyncio.Semaphore(_UPSTREAM_CONCURRENCY_LIMIT)
|
|
27
|
+
return _upstream_sem
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def is_resource_exhausted(body: bytes | None) -> bool:
|
|
31
|
+
"""True when NVIDIA says the worker is full (concurrent limit), not RPM.
|
|
32
|
+
|
|
33
|
+
429/503 with ResourceExhausted body = transient concurrency limit.
|
|
34
|
+
429 without it = real RPM rate-limit → burn the key cooldown.
|
|
35
|
+
|
|
36
|
+
The message arrives in two shapes: flat (``{"message": ...}``) and nested
|
|
37
|
+
under ``error`` (``{"error": {"message": "ResourceExhausted: Worker local
|
|
38
|
+
total request limit reached (48/48)"}}``), which is the one the 503 form
|
|
39
|
+
uses. Reading only the flat keys parsed that body successfully and then
|
|
40
|
+
reported "not exhausted", so the caller cooled the key down.
|
|
41
|
+
"""
|
|
42
|
+
if not body:
|
|
43
|
+
return False
|
|
44
|
+
try:
|
|
45
|
+
data = json.loads(body)
|
|
46
|
+
err = data.get("error")
|
|
47
|
+
if not isinstance(err, dict):
|
|
48
|
+
err = {}
|
|
49
|
+
msg = str(
|
|
50
|
+
data.get("message", "")
|
|
51
|
+
or data.get("detail", "")
|
|
52
|
+
or err.get("message", "")
|
|
53
|
+
or err.get("detail", "")
|
|
54
|
+
)
|
|
55
|
+
return "ResourceExhausted" in msg or "request limit reached" in msg.lower()
|
|
56
|
+
except Exception:
|
|
57
|
+
return "ResourceExhausted" in body.decode("utf-8", errors="replace")
|