KI-Tracking vollständig, Cloud-Limit 20/Woche, Statusmail täglich 06:00 — SW by-v434, APP_VER 413

- ki.complete() zählt sich selbst (user_id-Parameter, _track_usage)
- CLOUD_WEEKLY_LIMIT=20, geprüft vor jedem Cloud-Call
- user_id durchgereicht in health, diary, knigge, notes, ki-route
- Admin-Panel: 7-Tage-Ansicht, Limit-Info, Top-Cloud-User-Tabelle
- Statusmail täglich 06:00 CEST statt alle 2h
This commit is contained in:
rene 2026-04-26 17:01:05 +02:00
parent 85836e4e6e
commit 570dcd4e93
11 changed files with 135 additions and 78 deletions

View file

@ -149,41 +149,45 @@ async def stats(user=Depends(require_mod)):
).fetchall()
}
# KI-Trainer Nutzung
# KI-Nutzung
try:
from ki import CLOUD_WEEKLY_LIMIT
ki_today = conn.execute(
"SELECT COALESCE(SUM(count),0) FROM ki_daily_calls WHERE date=DATE('now')"
).fetchone()[0]
ki_week = conn.execute(
"SELECT COALESCE(SUM(count),0) FROM ki_daily_calls WHERE date>=DATE('now','-6 days')"
).fetchone()[0]
ki_month = conn.execute(
"SELECT COALESCE(SUM(count),0) FROM ki_daily_calls WHERE date>=DATE('now','start of month')"
).fetchone()[0]
ki_users_today = conn.execute(
"SELECT COUNT(DISTINCT user_id) FROM ki_daily_calls WHERE date=DATE('now')"
).fetchone()[0]
# Aufschlüsselung nach Quelle (heute)
_src_today = {
# Aufschlüsselung nach Quelle (diese Woche)
_src_week = {
r[0]: r[1] for r in conn.execute(
"SELECT source, COALESCE(SUM(count),0) FROM ki_daily_calls "
"WHERE date=DATE('now') GROUP BY source"
"WHERE date>=DATE('now','-6 days') GROUP BY source"
).fetchall()
}
ki_cloud_today = _src_today.get("cloud", 0)
ki_local_today = _src_today.get("local", 0)
ki_luna_today = _src_today.get("luna", 0)
# Aufschlüsselung nach Quelle (Monat)
_src_month = {
r[0]: r[1] for r in conn.execute(
"SELECT source, COALESCE(SUM(count),0) FROM ki_daily_calls "
"WHERE date>=DATE('now','start of month') GROUP BY source"
ki_cloud_week = _src_week.get("cloud", 0)
ki_local_week = _src_week.get("local", 0)
ki_luna_week = _src_week.get("luna", 0)
# Top-User Cloud diese Woche
ki_top_users = [
{"user_id": r[0], "name": r[1], "cloud_calls": r[2]} for r in conn.execute(
"""SELECT k.user_id, u.name, SUM(k.count) as n
FROM ki_daily_calls k JOIN users u ON u.id=k.user_id
WHERE k.source='cloud' AND k.date>=DATE('now','-6 days')
GROUP BY k.user_id ORDER BY n DESC LIMIT 10"""
).fetchall()
}
ki_cloud_month = _src_month.get("cloud", 0)
ki_local_month = _src_month.get("local", 0)
ki_luna_month = _src_month.get("luna", 0)
]
except Exception:
ki_today = ki_month = ki_users_today = 0
ki_cloud_today = ki_local_today = ki_luna_today = 0
ki_cloud_month = ki_local_month = ki_luna_month = 0
from ki import CLOUD_WEEKLY_LIMIT
ki_today = ki_week = ki_month = ki_users_today = 0
ki_cloud_week = ki_local_week = ki_luna_week = 0
ki_top_users = []
# Ausstehende Wiki-Foto-Einreichungen
try:
@ -245,15 +249,15 @@ async def stats(user=Depends(require_mod)):
"osm_total": osm_total,
"osm_tiles": osm_tiles,
"osm_by_type": osm_by_type,
"ki_today": ki_today,
"ki_month": ki_month,
"ki_users_today": ki_users_today,
"ki_cloud_today": ki_cloud_today,
"ki_local_today": ki_local_today,
"ki_luna_today": ki_luna_today,
"ki_cloud_month": ki_cloud_month,
"ki_local_month": ki_local_month,
"ki_luna_month": ki_luna_month,
"ki_today": ki_today,
"ki_week": ki_week,
"ki_month": ki_month,
"ki_users_today": ki_users_today,
"ki_cloud_week": ki_cloud_week,
"ki_local_week": ki_local_week,
"ki_luna_week": ki_luna_week,
"ki_cloud_weekly_limit": CLOUD_WEEKLY_LIMIT,
"ki_top_users": ki_top_users,
"social_total": social_total,
"social_published": social_published,
"social_scheduled": social_scheduled,

View file

@ -265,7 +265,7 @@ async def create_diary(dog_id: int, data: DiaryCreate,
# KI: Auto-Tags wenn Text vorhanden (lokal, kostenlos)
if data.text and len(data.text) > 10:
try:
ai_tags = await KI.diary_tags(data.text)
ai_tags = await KI.diary_tags(data.text, user_id=user["id"])
tags = list(set(tags + ai_tags))
except Exception:
pass

View file

@ -412,6 +412,7 @@ async def symptom_check(dog_id: int, data: SymptomCheckRequest,
symptoms=data.symptoms,
dog_info=dog_info,
user_is_premium=bool(user.get("is_premium")),
user_id=user["id"],
)
return result
except KIUnavailableError as e:
@ -444,6 +445,7 @@ async def ki_zusammenfassung(dog_id: int, user=Depends(get_current_user)):
health_data=health_data,
dog_info=dict(dog),
user_is_premium=bool(user.get("is_premium")),
user_id=user["id"],
)
return {"zusammenfassung": result}
except KIPremiumRequired as e:

View file

@ -55,6 +55,7 @@ Schreibe klar und strukturiert, ohne unnötigen Fachjargon."""
system=system,
max_tokens=600,
requires_premium=False,
user_id=user["id"],
)
return {"antwort": result}
except ki_module.KIUnavailableError as e:

View file

@ -105,6 +105,7 @@ async def ki_rat(data: KiRatRequest, user=Depends(get_current_user)):
max_tokens=300,
requires_premium=False,
user_is_premium=bool(user.get("is_premium")),
user_id=user["id"],
)
return {"rat": rat}
except KIPremiumRequired as e:

View file

@ -156,10 +156,11 @@ async def ki_analyse(user=Depends(get_current_user)):
try:
import ki as ki_module
suggestions, _ = await ki_module.complete(
suggestions = await ki_module.complete(
prompt,
requires_premium=False,
user_is_premium=False,
user_id=user["id"],
)
except Exception as e:
logger.warning("KI-Analyse fehlgeschlagen: %s", e)