Update app.py
Browse files
app.py
CHANGED
|
@@ -1187,7 +1187,11 @@ def get_behavior_instructions() -> str:
|
|
| 1187 |
|
| 1188 |
|
| 1189 |
def _looks_social_or_greeting(question: str) -> bool:
|
| 1190 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1191 |
|
| 1192 |
|
| 1193 |
async def _interpret_semantics(question: str, history=None) -> dict:
|
|
@@ -1545,10 +1549,45 @@ async def agent_query(req: AgentRequest):
|
|
| 1545 |
}
|
| 1546 |
|
| 1547 |
if _looks_social_or_greeting(q_clean):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1548 |
general = await _answer_general(question, history)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1549 |
elapsed = time.time() - start
|
| 1550 |
return {
|
| 1551 |
-
"answer":
|
| 1552 |
"intent": "social_greeting",
|
| 1553 |
"tools_used": ["general"],
|
| 1554 |
"search_results": [],
|
|
@@ -1674,7 +1713,10 @@ async def agent_query(req: AgentRequest):
|
|
| 1674 |
natural_query = search_plan["natural"]
|
| 1675 |
database_query = search_plan["database_query"] or search_plan["corrected"]
|
| 1676 |
elif intent == "library_info" and interp.get("grounding_keys"):
|
| 1677 |
-
#
|
|
|
|
|
|
|
|
|
|
| 1678 |
resolved = " ".join([question] + interp.get("canonical_terms", []) + [GROUNDED_LIBRARY_MAP.get(k, "") for k in interp.get("grounding_keys", []) if GROUNDED_LIBRARY_MAP.get(k)])
|
| 1679 |
question = re.sub(r"\s+", " ", resolved).strip()
|
| 1680 |
except Exception:
|
|
|
|
| 1187 |
|
| 1188 |
|
| 1189 |
def _looks_social_or_greeting(question: str) -> bool:
|
| 1190 |
+
# SOCIAL_RE is anchored with ^ so .match() is the correct call.
|
| 1191 |
+
# Using .search() with ^ worked most of the time but could silently
|
| 1192 |
+
# fail when the engine didn't treat ^ as start-of-string in search mode
|
| 1193 |
+
# with certain Unicode inputs β .match() is unambiguous.
|
| 1194 |
+
return bool(SOCIAL_RE.match((question or "").strip()))
|
| 1195 |
|
| 1196 |
|
| 1197 |
async def _interpret_semantics(question: str, history=None) -> dict:
|
|
|
|
| 1549 |
}
|
| 1550 |
|
| 1551 |
if _looks_social_or_greeting(q_clean):
|
| 1552 |
+
# ββ Try the hardcoded backstop first β zero latency, always correct ββ
|
| 1553 |
+
# This guarantees "who are you", "how are you", etc. NEVER produce
|
| 1554 |
+
# "I don't have information" even if _answer_general has edge-case failures.
|
| 1555 |
+
fixed = _fixed_social_answer(q_clean)
|
| 1556 |
+
if fixed:
|
| 1557 |
+
elapsed = time.time() - start
|
| 1558 |
+
return {
|
| 1559 |
+
"answer": fixed,
|
| 1560 |
+
"intent": "social_greeting",
|
| 1561 |
+
"tools_used": [],
|
| 1562 |
+
"search_results": [],
|
| 1563 |
+
"sources": [],
|
| 1564 |
+
"model_used": req.model,
|
| 1565 |
+
"response_time": round(elapsed, 2),
|
| 1566 |
+
"corrected_query": question,
|
| 1567 |
+
"natural_query": question,
|
| 1568 |
+
"database_query": question,
|
| 1569 |
+
"original_question": question,
|
| 1570 |
+
"is_follow_up": False,
|
| 1571 |
+
"source_mode": "social",
|
| 1572 |
+
}
|
| 1573 |
+
# ββ Fall through to general LLM for social questions not in the fixed list ββ
|
| 1574 |
general = await _answer_general(question, history)
|
| 1575 |
+
# If the general answer is empty or looks like a "no info" reply, substitute a safe fallback
|
| 1576 |
+
gen_answer = general.get("answer", "").strip()
|
| 1577 |
+
no_info_social = [
|
| 1578 |
+
"i don't have", "i do not have", "no specific information",
|
| 1579 |
+
"not available", "cannot find", "unable to find", "no information",
|
| 1580 |
+
]
|
| 1581 |
+
gen_lower = gen_answer.lower().replace("\u2019", "'").replace("\u2018", "'")
|
| 1582 |
+
if not gen_answer or any(p in gen_lower for p in no_info_social):
|
| 1583 |
+
gen_answer = (
|
| 1584 |
+
"I'm <strong>LibBee</strong>, the Khalifa University Library AI Assistant. "
|
| 1585 |
+
"I'm here to help with library questions, books, articles, databases, "
|
| 1586 |
+
"full text access, and library services. What can I help you with?"
|
| 1587 |
+
)
|
| 1588 |
elapsed = time.time() - start
|
| 1589 |
return {
|
| 1590 |
+
"answer": gen_answer,
|
| 1591 |
"intent": "social_greeting",
|
| 1592 |
"tools_used": ["general"],
|
| 1593 |
"search_results": [],
|
|
|
|
| 1713 |
natural_query = search_plan["natural"]
|
| 1714 |
database_query = search_plan["database_query"] or search_plan["corrected"]
|
| 1715 |
elif intent == "library_info" and interp.get("grounding_keys"):
|
| 1716 |
+
# Strengthen RAG using interpreted canonical library terms.
|
| 1717 |
+
# IMPORTANT: only mutate `question` for library_info intent β
|
| 1718 |
+
# social/general questions must NOT be expanded with library keywords
|
| 1719 |
+
# because that causes the synthesis LLM to produce "I don't have information".
|
| 1720 |
resolved = " ".join([question] + interp.get("canonical_terms", []) + [GROUNDED_LIBRARY_MAP.get(k, "") for k in interp.get("grounding_keys", []) if GROUNDED_LIBRARY_MAP.get(k)])
|
| 1721 |
question = re.sub(r"\s+", " ", resolved).strip()
|
| 1722 |
except Exception:
|