mirror of
https://github.com/open-webui/open-webui.git
synced 2026-07-16 06:03:26 -05:00
refac
This commit is contained in:
@@ -957,6 +957,20 @@ class ChatTable:
|
||||
all_chats = result.scalars().all()
|
||||
return [ChatModel.model_validate(chat) for chat in all_chats]
|
||||
|
||||
async def get_chat_metas_by_chat_ids(
|
||||
self,
|
||||
chat_ids: list[str],
|
||||
include_archived: bool = False,
|
||||
db: AsyncSession | None = None,
|
||||
) -> list[dict]:
|
||||
async with get_async_db_context(db) as session:
|
||||
stmt = select(Chat.meta).filter(Chat.id.in_(chat_ids))
|
||||
if not include_archived:
|
||||
stmt = stmt.filter_by(archived=False)
|
||||
|
||||
result = await session.execute(stmt)
|
||||
return [meta for meta in result.scalars().all() if isinstance(meta, dict)]
|
||||
|
||||
# retrieve conversation
|
||||
async def get_chat_by_id(
|
||||
self,
|
||||
@@ -1389,7 +1403,6 @@ class ChatTable:
|
||||
for chat in all_chats
|
||||
]
|
||||
|
||||
|
||||
async def get_chats_by_folder_ids_and_user_id(
|
||||
self, folder_ids: list[str], user_id: str, db: AsyncSession | None = None
|
||||
) -> list[ChatModel]:
|
||||
|
||||
@@ -133,6 +133,12 @@ class ModelHistoryEntry(BaseModel):
|
||||
lost: int
|
||||
|
||||
|
||||
class ModelHistoryCounts(BaseModel):
|
||||
date: str
|
||||
won: int = 0
|
||||
lost: int = 0
|
||||
|
||||
|
||||
class ModelHistoryResponse(BaseModel):
|
||||
model_id: str
|
||||
history: list[ModelHistoryEntry]
|
||||
@@ -375,6 +381,45 @@ class FeedbackTable:
|
||||
|
||||
return result
|
||||
|
||||
async def get_model_feedback_counts_by_day(
|
||||
self,
|
||||
model_id: str,
|
||||
start_date: Optional[int] = None,
|
||||
db: Optional[AsyncSession] = None,
|
||||
) -> list[ModelHistoryCounts]:
|
||||
"""Get aggregated feedback counts per day for a model, preserving all matching days."""
|
||||
from collections import defaultdict
|
||||
from datetime import datetime
|
||||
|
||||
async with get_async_db_context(db) as db:
|
||||
stmt = select(Feedback.created_at, Feedback.data).filter(Feedback.data['model_id'].as_string() == model_id)
|
||||
if start_date is not None:
|
||||
stmt = stmt.filter(Feedback.created_at >= start_date)
|
||||
|
||||
result = await db.execute(stmt.order_by(Feedback.created_at.asc()))
|
||||
rows = result.all()
|
||||
|
||||
daily_counts = defaultdict(lambda: {'won': 0, 'lost': 0})
|
||||
|
||||
for created_at, data in rows:
|
||||
if not data:
|
||||
continue
|
||||
|
||||
rating_str = str(data.get('rating', ''))
|
||||
if rating_str not in ('1', '-1'):
|
||||
continue
|
||||
|
||||
date_str = datetime.fromtimestamp(created_at).strftime('%Y-%m-%d')
|
||||
if rating_str == '1':
|
||||
daily_counts[date_str]['won'] += 1
|
||||
else:
|
||||
daily_counts[date_str]['lost'] += 1
|
||||
|
||||
return [
|
||||
ModelHistoryCounts(date=date_str, won=counts['won'], lost=counts['lost'])
|
||||
for date_str, counts in sorted(daily_counts.items())
|
||||
]
|
||||
|
||||
async def get_feedbacks_by_type(self, type: str, db: Optional[AsyncSession] = None) -> list[FeedbackModel]:
|
||||
async with get_async_db_context(db) as db:
|
||||
result = await db.execute(select(Feedback).filter_by(type=type).order_by(Feedback.updated_at.desc()))
|
||||
|
||||
@@ -367,6 +367,12 @@ async def get_model_overview(
|
||||
):
|
||||
"""Get model overview with feedback history and chat tags."""
|
||||
|
||||
# Calculate start date for history
|
||||
now = datetime.now()
|
||||
start_dt = None
|
||||
if days > 0:
|
||||
start_dt = now - timedelta(days=days)
|
||||
|
||||
# Get chat IDs that used this model
|
||||
chat_ids = await ChatMessages.get_chat_ids_by_model_id(
|
||||
model_id=model_id,
|
||||
@@ -377,31 +383,18 @@ async def get_model_overview(
|
||||
db=db,
|
||||
)
|
||||
|
||||
# Get feedback history per day
|
||||
history_counts: dict[str, dict] = defaultdict(lambda: {'won': 0, 'lost': 0})
|
||||
|
||||
# Calculate start date for history
|
||||
now = datetime.now()
|
||||
start_dt = None
|
||||
if days > 0:
|
||||
start_dt = now - timedelta(days=days)
|
||||
|
||||
for chat_id in chat_ids:
|
||||
feedbacks = await Feedbacks.get_feedbacks_by_chat_id(chat_id, db=db)
|
||||
for fb in feedbacks:
|
||||
if fb.data and 'rating' in fb.data:
|
||||
rating = fb.data['rating']
|
||||
fb_date = datetime.fromtimestamp(fb.created_at)
|
||||
|
||||
# Filter by date range
|
||||
if start_dt and fb_date < start_dt:
|
||||
continue
|
||||
|
||||
date_str = fb_date.strftime('%Y-%m-%d')
|
||||
if rating == 1:
|
||||
history_counts[date_str]['won'] += 1
|
||||
elif rating == -1:
|
||||
history_counts[date_str]['lost'] += 1
|
||||
history_rows = await Feedbacks.get_model_feedback_counts_by_day(
|
||||
model_id=model_id,
|
||||
start_date=int(start_dt.timestamp()) if start_dt else None,
|
||||
db=db,
|
||||
)
|
||||
history_counts = {
|
||||
entry.date: {
|
||||
'won': entry.won,
|
||||
'lost': entry.lost,
|
||||
}
|
||||
for entry in history_rows
|
||||
}
|
||||
|
||||
# Fill in missing days
|
||||
history = []
|
||||
@@ -430,10 +423,14 @@ async def get_model_overview(
|
||||
|
||||
# Get chat tags
|
||||
tag_counts: dict[str, int] = defaultdict(int)
|
||||
for chat_id in chat_ids:
|
||||
chat = await Chats.get_chat_by_id(chat_id, db=db)
|
||||
if chat and chat.meta:
|
||||
for tag in chat.meta.get('tags', []):
|
||||
if chat_ids:
|
||||
chat_metas = await Chats.get_chat_metas_by_chat_ids(
|
||||
chat_ids,
|
||||
include_archived=True,
|
||||
db=db,
|
||||
)
|
||||
for meta in chat_metas:
|
||||
for tag in meta.get('tags', []):
|
||||
tag_counts[tag] += 1
|
||||
|
||||
# Sort by count and take top 10
|
||||
|
||||
@@ -368,7 +368,11 @@ async def get_all_models(request, refresh: bool = False, user: UserModel = None)
|
||||
|
||||
models_dict = {model['id']: model for model in models}
|
||||
if isinstance(request.app.state.MODELS, RedisDict):
|
||||
request.app.state.MODELS.set(models_dict)
|
||||
try:
|
||||
request.app.state.MODELS.set(models_dict)
|
||||
except Exception as e:
|
||||
log.warning(f'Failed to update Redis model cache, using in-process cache: {e}')
|
||||
request.app.state.MODELS = models_dict
|
||||
else:
|
||||
request.app.state.MODELS = models_dict
|
||||
|
||||
|
||||
@@ -46,8 +46,9 @@
|
||||
try {
|
||||
const result = await getLeaderboard(localStorage.token, searchQuery);
|
||||
const statsMap = new Map((result?.entries ?? []).map((e) => [e.model_id, e]));
|
||||
const modelMap = new Map(($models ?? []).map((m) => [m.id, m]));
|
||||
|
||||
rankedModels = $models
|
||||
const activeModels = $models
|
||||
.filter((m) => m?.owned_by !== 'arena' && !m?.info?.meta?.hidden)
|
||||
.map((model) => {
|
||||
const s = statsMap.get(model.id);
|
||||
@@ -61,12 +62,27 @@
|
||||
},
|
||||
top_tags: s?.top_tags ?? []
|
||||
};
|
||||
})
|
||||
.sort((a, b) => {
|
||||
if (a.rating === '-') return 1;
|
||||
if (b.rating === '-') return -1;
|
||||
return b.rating - a.rating;
|
||||
});
|
||||
|
||||
const evaluatedModels = (result?.entries ?? [])
|
||||
.filter((entry) => !modelMap.has(entry.model_id))
|
||||
.map((entry) => ({
|
||||
id: entry.model_id,
|
||||
name: entry.model_id,
|
||||
rating: entry.rating,
|
||||
stats: {
|
||||
count: entry.won + entry.lost,
|
||||
won: entry.won.toString(),
|
||||
lost: entry.lost.toString()
|
||||
},
|
||||
top_tags: entry.top_tags ?? []
|
||||
}));
|
||||
|
||||
rankedModels = [...activeModels, ...evaluatedModels].sort((a, b) => {
|
||||
if (a.rating === '-') return 1;
|
||||
if (b.rating === '-') return -1;
|
||||
return b.rating - a.rating;
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Leaderboard load failed:', err);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user