Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions RAGManager/RAG Manager API/Get Chat History.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
meta {
name: Get Chat History
type: http
seq: 1
}

get {
url: {{base_url}}/api/{{api_version}}/chat/history/{{test_session_id}}
body: none
auth: none
}

settings {
encodeUrl: true
}
9 changes: 9 additions & 0 deletions RAGManager/RAG Manager API/bruno.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"version": "1",
"name": "RAG Manager API",
"type": "collection",
"ignore": [
"node_modules",
".git"
]
}
5 changes: 5 additions & 0 deletions RAGManager/RAG Manager API/environments/Local Development.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
vars {
base_url: http://localhost:8000
api_version: v1
test_session_id: 550e8400-e29b-41d4-a716-446655440000
}
5 changes: 3 additions & 2 deletions RAGManager/app/api/routes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

from fastapi import APIRouter

from app.api.routes import documents
from app.api.routes import chat, documents

router = APIRouter(prefix="/api/v1")

router.include_router(documents.router)
router.include_router(documents.router)
router.include_router(chat.router)
70 changes: 70 additions & 0 deletions RAGManager/app/api/routes/chat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""API routes for chat-related endpoints."""

import logging
from uuid import UUID

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session

from app.core.database_connection import get_db
from app.schemas.chat import ChatHistoryResponse, ChatMessageResponse
from app.services.chat import get_chat_history

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/chat", tags=["chat"])


@router.get("/history/{chat_session_id}", response_model=ChatHistoryResponse)
async def get_chat_history_endpoint(
chat_session_id: UUID,
db: Session = Depends(get_db),
) -> ChatHistoryResponse:
"""
Retrieve the last 10 messages from a chat session.

This endpoint returns the most recent 10 messages from the specified chat session,
ordered by creation time (most recent first).

Args:
chat_session_id: UUID of the chat session
db: Database session dependency

Returns:
ChatHistoryResponse containing the session_id, list of messages, and count

Raises:
HTTPException: 404 if chat session doesn't exist
HTTPException: 400 if invalid UUID format
HTTPException: 500 for database errors
"""
logger.info(f"Received chat history request for session: {chat_session_id}")

try:
# Get chat history from service
messages = get_chat_history(db, chat_session_id)

# Convert SQLAlchemy models to Pydantic models
message_responses = [
ChatMessageResponse(
id=msg.id,
session_id=msg.session_id,
sender=msg.sender,
message=msg.message,
created_at=msg.created_at,
)
for msg in messages
]

return ChatHistoryResponse(
session_id=chat_session_id,
messages=message_responses,
count=len(message_responses),
)

except ValueError as e:
logger.warning(f"Chat session not found: {e}")
raise HTTPException(status_code=404, detail=str(e))
except Exception as e:
logger.error(f"Error retrieving chat history: {e}")
raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
3 changes: 1 addition & 2 deletions RAGManager/app/models/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ class ChatSession(Base):
__tablename__ = "chat_sessions"

id = Column(PGUUID(as_uuid=True), primary_key=True, server_default="uuid_generate_v4()")
user_id = Column(Text, nullable=True, index=True) # User ID for ownership validation
created_at = Column(TIMESTAMP, default=datetime.utcnow, nullable=False)
metadata = Column(JSONB, nullable=True)
session_metadata = Column("metadata", JSONB, nullable=True) # Map to 'metadata' column in DB

# Relationship to messages
messages = relationship("ChatMessage", back_populates="session", cascade="all, delete-orphan")
Expand Down
29 changes: 29 additions & 0 deletions RAGManager/app/schemas/chat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""Pydantic schemas for chat-related endpoints."""

from datetime import datetime
from uuid import UUID

from pydantic import BaseModel


class ChatMessageResponse(BaseModel):
"""Response schema for a single chat message."""

id: int
session_id: UUID
sender: str # 'user', 'assistant', or 'system'
message: str
created_at: datetime

class Config:
"""Pydantic config."""

from_attributes = True


class ChatHistoryResponse(BaseModel):
"""Response schema for chat history endpoint."""

session_id: UUID
messages: list[ChatMessageResponse]
count: int
44 changes: 44 additions & 0 deletions RAGManager/app/services/chat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""Service functions for chat-related operations."""

import logging
from uuid import UUID

from sqlalchemy.orm import Session

from app.models.chat import ChatMessage, ChatSession

logger = logging.getLogger(__name__)


def get_chat_history(db: Session, session_id: UUID) -> list[ChatMessage]:
"""
Retrieve the last 10 messages from a chat session.

Args:
db: SQLAlchemy database session
session_id: UUID of the chat session

Returns:
List of ChatMessage objects ordered by created_at DESC (most recent first)

Raises:
ValueError: If the chat session doesn't exist
"""
# First, validate that the session exists
session = db.query(ChatSession).filter(ChatSession.id == session_id).first()
if not session:
raise ValueError(f"Chat session {session_id} not found")

# Query the last 10 messages for this session, ordered by created_at DESC
messages = (
db.query(ChatMessage)
.filter(ChatMessage.session_id == session_id)
.order_by(ChatMessage.created_at.desc())
.limit(10)
.all()
)

# Reverse to get chronological order (oldest first)
# But the plan says "most recent first", so we'll keep DESC order
logger.info(f"Retrieved {len(messages)} messages for session {session_id}")
return messages
Loading