feat: 添加模型上下文管理并统一主题组件与用量交互

This commit is contained in:
2026-09-05 21:58:37 +08:00
parent 031ab135d2
commit 7551716e13
33 changed files with 738 additions and 38 deletions
+13 -3
View File
@@ -108,7 +108,7 @@ class UsageAttempt:
def aggregate(start, end, provider_id=None, model=None, source=None, timezone_offset=0):
query = "SELECT counters_json,completed,capability,started_at,source FROM model_usage WHERE started_at>=? AND started_at<?"
query = "SELECT counters_json,completed,capability,started_at,source,provider_id,model FROM model_usage WHERE started_at>=? AND started_at<?"
args = [start.astimezone(timezone.utc).isoformat(), end.astimezone(timezone.utc).isoformat()]
for column, value in (("provider_id", provider_id), ("model", model), ("source", source)):
if value:
@@ -127,8 +127,8 @@ def aggregate(start, end, provider_id=None, model=None, source=None, timezone_of
for offset in range(0, days, step):
date = first + timedelta(days=offset)
series.append({"date": date.isoformat(), "end_date": (first + timedelta(days=min(days-1, offset+step-1))).isoformat(),
"local": {"requests": 0, "totals": {key: None for key in METRICS}, "coverage": {key: 0 for key in METRICS}},
"api": {"requests": 0, "totals": {key: None for key in METRICS}, "coverage": {key: 0 for key in METRICS}}})
"local": {"requests": 0, "totals": {key: None for key in METRICS}, "coverage": {key: 0 for key in METRICS}, "models": {}},
"api": {"requests": 0, "totals": {key: None for key in METRICS}, "coverage": {key: 0 for key in METRICS}, "models": {}}})
totals = {key: None for key in METRICS}
coverage = {key: 0 for key in METRICS}
hits, eligible_input, cache_requests = 0, 0, 0
@@ -140,6 +140,13 @@ def aggregate(start, end, provider_id=None, model=None, source=None, timezone_of
date = datetime.fromisoformat(row[3]).astimezone(zone).date()
bucket = series[(date - first).days // step][row[4]]
bucket['requests'] += 1
model_key = json.dumps([row[5], row[6]], ensure_ascii=False)
part = bucket['models'].setdefault(model_key, {'key': model_key, 'provider_id': row[5], 'model': row[6], 'requests': 0, 'totals': {key: None for key in METRICS}, 'coverage': {key: 0 for key in METRICS}})
part['requests'] += 1
for key in METRICS:
if counts.get(key) is not None:
part['totals'][key] = (part['totals'][key] or 0) + counts[key]
part['coverage'][key] += 1
for key in METRICS:
if counts.get(key) is not None:
bucket['totals'][key] = (bucket['totals'][key] or 0) + counts[key]
@@ -155,6 +162,9 @@ def aggregate(start, end, provider_id=None, model=None, source=None, timezone_of
hits += counts["cache_hit_tokens"]
eligible_input += counts["input_tokens"] if counts.get("input_tokens") is not None else counts["cache_hit_tokens"] + counts["cache_miss_tokens"]
cache_requests += 1
for bucket in series:
for origin in ('local', 'api'):
bucket[origin]['models'] = sorted(bucket[origin]['models'].values(), key=lambda item: item['key'])
return {"audio_request_count": audio_requests, "audio_seconds": audio_seconds, "audio_covered_requests": audio_covered, "totals": totals, "coverage": coverage, "request_count": len(rows),
"complete_requests": sum(row[1] for row in rows), "cache_covered_requests": cache_requests,
"cache_hit_rate": hits / eligible_input if eligible_input else None,