fixed the RAg in test pipeline issue

This commit is contained in:
belviskhoremk
2026-04-26 18:51:48 +00:00
parent 205d9d7901
commit 97a501097d
14 changed files with 249 additions and 57 deletions

View File

@@ -2,7 +2,7 @@ import time
from collections import defaultdict
from fastapi import APIRouter, HTTPException, Depends, Request
from app.models import ChatMessage, ChatResponse, ConversationResponse, MessageResponse, FeedbackCreate
from app.models import ChatMessage, ChatResponse, ConversationResponse, MessageResponse, FeedbackCreate, TestChatRequest, TestChatResult
from app.database import get_supabase
from app.dependencies import get_current_user, get_optional_user
from app.services.rag import rag_engine
@@ -15,6 +15,8 @@ import logging
logger = logging.getLogger(__name__)
router = APIRouter(tags=["Chat"])
CONFIDENCE_THRESHOLD = 0.55
# ── Simple in-memory rate limiter ────────────────────────────────────────────
_rate_store: dict = defaultdict(list)
_RATE_LIMIT = 30 # max requests
@@ -166,29 +168,27 @@ async def chat(
language=message.language,
)
# Compute confidence score
confidence_score = max((s.score for s in result.get("sources", [])), default=0.0)
confidence_score = result.get("confidence_score", 0.0)
# Check handoff
is_handoff = False
low_confidence = confidence_score < CONFIDENCE_THRESHOLD
if chatbot.get("handoff_enabled"):
handoff_keywords = chatbot.get("handoff_keywords", [])
msg_lower = message.message.lower()
if any(kw.lower() in msg_lower for kw in handoff_keywords):
keyword_triggered = any(kw.lower() in msg_lower for kw in handoff_keywords)
if keyword_triggered or low_confidence:
is_handoff = True
# Fire n8n notification (async, non-blocking)
try:
from app.services.n8n_service import send_handoff_notification
from app.config import settings as _settings
company_data_for_handoff = chatbot.get("companies", {}) or {}
await send_handoff_notification(
from app.services.notification_service import send_handoff_alert
await send_handoff_alert(
chatbot_id=chatbot_id,
chatbot_name=chatbot.get("name", ""),
owner_email=chatbot.get("handoff_email") or "",
conversation_history=history,
trigger_message=message.message,
chatbot_id=chatbot_id,
conversation_id=conversation["id"],
webhook_url=_settings.n8n_handoff_webhook_url,
low_confidence=low_confidence,
supabase=supabase,
)
except Exception:
pass # never block chat on handoff failure
@@ -228,6 +228,7 @@ async def chat(
tokens_used=result.get("tokens_used", 0),
needs_lead_capture=needs_lead_capture,
handoff=is_handoff,
low_confidence=low_confidence,
)
@@ -289,6 +290,56 @@ async def submit_feedback(chatbot_id: str, data: FeedbackCreate):
return {"success": True}
@router.post("/chat/{chatbot_id}/test", response_model=List[TestChatResult])
async def test_chat(
chatbot_id: str,
body: TestChatRequest,
user=Depends(get_current_user),
):
"""Run test questions against a chatbot without saving to conversation history. Owner only."""
supabase = get_supabase()
chatbot = _get_public_chatbot(chatbot_id, supabase)
company = supabase.table("companies").select("id").eq("owner_id", user.id).execute()
if not company.data or company.data[0]["id"] != chatbot.get("company_id"):
raise HTTPException(status_code=403, detail="Access denied")
collection_name = chatbot.get("qdrant_collection_name")
if not collection_name:
raise HTTPException(status_code=400, detail="Chatbot has no knowledge base configured")
company_data = chatbot.get("companies", {}) or {}
chatbot_config = {**chatbot, "company_name": company_data.get("name", "")}
results = []
for question in body.questions:
try:
result = await rag_engine.process_query(
query=question,
collection_name=collection_name,
chatbot_config=chatbot_config,
conversation_history=[],
language="auto",
bypass_cache=True,
)
results.append(TestChatResult(
question=question,
response=result["response"],
confidence_score=result.get("confidence_score", 0.0),
sources=result.get("sources", []),
model_used=result.get("model", ""),
))
except Exception as e:
results.append(TestChatResult(
question=question,
response=f"Error: {e}",
confidence_score=0.0,
sources=[],
model_used="",
))
return results
# ── OLD analytics endpoint REMOVED ───────────────────────────────────────────
# The /analytics/{chatbot_id} endpoint that was here has been replaced by
# the dedicated analytics router (app/routers/analytics.py) which provides: