fix: route conversational queries early in stream_answer to bypass RAG retrieval and ensure correct greeting/identity responses
Browse files- app/services/engine.py +39 -0
app/services/engine.py
CHANGED
|
@@ -514,6 +514,45 @@ async def stream_answer(
|
|
| 514 |
yield {"type": "done"}
|
| 515 |
return
|
| 516 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 517 |
# Compute query embeddings for cache and search
|
| 518 |
embedding_fn = rag._get_embedding_fn()
|
| 519 |
query_embeddings = await asyncio.to_thread(embedding_fn, [query])
|
|
|
|
| 514 |
yield {"type": "done"}
|
| 515 |
return
|
| 516 |
|
| 517 |
+
# ── Step 1.2: Early Conversational Query Check ──────────────────────────────
|
| 518 |
+
if is_conversational_query(query):
|
| 519 |
+
logger.info("Conversational query detected: '%s'", query[:80])
|
| 520 |
+
engine_mode = "hybrid" if is_online else "fallback"
|
| 521 |
+
yield {"type": "status", "engine_mode": engine_mode}
|
| 522 |
+
yield {"type": "citations", "citations": [], "is_grounded": True}
|
| 523 |
+
if is_online:
|
| 524 |
+
conv_prompt = [
|
| 525 |
+
{
|
| 526 |
+
"role": "system",
|
| 527 |
+
"content": (
|
| 528 |
+
"You are ByteAstra, a helpful AI tutoring assistant for BAMS (Bachelor of "
|
| 529 |
+
"Ayurvedic Medicine and Surgery) students, developed by the engineering team at Risu Solutions.\n\n"
|
| 530 |
+
"Your purpose is to guide students through the BAMS syllabus and classical Ayurvedic texts "
|
| 531 |
+
"(like Charaka Samhita, Sushruta Samhita, and Ashtanga Hridaya) by providing detailed, exam-quality answers with verified citations.\n\n"
|
| 532 |
+
"Introduce yourself as ByteAstra, created by Risu Solutions, and explain your purpose. "
|
| 533 |
+
"Keep your response brief, friendly, and polite."
|
| 534 |
+
)
|
| 535 |
+
}
|
| 536 |
+
]
|
| 537 |
+
conv_prompt.extend(history[-6:])
|
| 538 |
+
conv_prompt.append({"role": "user", "content": query})
|
| 539 |
+
|
| 540 |
+
async for token in llm.stream_completion(
|
| 541 |
+
conv_prompt,
|
| 542 |
+
model=llm_cfg.get("model_name"),
|
| 543 |
+
temperature=0.7,
|
| 544 |
+
max_tokens=128, # conversational — keep short
|
| 545 |
+
):
|
| 546 |
+
yield {"type": "delta", "content": token}
|
| 547 |
+
else:
|
| 548 |
+
fallback_msg = get_conversational_response_fallback(query)
|
| 549 |
+
for word in fallback_msg.split(" "):
|
| 550 |
+
yield {"type": "delta", "content": word + " "}
|
| 551 |
+
await asyncio.sleep(0.01)
|
| 552 |
+
|
| 553 |
+
yield {"type": "done"}
|
| 554 |
+
return
|
| 555 |
+
|
| 556 |
# Compute query embeddings for cache and search
|
| 557 |
embedding_fn = rag._get_embedding_fn()
|
| 558 |
query_embeddings = await asyncio.to_thread(embedding_fn, [query])
|