This commit is contained in:
Timothy Jaeryang Baek committed 2026-06-29 01:38:41 -05:00
1 parent a4f7ec1fb3
commit 3730a9eaac
3 files changed
+161 -56

No files matched your search

+63
View File
@@ -984,6 +984,69 @@ class ChatTable:
result = await session.execute(stmt)
return [meta for meta in result.scalars().all() if isinstance(meta, dict)]
async def get_chats_by_model_id(
self,
model_id: str,
filter: dict | None = None,
skip: int = 0,
limit: int = 50,
db: AsyncSession | None = None,
) -> dict:
from open_webui.models.users import User
async with get_async_db_context(db) as session:
chat_ids = select(ChatMessage.chat_id).filter(ChatMessage.model_id == model_id).group_by(ChatMessage.chat_id)
if filter:
if filter.get('start_date'):
chat_ids = chat_ids.filter(ChatMessage.created_at >= filter.get('start_date'))
if filter.get('end_date'):
chat_ids = chat_ids.filter(ChatMessage.created_at <= filter.get('end_date'))
chat_ids = chat_ids.subquery()
stmt = (
select(Chat.id, Chat.user_id, Chat.title, Chat.updated_at, User.name.label('user_name'))
.join(chat_ids, chat_ids.c.chat_id == Chat.id)
.outerjoin(User, User.id == Chat.user_id)
)
order_by = filter.get('order_by') if filter else None
direction = filter.get('direction') if filter else None
is_asc = direction == 'asc'
if order_by == 'title':
primary_sort = Chat.title.asc() if is_asc else Chat.title.desc()
elif order_by == 'user_name':
primary_sort = User.name.asc() if is_asc else User.name.desc()
else:
primary_sort = Chat.updated_at.asc() if is_asc else Chat.updated_at.desc()
stmt = stmt.order_by(primary_sort, Chat.id.asc())
count_result = await session.execute(select(func.count()).select_from(stmt.subquery()))
total = count_result.scalar()
if skip:
stmt = stmt.offset(skip)
if limit:
stmt = stmt.limit(limit)
result = await session.execute(stmt)
return {
'items': [
{
'chat_id': chat.id,
'user_id': chat.user_id,
'user_name': chat.user_name,
'first_message': chat.title,
'updated_at': chat.updated_at,
}
for chat in result.all()
],
'total': total,
}
# retrieve conversation
async def get_chat_by_id(
self,
+20 -48
View File
@@ -279,6 +279,9 @@ class ModelChatsResponse(BaseModel):
total: int
MODEL_CHAT_ORDER_FIELDS = {'title', 'updated_at', 'user_name'}
@router.get('/models/{model_id:path}/chats', response_model=ModelChatsResponse)
async def get_model_chats(
model_id: str,
@@ -286,65 +289,34 @@ async def get_model_chats(
end_date: Optional[int] = Query(None),
skip: int = Query(0),
limit: int = Query(50, le=100),
order_by: str = Query('updated_at'),
direction: str = Query('desc'),
user=Depends(get_admin_user),
db: AsyncSession = Depends(get_async_session),
):
"""Get chats that used a specific model, with preview and feedback info."""
filter = {}
if start_date:
filter['start_date'] = start_date
if end_date:
filter['end_date'] = end_date
if order_by in MODEL_CHAT_ORDER_FIELDS:
filter['order_by'] = order_by
if direction in {'asc', 'desc'}:
filter['direction'] = direction
# Get chat IDs that used this model
chat_ids = await ChatMessages.get_chat_ids_by_model_id(
result = await Chats.get_chats_by_model_id(
model_id=model_id,
start_date=start_date,
end_date=end_date,
filter=filter,
skip=skip,
limit=limit,
db=db,
)
if not chat_ids:
return ModelChatsResponse(chats=[], total=0)
# Get chat details from messages only
chats_data = []
for chat_id in chat_ids:
messages = await ChatMessages.get_messages_by_chat_id(chat_id, db=db)
if not messages:
continue
# Get user_id from first user message
first_user_msg = next((m for m in messages if m.role == 'user'), None)
user_id = first_user_msg.user_id if first_user_msg else None
# Extract first message content as preview
first_message = None
if first_user_msg and first_user_msg.content:
content = first_user_msg.content
if isinstance(content, str):
first_message = content[:200]
elif isinstance(content, list):
text_parts = [b.get('text', '') for b in content if isinstance(b, dict)]
first_message = ' '.join(text_parts)[:200]
# Get user info
user_name = None
if user_id:
user_info = await Users.get_user_by_id(user_id, db=db)
user_name = user_info.name if user_info else None
# Timestamps from messages
updated_at = max(m.created_at for m in messages) if messages else 0
chats_data.append(
ModelChatEntry(
chat_id=chat_id,
user_id=user_id,
user_name=user_name,
first_message=first_message,
updated_at=updated_at,
)
)
return ModelChatsResponse(chats=chats_data, total=len(chats_data))
return ModelChatsResponse(
chats=[ModelChatEntry.model_validate(chat) for chat in result['items']],
total=result['total'] or 0,
)
####################