Spaces:
Running
Running
Update app/services.py
Browse files- app/services.py +35 -8
app/services.py
CHANGED
|
@@ -402,7 +402,7 @@ async def get_rag_response(request_data: ChatRequest, api_key: Optional[str] = N
|
|
| 402 |
|
| 403 |
if doc_count == 0:
|
| 404 |
logger.warning("⚠️ Vector DB is empty. Cannot answer query.")
|
| 405 |
-
return "
|
| 406 |
|
| 407 |
# Step 3: Retrieve relevant chunks from ChromaDB
|
| 408 |
logger.info("🔎 Retrieving relevant chunks from vector DB...")
|
|
@@ -413,7 +413,7 @@ async def get_rag_response(request_data: ChatRequest, api_key: Optional[str] = N
|
|
| 413 |
|
| 414 |
if not retrieved_chunks or not retrieved_chunks.get('documents') or not retrieved_chunks['documents'][0]:
|
| 415 |
logger.warning("❌ No relevant chunks found in the vector DB for this query.")
|
| 416 |
-
return "I
|
| 417 |
|
| 418 |
# Log retrieved chunks
|
| 419 |
chunks = retrieved_chunks['documents'][0]
|
|
@@ -427,14 +427,26 @@ async def get_rag_response(request_data: ChatRequest, api_key: Optional[str] = N
|
|
| 427 |
logger.warning(f"⚠️ Context too long, truncating to {max_context_length}")
|
| 428 |
context_for_prompt = context_for_prompt[:max_context_length] + "\n\n[... content truncated ...]"
|
| 429 |
|
| 430 |
-
# Step 4: Construct prompt for the LLM
|
| 431 |
full_prompt = (
|
| 432 |
-
"
|
| 433 |
-
"
|
| 434 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 435 |
f"{context_for_prompt}\n\n"
|
| 436 |
-
|
| 437 |
-
"
|
|
|
|
|
|
|
| 438 |
)
|
| 439 |
|
| 440 |
# Step 5: Generate the response using the LLM
|
|
@@ -459,6 +471,21 @@ async def get_rag_response(request_data: ChatRequest, api_key: Optional[str] = N
|
|
| 459 |
logger.error(f"❌ An unexpected error occurred: {e}", exc_info=True)
|
| 460 |
return f"An unexpected error occurred: {e}"
|
| 461 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 462 |
async def execute_task(request_data: TaskRequest, api_key: Optional[str] = None) -> str:
|
| 463 |
"""
|
| 464 |
Executes a specific task on the given context.
|
|
|
|
| 402 |
|
| 403 |
if doc_count == 0:
|
| 404 |
logger.warning("⚠️ Vector DB is empty. Cannot answer query.")
|
| 405 |
+
return "I don't have any specific context loaded right now. Please provide some context in the Knowledge Base and click 'Index Context' before asking questions. However, I'd be happy to help with general questions using my built-in knowledge!"
|
| 406 |
|
| 407 |
# Step 3: Retrieve relevant chunks from ChromaDB
|
| 408 |
logger.info("🔎 Retrieving relevant chunks from vector DB...")
|
|
|
|
| 413 |
|
| 414 |
if not retrieved_chunks or not retrieved_chunks.get('documents') or not retrieved_chunks['documents'][0]:
|
| 415 |
logger.warning("❌ No relevant chunks found in the vector DB for this query.")
|
| 416 |
+
return "I couldn't find specific information about that in the provided context. Let me help you with what I know from my general knowledge:\n\n" + await _generate_fallback_response(request_data.prompt, api_key)
|
| 417 |
|
| 418 |
# Log retrieved chunks
|
| 419 |
chunks = retrieved_chunks['documents'][0]
|
|
|
|
| 427 |
logger.warning(f"⚠️ Context too long, truncating to {max_context_length}")
|
| 428 |
context_for_prompt = context_for_prompt[:max_context_length] + "\n\n[... content truncated ...]"
|
| 429 |
|
| 430 |
+
# Step 4: Construct improved prompt for the LLM
|
| 431 |
full_prompt = (
|
| 432 |
+
"You are an intelligent assistant with access to specific context information. "
|
| 433 |
+
"Your goal is to provide comprehensive, helpful answers that combine the provided context with your expertise.\n\n"
|
| 434 |
+
|
| 435 |
+
"INSTRUCTIONS:\n"
|
| 436 |
+
"• Use the provided context as your PRIMARY source when it's relevant\n"
|
| 437 |
+
"• If the context fully answers the question, focus on that information and enhance it with practical insights\n"
|
| 438 |
+
"• If the context only partially addresses the question, build upon it with your knowledge\n"
|
| 439 |
+
"• If the context isn't relevant to the question, briefly mention this and provide a helpful answer based on your expertise\n"
|
| 440 |
+
"• Be natural and conversational - avoid robotic phrases like 'based solely on the context'\n"
|
| 441 |
+
"• Provide actionable, practical advice when appropriate\n"
|
| 442 |
+
"• Structure your response clearly with headings or bullet points when helpful\n\n"
|
| 443 |
+
|
| 444 |
+
"CONTEXT INFORMATION:\n"
|
| 445 |
f"{context_for_prompt}\n\n"
|
| 446 |
+
|
| 447 |
+
f"USER QUESTION: {request_data.prompt}\n\n"
|
| 448 |
+
|
| 449 |
+
"Please provide a comprehensive, helpful response:"
|
| 450 |
)
|
| 451 |
|
| 452 |
# Step 5: Generate the response using the LLM
|
|
|
|
| 471 |
logger.error(f"❌ An unexpected error occurred: {e}", exc_info=True)
|
| 472 |
return f"An unexpected error occurred: {e}"
|
| 473 |
|
| 474 |
+
|
| 475 |
+
async def _generate_fallback_response(prompt: str, api_key: Optional[str] = None) -> str:
|
| 476 |
+
"""Generate a response using only the model's knowledge when no context is available."""
|
| 477 |
+
fallback_prompt = (
|
| 478 |
+
f"Please provide a helpful, comprehensive answer to this question using your knowledge:\n\n"
|
| 479 |
+
f"Question: {prompt}\n\n"
|
| 480 |
+
f"Answer:"
|
| 481 |
+
)
|
| 482 |
+
|
| 483 |
+
try:
|
| 484 |
+
return await _generate_response_async(fallback_prompt, api_key)
|
| 485 |
+
except Exception as e:
|
| 486 |
+
logger.error(f"❌ Fallback response generation failed: {e}")
|
| 487 |
+
return "I'm having trouble generating a response right now. Please try again or rephrase your question."
|
| 488 |
+
|
| 489 |
async def execute_task(request_data: TaskRequest, api_key: Optional[str] = None) -> str:
|
| 490 |
"""
|
| 491 |
Executes a specific task on the given context.
|