refac
This commit is contained in:
@@ -269,6 +269,50 @@ class ChatMessageTable:
|
||||
results = query.group_by(ChatMessage.model_id).all()
|
||||
return {row.model_id: row.count for row in results}
|
||||
|
||||
def get_token_usage_by_model(
|
||||
self,
|
||||
start_date: Optional[int] = None,
|
||||
end_date: Optional[int] = None,
|
||||
db: Optional[Session] = None,
|
||||
) -> dict[str, dict]:
|
||||
"""Aggregate token usage by model. Works with SQLite and PostgreSQL."""
|
||||
with get_db_context(db) as db:
|
||||
query = db.query(
|
||||
ChatMessage.model_id,
|
||||
ChatMessage.usage,
|
||||
).filter(
|
||||
ChatMessage.role == "assistant",
|
||||
ChatMessage.model_id.isnot(None),
|
||||
ChatMessage.usage.isnot(None),
|
||||
)
|
||||
|
||||
if start_date:
|
||||
query = query.filter(ChatMessage.created_at >= start_date)
|
||||
if end_date:
|
||||
query = query.filter(ChatMessage.created_at <= end_date)
|
||||
|
||||
results = query.all()
|
||||
|
||||
# Aggregate in Python for cross-database compatibility
|
||||
usage_by_model: dict[str, dict] = {}
|
||||
for model_id, usage in results:
|
||||
if model_id not in usage_by_model:
|
||||
usage_by_model[model_id] = {
|
||||
"input_tokens": 0,
|
||||
"output_tokens": 0,
|
||||
"message_count": 0,
|
||||
}
|
||||
|
||||
usage_by_model[model_id]["input_tokens"] += usage.get("input_tokens") or 0
|
||||
usage_by_model[model_id]["output_tokens"] += usage.get("output_tokens") or 0
|
||||
usage_by_model[model_id]["message_count"] += 1
|
||||
|
||||
# Add total_tokens
|
||||
for data in usage_by_model.values():
|
||||
data["total_tokens"] = data["input_tokens"] + data["output_tokens"]
|
||||
|
||||
return usage_by_model
|
||||
|
||||
def get_message_count_by_user(
|
||||
self,
|
||||
start_date: Optional[int] = None,
|
||||
|
||||
@@ -3001,6 +3001,7 @@ async def process_chat_response(
|
||||
"content": content,
|
||||
}
|
||||
]
|
||||
usage = None
|
||||
|
||||
reasoning_tags_param = metadata.get("params", {}).get("reasoning_tags")
|
||||
DETECT_REASONING_TAGS = reasoning_tags_param is not False
|
||||
@@ -3122,11 +3123,11 @@ async def process_chat_response(
|
||||
else:
|
||||
choices = data.get("choices", [])
|
||||
|
||||
# 17421 - Normalize usage data to standard format
|
||||
usage = data.get("usage", {}) or {}
|
||||
usage.update(data.get("timings", {})) # llama.cpp
|
||||
if usage:
|
||||
usage = normalize_usage(usage)
|
||||
# Normalize usage data to standard format
|
||||
raw_usage = data.get("usage", {}) or {}
|
||||
raw_usage.update(data.get("timings", {})) # llama.cpp
|
||||
if raw_usage:
|
||||
usage = normalize_usage(raw_usage)
|
||||
await event_emitter(
|
||||
{
|
||||
"type": "chat:completion",
|
||||
@@ -3924,8 +3925,15 @@ async def process_chat_response(
|
||||
{
|
||||
"content": serialize_output(output),
|
||||
"output": output,
|
||||
**({"usage": usage} if usage else {}),
|
||||
},
|
||||
)
|
||||
elif usage:
|
||||
Chats.upsert_message_to_chat_by_id_and_message_id(
|
||||
metadata["chat_id"],
|
||||
metadata["message_id"],
|
||||
{"usage": usage},
|
||||
)
|
||||
|
||||
# Send a webhook notification if the user is not active
|
||||
if not Users.is_user_active(user.id):
|
||||
|
||||
Reference in New Issue
Block a user