Update src/api/agent.py
Browse files- src/api/agent.py +37 -13
src/api/agent.py
CHANGED
|
@@ -405,13 +405,20 @@ def _rule_based_classify(question: str) -> Dict[str, str]:
|
|
| 405 |
def _hours_answer() -> str:
|
| 406 |
return (
|
| 407 |
"Here are the current <strong>Khalifa University Library</strong> hours:<br><br>"
|
| 408 |
-
"<strong>
|
| 409 |
"Sunday β Wednesday: 8:00 AM β 7:00 PM<br>"
|
| 410 |
"Thursday: 8:00 AM β 4:00 PM<br>"
|
| 411 |
"Friday: Closed<br>"
|
| 412 |
-
"Saturday: 12:00 PM β 8:00 PM<br>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 413 |
"β οΈ Hours may change during exam periods, public holidays, and Ramadan. "
|
| 414 |
-
"Always check the official Library Hours page for the latest
|
| 415 |
f'<a href="{LIBRARY_HOURS_URL}" target="_blank">{LIBRARY_HOURS_URL}</a>'
|
| 416 |
)
|
| 417 |
|
|
@@ -1436,10 +1443,23 @@ def _database_recommendation_answer(question: str) -> str:
|
|
| 1436 |
# ββ Research Snapshot βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1437 |
|
| 1438 |
async def _research_snapshot(context: SearchContextPayload, model: str) -> Tuple[str, List[dict], List[dict]]:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1439 |
topic = context.topic
|
| 1440 |
-
papers = await _semantic_scholar_search(topic, limit=8)
|
| 1441 |
references: List[dict] = []
|
| 1442 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1443 |
search_results = primo_result.get("results", []) or []
|
| 1444 |
|
| 1445 |
if papers:
|
|
@@ -1451,10 +1471,9 @@ async def _research_snapshot(context: SearchContextPayload, model: str) -> Tuple
|
|
| 1451 |
answer = f"<strong>π Research Snapshot: {_escape(topic)}</strong><br><br>{summary}"
|
| 1452 |
if search_results:
|
| 1453 |
answer += (
|
| 1454 |
-
"<br><br><strong>KU Library
|
| 1455 |
-
"
|
| 1456 |
)
|
| 1457 |
-
answer += f"<br><br><strong>AI sources:</strong> {_database_guidance_for_topic(context)}"
|
| 1458 |
answer += "<br><br><strong>Selected references:</strong><br>"
|
| 1459 |
for i, paper in enumerate(papers[:6], 1):
|
| 1460 |
answer += (
|
|
@@ -1464,22 +1483,27 @@ async def _research_snapshot(context: SearchContextPayload, model: str) -> Tuple
|
|
| 1464 |
f'{_escape(paper["authors"])} Β· {paper["year"]} Β· {_escape(paper["venue"] or "")}'
|
| 1465 |
f"</span>"
|
| 1466 |
)
|
|
|
|
|
|
|
| 1467 |
answer += _source_badge("semantic", "https://www.semanticscholar.org/")
|
| 1468 |
if search_results:
|
| 1469 |
answer += _source_badge("primo", primo_url)
|
| 1470 |
references = [{"title": p["title"], "url": p["link"]} for p in papers[:6]]
|
| 1471 |
return answer, search_results, references
|
| 1472 |
|
|
|
|
| 1473 |
if search_results:
|
| 1474 |
answer = (
|
| 1475 |
-
f"<strong>π
|
| 1476 |
-
"
|
| 1477 |
-
|
|
|
|
| 1478 |
)
|
| 1479 |
else:
|
| 1480 |
answer = (
|
| 1481 |
-
f"
|
| 1482 |
-
|
|
|
|
| 1483 |
)
|
| 1484 |
answer += _source_badge("primo", primo_url)
|
| 1485 |
return answer, search_results, []
|
|
|
|
| 405 |
def _hours_answer() -> str:
|
| 406 |
return (
|
| 407 |
"Here are the current <strong>Khalifa University Library</strong> hours:<br><br>"
|
| 408 |
+
"<strong>π Main Campus Library (E Building, Main Campus, Abu Dhabi)</strong><br>"
|
| 409 |
"Sunday β Wednesday: 8:00 AM β 7:00 PM<br>"
|
| 410 |
"Thursday: 8:00 AM β 4:00 PM<br>"
|
| 411 |
"Friday: Closed<br>"
|
| 412 |
+
"Saturday: 12:00 PM β 8:00 PM<br>"
|
| 413 |
+
f'Reference desk: <a href="tel:+97123124604">+971 2 312 4604</a><br><br>'
|
| 414 |
+
"<strong>π Habshan Library (Building 5, SAN Campus, Abu Dhabi)</strong><br>"
|
| 415 |
+
"Sunday β Wednesday: 8:00 AM β 7:00 PM<br>"
|
| 416 |
+
"Thursday: 8:00 AM β 4:00 PM<br>"
|
| 417 |
+
"Friday: Closed<br>"
|
| 418 |
+
"Saturday: 12:00 PM β 8:00 PM<br>"
|
| 419 |
+
f'Service desk: <a href="tel:+97123123160">+971 2 312 3160</a><br><br>'
|
| 420 |
"β οΈ Hours may change during exam periods, public holidays, and Ramadan. "
|
| 421 |
+
"Always check the official Library Hours page for the latest:<br>"
|
| 422 |
f'<a href="{LIBRARY_HOURS_URL}" target="_blank">{LIBRARY_HOURS_URL}</a>'
|
| 423 |
)
|
| 424 |
|
|
|
|
| 1443 |
# ββ Research Snapshot βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1444 |
|
| 1445 |
async def _research_snapshot(context: SearchContextPayload, model: str) -> Tuple[str, List[dict], List[dict]]:
|
| 1446 |
+
"""
|
| 1447 |
+
Research snapshot:
|
| 1448 |
+
- Runs Semantic Scholar + PRIMO in parallel for speed.
|
| 1449 |
+
- If Semantic Scholar returns papers: generate cited summary, show refs, then AI tools at bottom.
|
| 1450 |
+
- If Semantic Scholar returns nothing: silently fall back to PRIMO results + AI tools.
|
| 1451 |
+
Never mention Semantic Scholar failure to the user.
|
| 1452 |
+
- AI tools panel always appears at the end.
|
| 1453 |
+
"""
|
| 1454 |
+
import asyncio as _asyncio
|
| 1455 |
topic = context.topic
|
|
|
|
| 1456 |
references: List[dict] = []
|
| 1457 |
+
|
| 1458 |
+
# Parallel fetch β don't wait for Semantic Scholar before starting PRIMO
|
| 1459 |
+
papers, (primo_result, primo_url) = await _asyncio.gather(
|
| 1460 |
+
_semantic_scholar_search(topic, limit=8),
|
| 1461 |
+
_search_primo_catalog(context, limit=6),
|
| 1462 |
+
)
|
| 1463 |
search_results = primo_result.get("results", []) or []
|
| 1464 |
|
| 1465 |
if papers:
|
|
|
|
| 1471 |
answer = f"<strong>π Research Snapshot: {_escape(topic)}</strong><br><br>{summary}"
|
| 1472 |
if search_results:
|
| 1473 |
answer += (
|
| 1474 |
+
"<br><br><strong>KU Library results:</strong> "
|
| 1475 |
+
"KU-accessible items are shown below β open them directly or use the AI tools for a deeper search."
|
| 1476 |
)
|
|
|
|
| 1477 |
answer += "<br><br><strong>Selected references:</strong><br>"
|
| 1478 |
for i, paper in enumerate(papers[:6], 1):
|
| 1479 |
answer += (
|
|
|
|
| 1483 |
f'{_escape(paper["authors"])} Β· {paper["year"]} Β· {_escape(paper["venue"] or "")}'
|
| 1484 |
f"</span>"
|
| 1485 |
)
|
| 1486 |
+
# AI tools always at the bottom
|
| 1487 |
+
answer += f"<br><br>{_database_guidance_for_topic(context)}"
|
| 1488 |
answer += _source_badge("semantic", "https://www.semanticscholar.org/")
|
| 1489 |
if search_results:
|
| 1490 |
answer += _source_badge("primo", primo_url)
|
| 1491 |
references = [{"title": p["title"], "url": p["link"]} for p in papers[:6]]
|
| 1492 |
return answer, search_results, references
|
| 1493 |
|
| 1494 |
+
# Semantic Scholar returned nothing β silent fallback, no error message
|
| 1495 |
if search_results:
|
| 1496 |
answer = (
|
| 1497 |
+
f"<strong>π Research starting points: {_escape(topic)}</strong><br><br>"
|
| 1498 |
+
"Here are KU-accessible results you can open immediately. "
|
| 1499 |
+
"For a deeper literature synthesis, use the AI research tools below."
|
| 1500 |
+
f"<br><br>{_database_guidance_for_topic(context)}"
|
| 1501 |
)
|
| 1502 |
else:
|
| 1503 |
answer = (
|
| 1504 |
+
f"<strong>π Research starting points: {_escape(topic)}</strong><br><br>"
|
| 1505 |
+
"I didn't find direct results right now β try the AI research tools below for a deep search on this topic."
|
| 1506 |
+
f"<br><br>{_database_guidance_for_topic(context)}"
|
| 1507 |
)
|
| 1508 |
answer += _source_badge("primo", primo_url)
|
| 1509 |
return answer, search_results, []
|