Feat: Add Token Stats and Cost Savings dashboard card and backend tracking
This commit is contained in:
@@ -1,18 +1,11 @@
|
||||
"""
|
||||
Eingebauter Routing-Gateway (OpenAI-kompatibel) — EIN Endpunkt für Hermes + IDEs.
|
||||
|
||||
`model: auto` → Komplexitäts-Routing fast↔heavy; jeder andere Name geht als
|
||||
llama-swap-Alias durch (das lädt das Modell bei Bedarf). Streaming wird
|
||||
durchgereicht. Ersetzt LiteLLM (das auf Python 3.14 nicht baut) — gleicher
|
||||
Vertrag, später austauschbar.
|
||||
"""
|
||||
|
||||
import json
|
||||
import httpx
|
||||
from fastapi import APIRouter, Request
|
||||
from fastapi.responses import JSONResponse, StreamingResponse
|
||||
|
||||
from config import LLAMA_SWAP_URL
|
||||
from services.router_logic import FAST, FAST_NO_THINK, choose_model
|
||||
from services.token_stats import increment_tokens
|
||||
|
||||
router = APIRouter(prefix="/v1")
|
||||
|
||||
@@ -44,12 +37,42 @@ async def _proxy(path: str, request: Request):
|
||||
async with httpx.AsyncClient(timeout=None) as c:
|
||||
async with c.stream("POST", url, json=body) as r:
|
||||
async for chunk in r.aiter_raw():
|
||||
try:
|
||||
chunk_str = chunk.decode("utf-8", errors="ignore")
|
||||
if '"usage":' in chunk_str:
|
||||
for line in chunk_str.splitlines():
|
||||
if line.startswith("data:"):
|
||||
data_str = line[5:].strip()
|
||||
if data_str == "[DONE]":
|
||||
continue
|
||||
try:
|
||||
data_json = json.loads(data_str)
|
||||
usage = data_json.get("usage")
|
||||
if usage:
|
||||
prompt = usage.get("prompt_tokens", 0)
|
||||
completion = usage.get("completion_tokens", 0)
|
||||
if prompt or completion:
|
||||
increment_tokens(prompt, completion)
|
||||
except Exception:
|
||||
pass
|
||||
except Exception:
|
||||
pass
|
||||
yield chunk
|
||||
return StreamingResponse(gen(), media_type="text/event-stream", headers=routed)
|
||||
|
||||
async with httpx.AsyncClient(timeout=600) as c:
|
||||
r = await c.post(url, json=body)
|
||||
return JSONResponse(r.json(), status_code=r.status_code, headers=routed)
|
||||
resp_json = r.json()
|
||||
try:
|
||||
usage = resp_json.get("usage")
|
||||
if usage:
|
||||
prompt = usage.get("prompt_tokens", 0)
|
||||
completion = usage.get("completion_tokens", 0)
|
||||
if prompt or completion:
|
||||
increment_tokens(prompt, completion)
|
||||
except Exception:
|
||||
pass
|
||||
return JSONResponse(resp_json, status_code=r.status_code, headers=routed)
|
||||
|
||||
|
||||
@router.post("/chat/completions")
|
||||
|
||||
Reference in New Issue
Block a user