File size: 53,097 Bytes
41fe3fc | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 | """All compiled regexes, URLs, keyword lists and LLM system prompts. No logic lives here."""
import asyncio
import html
import json
import logging
import os
import re
import time
import uuid
from datetime import datetime
from typing import Any, Dict, List, Literal, Optional, Tuple
from urllib.parse import quote
import httpx
from pydantic import BaseModel, ConfigDict, Field
from src.config import get_settings, LIBBEE_VERSION
logger = logging.getLogger(__name__)
LIBRARY_HOURS_URL = "https://library.ku.ac.ae/hours"
KU_MAIN_URL = "https://www.ku.ac.ae/"
ASK_LIBRARIAN_URL = "https://library.ku.ac.ae/AskUs"
PRIMO_BASE_URL = "https://khalifa.primo.exlibrisgroup.com/discovery/search?vid=971KUOSTAR_INST:KU"
PRIMO_AI_URL = "https://khalifa.primo.exlibrisgroup.com/discovery/researchAssistant?vid=971KUOSTAR_INST:KU&query="
HISTORY_WINDOW = 6
CURRENT_YEAR = datetime.utcnow().year
_RESOURCE_TYPE_NOISE = re.compile(
r"\b(articles?|papers?|books?|ebooks?|journals?|publications?|monographs?"
r"|peer[- ]reviewed|open[- ]access|studies|study|research)\b",
re.IGNORECASE,
)
SOCIAL_RE = re.compile(
r"^(hi|hello|hey|good morning|good afternoon|good evening|how are you|hows it going"
r"|how are you doing|who are you|what are you|tell me about yourself|what can you do"
r"|what do you do|how can you help|what help can you provide|are you a bot|are you a robot"
r"|are you ai|are you an ai|thank you|thanks|thx|bye|goodbye|see you|lol|haha"
r"|you are silly|are you silly|are you dumb|stupid bot|dumb bot|idiot bot"
r"|joke|tell me a joke)$",
re.IGNORECASE,
)
PURE_GREETING_RE = re.compile(
r"^(hi|hello|hey|good morning|good afternoon|good evening)[!.\s]*$",
re.IGNORECASE,
)
GREETING_FOLLOWUP_RE = re.compile(
r"^(yes|yes please|yes check|sure|okay|ok|yeah|yep|please do|go ahead)$",
re.IGNORECASE,
)
HOURS_RE = re.compile(
r"\b(library hours?|opening hours?|closing hours?|open hours?|open today|open tomorrow"
r"|open now|open on|open this|closed today|closed tomorrow|closed on|closed this"
r"|when.*open|when.*close|when.*does.*library|what time.*open|what time.*close"
r"|what time.*library|opening time|closing time|is.*library.*open|is.*campus.*library"
r"|is.*habshan.*open|is.*san.*open|is.*library.*closed|will.*library.*open"
r"|will.*it.*open|does.*library.*open|library.*open.*today|library.*close.*today"
r"|habshan.*open|san.*open|main campus.*open|ramadan hours?|weekend hours?"
r"|friday hours?|saturday hours?|sunday hours?|library.*schedule|schedule.*library"
r"|what.*hours|till.*when|until.*when|what day.*open|which day.*open"
r"|what day.*closed|which day.*closed"
r"|library\s+timing[s]?|timing[s]?\s+library|library\s+time[s]?"
r"|library\s+open\s+time|library\s+close\s+time"
r"|ku\s+library\s+open|ku\s+library\s+close|ku.*library.*timing"
r"|libra[ry]+\s+timing[s]?|libra[ry]+\s+time[s]?"
r"|what\s+are\s+the\s+timing[s]?|what.*timing[s]?"
r"|is\s+library\s+open|is\s+ku.*open|ku.*open.*now"
r"|open\s+time.*library|close\s+time.*library"
r"|operating\s+hours?|working\s+hours?.*library|library.*working\s+hours?"
r"|when\s+can\s+i.*library|library.*available\s+now"
r"|library\s+open$|^library\s+open|library\s+closed$|^library\s+closed"
r"|library.*open.*week|library.*close.*week)\b",
re.IGNORECASE,
)
KU_CAMPUS_RE = re.compile(
r"\b(where is the library|where is.*library|library.*location|location.*library"
r"|which building|what building|which floor|main campus library|san campus library"
r"|habshan library|sas al nakhl library|library.*address|address.*library"
r"|how to get to.*library|how.*reach.*library|how.*find.*library"
r"|library.*campus(es)?|campus(es)?.*library|how many.*librar|how many.*branch"
r"|library.*branch(es)?|branch(es)?.*library|which campus.*library"
r"|library.*which campus|library.*map|map.*library|how many libraries"
r"|what libraries|which libraries|(ku|khalifa).*(has|have|got).*(librar|branch)"
r"|(librar|branch).*(ku|khalifa).*(has|have)"
r"|(all|both|two|2).*(libraries|library|branches)"
r"|tell me about.*(campus|libraries|branches)|describe.*(campus|libraries)"
r"|(what|where).*(campus|campuses).*(librar))\b",
re.IGNORECASE,
)
RESEARCH_CUE_RE = re.compile(
r"\b(find|search|look for|show me|get me|give me|locate|recommend|suggest"
r"|articles?|papers?|books?|journals?|studies|literature|research|systematic review"
r"|evidence|sources|database|databases|peer reviewed|advances?"
r"|approach(es)?|method(s|ology)?|technique[s]?|application[s]?|framework[s]?"
r"|model[s]?|algorithm[s]?|publication[s]?|recent work|current state|state of the art)\b",
re.IGNORECASE,
)
LIBRARY_CUE_RE = re.compile(
r"\b(library|librarian|borrow|loan|renew|fine|study room|room booking|reserve a room"
r"|account|my library|interlibrary|ill|khazna|orcid|open access|apc|refworks"
r"|libkey|hours|location|contact|visitor|alumni|database access|off campus|remote access)\b",
re.IGNORECASE,
)
MEDICAL_SEARCH_RE = re.compile(
r"\b(pubmed|embase|cinahl|clinicalkey|cochrane|uptodate|medline|systematic review"
r"|clinical trial|biomedical literature|medical literature)\b",
re.IGNORECASE,
)
CURRENT_INFO_RE = re.compile(
r"\b(current|currently|latest|today|recent|recently|now|this week|this month"
r"|news|update|updated|prime minister|ceo|minister|king|ruler|who won)\b",
re.IGNORECASE,
)
_GUARDRAIL = (
"IMPORTANT β GUARDRAILS: "
"You must never make negative, critical, or controversial statements about "
"Khalifa University, its leadership, staff, or policies; the UAE government, "
"its leaders, laws, or institutions; or any religion. "
"You must never generate sexually explicit, suggestive, or adult content of any kind. "
"You must never produce political criticism, propaganda, or inflammatory commentary "
"targeting UAE, its leadership, or any Gulf state government. "
"If asked for any of the above, politely decline and redirect to library services. "
"Never generate content that is offensive, discriminatory, or inappropriate "
"for a university academic environment. "
"You may answer general factual questions β such as historical facts, science, "
"geography, or current affairs β but always from a neutral, academic perspective. "
"Never produce content that could embarrass Khalifa University or its library."
)
_URL_INSTRUCTION = (
"IMPORTANT β URLS AND LINKS: "
"You must ONLY include URLs that are explicitly present in the context or "
"knowledge base provided to you, OR that appear in this fixed verified list of "
"KU Library URLs: "
"https://library.ku.ac.ae | "
"https://library.ku.ac.ae/hours | "
"https://library.ku.ac.ae/AskUs | "
"https://library.ku.ac.ae/ill/ | "
"https://library.ku.ac.ae/rooms/ | "
"https://library.ku.ac.ae/eresources | "
"https://library.ku.ac.ae/orcid | "
"https://library.ku.ac.ae/oa/ | "
"https://library.ku.ac.ae/alumni/ | "
"https://library.ku.ac.ae/med/ | "
"https://library.ku.ac.ae/requesttitle/ | "
"https://library.ku.ac.ae/google | "
"https://khazna.ku.ac.ae | "
"https://khalifa.primo.exlibrisgroup.com/discovery/search?vid=971KUOSTAR_INST:KU | "
"https://khalifa.primo.exlibrisgroup.com/discovery/account?vid=971KUOSTAR_INST:KU§ion=overview | "
"https://kustar.libcal.com/calendar/events | "
"https://ku-library.github.io/researchbee/. "
"NEVER invent, guess, or construct URLs that are not in the above list or "
"explicitly present in the provided context. "
"When a relevant verified URL exists for your answer, ALWAYS include it as a "
'clickable HTML link: <a href="URL" target="_blank">descriptive link text</a>. '
"If you are unsure whether a URL is correct, omit it entirely and direct the "
"user to Ask a Librarian at https://library.ku.ac.ae/AskUs instead."
)
_SENSITIVE_TOPIC_RE = re.compile(
r"\b("
r"(bad|worst|negative[s]?|problem[s]?|issue[s]?|weakness|weaknesses|"
r"criticism[s]?|criticise|criticize|critique|flaw[s]?|failure[s]?|"
r"scandal[s]?|corrupt\w*|mistake[s]?|disadvantage[s]?|downside[s]?|"
r"complaint[s]?|controversi\w*|shame|shameful|terrible|horrible|awful)"
r"\s.{0,50}(ku|khalifa\s+university|uae|emirates|dubai|abu\s+dhabi|"
r"uae\s+government|sheikh|ministry|ruler)"
r"|"
r"(ku|khalifa\s+university|uae|emirates|dubai|abu\s+dhabi|"
r"uae\s+government|sheikh|ministry|ruler)"
r"\s.{0,50}(bad|worst|negative|problem[s]?|issue[s]?|weakness|weaknesses|"
r"criticism[s]?|criticise|criticize|critique|flaw[s]?|failure[s]?|"
r"scandal[s]?|corrupt\w*|mistake[s]?|disadvantage[s]?|downside[s]?|"
r"complaint[s]?|shame|shameful|terrible|horrible|awful)"
r")\b",
re.IGNORECASE,
)
_INJECTION_RE = re.compile(
r"\b(ignore\s+(previous|above|all|prior)\s+instructions?"
r"|disregard\s+(all|previous|above|prior)\s+instructions?"
r"|override\s+(system|instructions?|prompt)"
r"|new\s+instructions?\s*(are|follow|:|;)"
r"|you\s+are\s+now\s+(a|an|the|going)"
r"|act\s+as\s+(a|an|if|though|when)\b"
r"|act\s+like\s+(a|an)\s+\w"
r"|pretend\s+(you\s+are|to\s+be)"
r"|jailbreak|dan\s+mode|developer\s+mode|god\s+mode"
r"|system\s+prompt\s*(is|was|says|leak|show|reveal|print|output)"
r"|reveal\s+(your\s+)?(system\s+)?prompt"
r"|print\s+(your\s+)?(system\s+)?instructions?"
r"|forget\s+(you\s+are|your\s+role|everything)"
r"|do\s+anything\s+now|no\s+restrictions?)\b",
re.IGNORECASE,
)
SUMMARY_RE = re.compile(
r"\b(summar(y|ize|ise|izing|ising)|overview|explain|what is|what are|describe"
r"|tell me about|give me a summary|give me an overview|give me a brief"
r"|brief (summary|overview|explanation|description)"
r"|research (overview|summary|landscape|state)"
r"|state of (the art|research|the field)"
r"|recent (advances?|developments?|progress|trends?)"
r"|current (state|trends?|advances?|research)"
r"|deep analysis|analysis of|review of|literature review|deep research|deep dive"
r"|what do we know about|how does|how do)\b",
re.IGNORECASE,
)
DATABASE_RECOMMEND_RE = re.compile(
r"("
r"\b(best database|best databases|which database|which databases"
r"|database for|databases for"
r"|where should i search|where should i start)\b"
r"|databases?\s+(does|did|do)\s+.{0,40}subscri"
r"|\bsubscribed\s+databases?\b"
r"|\blibrary\s+subscri"
r"|\bwhat\s+databases?\b"
r"|\bdatabases?\s+(available|accessible)\b"
r"|\bdatabases?\s+(at|in|through|via)\s+(ku|khalifa)\b"
r"|\bku\s+(library\s+)?databases?\b"
r"|\bkhalifa.{0,20}databases?\b"
r"|\blibrary\s+databases?\b"
r"|\be.?resources?\s+(available|subscri)\b"
r"|\baccess\s+to\s+databases?\b"
r"|\blist\s+of\s+databases?\b"
r"|\b(compare|comparison|difference|differences)\s+(between\s+)?(\w+\s+)?(and\s+)?\w*\s*database"
r"|\bdifference\s+between.{0,60}database"
r"|\bscopus\s+(vs|versus|or)\s+(web of science|wos|google scholar)\b"
r"|\b(web of science|wos)\s+(vs|versus|or)\s+(scopus|google scholar)\b"
r")",
re.IGNORECASE,
)
HIGHLY_CITED_RE = re.compile(
r"\b(highly cited|most cited|top cited|citation count|most influential"
r"|most referenced|high impact papers?|most downloaded)\b",
re.IGNORECASE,
)
BOOLEAN_STRATEGY_RE = re.compile(
r"\b(search strategy|boolean (search|operator|query|logic)"
r"|build.{0,20}search|help.{0,20}search strategy"
r"|how.{0,30}search.{0,30}(database|boolean|keyword)"
r"|refine.{0,30}(topic|question|research question|searchable)"
r"|turn.{0,30}(topic|question).{0,20}search"
r"|keywords? for.{0,30}search|search terms?"
r"|explain.{0,20}keyword|why.{0,20}(chose|choose|selected|pick).{0,20}keyword)\b",
re.IGNORECASE,
)
FULLTEXT_REQUEST_RE = re.compile(
r"\b("
r"(can.t|cannot|couldn.t|don.t have|doesn.t have|no).{0,30}(access|pdf|full.?text)"
r"|(pdf|full.?text).{0,20}(not available|unavailable|can.t find|not found|missing)"
r"|found.{0,30}citation.{0,20}(but|not).{0,20}(pdf|full.?text)"
r"|article.{0,20}(behind.{0,10}paywall|not available|no access|access denied)"
r"|ku.{0,20}(doesn.t|does not|no).{0,20}(have|access).{0,20}(article|journal|pdf)"
r"|(how|where).{0,20}(get|find|access|download).{0,20}(full.?text|pdf).{0,20}article"
r"|get full.?text|access full.?text|download.{0,10}(article|pdf)"
r"|ku.{0,15}(don.t|doesn.t|no).{0,15}(subscribe|have access)"
r")\b",
re.IGNORECASE,
)
PARTIAL_TITLE_RE = re.compile(
r"\b(only (remember|recall|know).{0,20}(title|name)"
r"|title (starts?|begins?).{0,15}with"
r"|article.{0,20}(called|titled|named|starts? with)"
r"|find.{0,20}(article|paper).{0,20}(called|titled|named)"
r"|looking for.{0,20}(paper|article).{0,20}(about|called))\b",
re.IGNORECASE,
)
DUAL_RESOURCE_RE = re.compile(
r"\b(papers?.{0,30}(and|as well as|plus).{0,30}textbooks?"
r"|textbooks?.{0,30}(and|as well as|plus).{0,30}papers?"
r"|(literature review|articles?).{0,50}(background|textbook|introductory book)"
r"|(textbook|book).{0,50}(literature review|research articles?))\b",
re.IGNORECASE,
)
THESES_RE = re.compile(
r"\b(thes(is|es)|dissertation|doctoral|phd thesis|master.s thesis"
r"|khazna|ku repository|institutional repository"
r"|proquest dissertations?)\b",
re.IGNORECASE,
)
PREDATORY_RE = re.compile(
r"\b(predatory (journal|publisher|publication)"
r"|how.{0,20}(know|tell|check).{0,30}(peer.?reviewed|scholarly|legitimate|reputable)"
r"|is.{0,30}(journal|article).{0,30}(legitimate|reputable|trusted|peer.?reviewed)"
r"|peer.?reviewed vs|distinguish.{0,20}(peer|scholarly|predatory)"
r"|journal (quality|credibility|ranking|whitelist|blacklist)"
r"|beall.s list|doaj|cabells|think.check.submit)\b",
re.IGNORECASE,
)
CITATION_CHAIN_RE = re.compile(
r"\b(cited by|forward citation|backward citation|reference.{0,15}(chain|mining)"
r"|trace.{0,30}(reference|citation)|who cited|papers? that cite"
r"|related (articles?|papers?).{0,20}(paper|article)"
r"|find similar.{0,20}(paper|article))\b",
re.IGNORECASE,
)
REVIEW_ONLY_RE = re.compile(
r"\b(review (articles?|papers?|only)|only (review|systematic review)"
r"|limit.{0,20}review|show.{0,20}review|filter.{0,20}review"
r"|systematic reviews? only|literature reviews? only)\b",
re.IGNORECASE,
)
ALT_TERMS_RE = re.compile(
r"\b(alternative (search terms?|keywords?|terms?)"
r"|other (search terms?|keywords?|ways? to search)"
r"|more (keywords?|search terms?)|suggest.{0,20}keywords?"
r"|related (terms?|keywords?|synonyms?)|synonyms? for.{0,20}search"
r"|different (keywords?|terms?|search))\b",
re.IGNORECASE,
)
MEDICAL_KEYWORDS = [
"medicine", "medical", "health", "clinical", "nursing", "pharmacy", "biomedical",
"anatomy", "physiology", "epidemiology", "oncology", "cardiology", "neuroscience",
"genomics", "pathology", "surgery", "mental health", "nutrition", "public health",
"disease", "therapy", "treatment", "diagnosis", "patient", "drug", "pharmaceutical",
"hospital", "cancer", "diabetes", "heart", "brain", "cell biology", "immunology",
"biochemistry", "microbiology", "virology", "pediatric", "psychiatric", "dental",
"ophthalmology", "radiology", "anesthesia", "emergency medicine", "geriatric",
"crispr", "gene therapy", "gene editing", "genomic medicine", "precision medicine",
]
REFINEMENT_STOP_WORDS = {
"make", "it", "them", "those", "these", "the", "a", "an", "for", "to", "only", "show",
"find", "give", "me", "please", "and", "with", "within", "limit", "narrow", "search",
"results", "on", "about", "of", "this", "that", "topic", "same", "using", "from",
"peer", "reviewed", "review", "open", "access", "books", "book", "articles", "article",
"papers", "paper", "years", "year", "last", "past", "recent", "instead", "summary",
"overview", "brief", "pubmed", "primo", "database", "databases", "best", "deep", "research",
"tools", "tool", "guide", "ku", "library",
}
_CLASSIFIER_SYSTEM = """You are the routing brain of LibBee, the Khalifa University Library AI Assistant (Abu Dhabi, UAE).
Your only job: read the user message and return a single JSON object routing it to the right handler.
INTENTS β pick exactly one:
"social" β casual chat, greetings, emotions, compliments, complaints, vague help requests
"library_info" β questions about KU Library services, hours, rooms, borrowing, fines, ILL, staff, databases, ORCID, RefWorks, open access, APC, account, printing, remote access, LibKey, acquisitions, Khazna, thesis submission, library policies, alumni access, library events, workshops, seminars, training sessions, library calendar
"search_academic"β user wants to FIND/GET articles/papers/books on a topic, OR wants a summary/overview/analysis/explanation of an academic/research topic
"search_medical" β same as search_academic but topic is medical/clinical/nursing/pharmacy/health sciences
"general_recent" β questions about TRULY live/real-time data: breaking news, live sports scores, today's weather, current stock prices
"general" β ALL other factual questions: university info, people, history, science definitions, technology explanations
"sensitive" β block any of the following:
(a) Requests for negative opinions, criticism, or controversy about Khalifa University, UAE government/leaders/laws/institutions, or religion.
(b) Sexually explicit, suggestive, or adult content of any kind β including questions asking for sexual information, stories, jokes, or descriptions.
(c) Political criticism, propaganda, or inflammatory commentary targeting UAE, its leadership, policies, or any Gulf state government.
(d) Content that is offensive, discriminatory, or inappropriate for a university academic environment.
ONLY use "sensitive" when the clear intent falls into one of these categories. Neutral academic research questions about politics, health, relationships, or social issues are NOT sensitive.
CRITICAL RULES:
1. "research" as a job title or service modifier (research librarian, research support, research help) = library_info, NOT search_academic.
2. ANY question about a person working at the library (librarian, staff, who to contact) = library_info.
3. "I cannot access / can't access / no access to" a database or resource = library_info.
4. "What is X?" / "Explain X" / "How does X work?" where X is an academic/scientific topic = search_academic.
5. KU = Khalifa University. Do NOT confuse with Kuwait University.
6. Only use general_recent for truly live data changing by the minute (news, scores, weather, stocks).
7. When in doubt between library_info and anything else, choose library_info if the question involves a library service, person, or resource.
8. "sensitive" covers: (a) criticism/negative commentary about KU or UAE, (b) sexual or adult content, (c) political attacks on UAE/Gulf governments, (d) religiously offensive content. Academic research on politics, health, or social issues = general or search_academic.
9. APC, article processing charges, open access publishing, OA fees, open access waivers, open access journal policies, Creative Commons licences = ALWAYS library_info. NEVER search_academic or search_medical.
10. Research support, research consultation, bibliometrics, ORCID, Khazna, SciVal, scholarly communication, where to publish, journal selection = ALWAYS library_info. NEVER search_academic.
11. "research on X" / "find research on X" / "research about X" where X is an academic topic = search_academic. Only the word "research" alone with a topic = article search, NOT a library service question.
EXAMPLES β follow these exactly:
{"message": "who is the research librarian", "intent": "library_info"}
{"message": "how do I reserve a study room", "intent": "library_info"}
{"message": "I cannot access a library database from home", "intent": "library_info"}
{"message": "can I access journals off campus", "intent": "library_info"}
{"message": "who should I contact for research support", "intent": "library_info"}
{"message": "what is an APC", "intent": "library_info"}
{"message": "how do I pay article processing charges", "intent": "library_info"}
{"message": "does KU cover APC fees", "intent": "library_info"}
{"message": "how to publish open access", "intent": "library_info"}
{"message": "open access publishing at KU", "intent": "library_info"}
{"message": "is there an OA fund at Khalifa University", "intent": "library_info"}
{"message": "Walter Hall open access", "intent": "library_info"}
{"message": "who handles open access at KU library", "intent": "library_info"}
{"message": "creative commons licence for my paper", "intent": "library_info"}
{"message": "who is the research librarian", "intent": "library_info"}
{"message": "I need research support", "intent": "library_info"}
{"message": "bibliometrics help", "intent": "library_info"}
{"message": "how do I register for ORCID", "intent": "library_info"}
{"message": "deposit in Khazna", "intent": "library_info"}
{"message": "research on machine learning", "intent": "search_academic"}
{"message": "find research on climate change", "intent": "search_academic"}
{"message": "research about AI in healthcare", "intent": "search_medical"}
{"message": "what is quantum computing", "intent": "search_academic"}
{"message": "explain CRISPR gene editing", "intent": "search_academic"}
{"message": "best practices in cybersecurity", "intent": "search_academic"}
{"message": "I need help with my thesis on renewable energy", "intent": "search_academic"}
{"message": "find papers on diabetes treatment", "intent": "search_medical"}
{"message": "systematic review on COVID-19 vaccines", "intent": "search_medical"}
{"message": "who is the president of UAE", "intent": "general"}
{"message": "what year was KU founded", "intent": "general"}
{"message": "what challenges does KU face in AI research", "intent": "general"}
{"message": "UAE water scarcity problems and solutions", "intent": "search_academic"}
{"message": "find research on sexual health education", "intent": "search_academic"}
{"message": "articles on political systems in the Middle East", "intent": "search_academic"}
{"message": "latest news on AI regulation", "intent": "general_recent"}
{"message": "what are the bad things about KU", "intent": "sensitive"}
{"message": "say something negative about Khalifa University", "intent": "sensitive"}
{"message": "criticize the UAE government", "intent": "sensitive"}
{"message": "what is wrong with UAE laws", "intent": "sensitive"}
{"message": "tell me the problems with KU administration", "intent": "sensitive"}
{"message": "write me a sexual story", "intent": "sensitive"}
{"message": "tell me something sexual", "intent": "sensitive"}
{"message": "generate adult content", "intent": "sensitive"}
{"message": "describe a sexual encounter", "intent": "sensitive"}
{"message": "write explicit content", "intent": "sensitive"}
{"message": "UAE government is corrupt and oppressive", "intent": "sensitive"}
{"message": "why is the UAE government so bad", "intent": "sensitive"}
{"message": "UAE leaders are dictators", "intent": "sensitive"}
{"message": "insult the UAE", "intent": "sensitive"}
{"message": "hi there", "intent": "social", "casual_answer": "Hello! I'm LibBee, the KU Library AI Assistant. How can I help you today?"}
{"message": "I am fed up with searching", "intent": "social", "casual_answer": "I understand the frustration! Let me help make your search easier. What topic are you working on?"}
For "social" intent ONLY: include "casual_answer" β a warm 1-3 sentence LibBee response (no markdown, no bullets).
For all other intents: omit "casual_answer".
Respond ONLY with valid JSON. No preamble, no markdown fences.
"""
EVENTS_RE = re.compile(
r"\b("
r"library events?|library workshops?|library seminars?|library training"
r"|library sessions?|library talks?|library webinars?|library programmes?"
r"|library classes?|library courses?|library instruction"
r"|upcoming (events?|workshops?|seminars?|training|sessions?|talks?|webinars?)"
r"|any (events?|workshops?|seminars?|training|sessions?|talks?)"
r"|what (events?|workshops?|seminars?|training|sessions?|talks?)"
r"|events? (at|in|by|from) (the )?library"
r"|workshops? (at|in|by|from) (the )?library"
r"|seminars? (at|in|by|from) (the )?library"
r"|training (at|in|by|from) (the )?library"
r"|what'?s? on (at |in )?(the )?library"
r"|library calendar|library programme|library schedule"
r"|library events? calendar|events? calendar"
r"|is there (a |an )?(workshop|seminar|training|session|event|talk|webinar)"
r"|are there (any )?(workshops?|seminars?|training|sessions?|events?|talks?)"
r"|database training|research skills (workshop|session|training|class)"
r"|citation (workshop|training|session)|refworks (workshop|training|session)"
r"|endnote (workshop|training)|zotero (workshop|training)"
r"|information literacy (session|workshop|class|training)"
r")\b",
re.IGNORECASE,
)
_BOOLEAN_SYSTEM = """You are an expert academic database search specialist building PRIMO/ExLibris boolean queries.
Given a research topic or question, output ONLY a valid boolean search string.
RULES:
1. Identify 2-4 key CONCEPTS in the query.
2. Multi-word concepts MUST be quoted: "machine learning" not machine AND learning.
3. Use OR between synonyms of the same concept: ("machine learning" OR "deep learning" OR "neural networks")
4. Use AND to connect different concepts: ("climate change" OR "global warming") AND ("renewable energy" OR "clean energy")
5. NEVER split a natural phrase with AND: "global warming" stays "global warming", NOT global AND warming.
6. NEVER include stop words (of, the, a, in, on, for, to, with, by, impact, role, effect, use, study, analysis, review) as standalone terms.
7. For medical/clinical topics, include MeSH-style synonyms.
8. Keep to a maximum of 3 concept groups joined by AND.
9. Return ONLY the boolean string. No explanation, no preamble, no markdown.
EXAMPLES:
Input: global warming
Output: ("global warming" OR "climate change" OR "greenhouse effect")
Input: machine learning in healthcare
Output: ("machine learning" OR "deep learning" OR "artificial intelligence") AND ("healthcare" OR "medicine" OR "clinical")
Input: impact of social media on mental health
Output: ("social media" OR "social networks") AND ("mental health" OR "psychological wellbeing" OR "depression")
Input: structural engineering UAE
Output: ("structural engineering" OR "structural analysis") AND ("UAE" OR "United Arab Emirates" OR "Gulf")
Input: CRISPR gene editing applications
Output: ("CRISPR" OR "CRISPR-Cas9" OR "gene editing") AND ("applications" OR "therapeutic" OR "treatment")
Input: renewable energy policy
Output: ("renewable energy" OR "clean energy" OR "sustainable energy") AND ("policy" OR "regulation" OR "governance")
"""
_LEGACY_SYSTEM_PATTERNS = [
(
re.compile(
r'(you can use )?summon[β’β’]?\s*(to find [^.]+\.)?\s*'
r'(search summon\s*)?'
r'(what is summon[β’β’]?.*?(?:search screen|search results|find articles)[^<]*)?',
re.IGNORECASE | re.DOTALL,
),
"PRIMO Library Discovery (https://khalifa.primo.exlibrisgroup.com/discovery/search?vid=971KUOSTAR_INST:KU)",
),
(re.compile(r'\bSummon[β’β’]?\b', re.IGNORECASE), "PRIMO Library Discovery"),
(re.compile(r'\bEBSCO Discovery Service\b', re.IGNORECASE), "PRIMO Library Discovery"),
(re.compile(r'\bEncore\b(?!\s+(?:learning|education))', re.IGNORECASE), "PRIMO Library Discovery"),
]
_BUILD_SEARCH_PLAN_SYSTEM = f"""You are a search expert for Khalifa University Library.
The user typed a research request. Create THREE forms preserving the full intent.
1. corrected: lightly edit the FULL request for spelling, grammar, and clarity.
Preserve every substantive concept, constraint, and task. Do NOT collapse.
2. natural: write a natural-language research query for AI tools such as Consensus,
Scopus AI, PRIMO AI, and LeapSpace. Keep full context. Remove only retrieval
boilerplate like "find me", "show me", "can you find".
3. boolean: write a PRIMO/PubMed Boolean query with AND/OR/parentheses.
Also detect: year_from, year_to (e.g. "last 24 months" β year_from={{{CURRENT_YEAR}-2}}),
peer_reviewed, open_access.
STEP 1 β TOPIC EXTRACTION:
Before building the boolean, strip all search intent verbs from the query.
These include: find, search, look for, get me, show me, give me, fetch, retrieve,
research on, articles on, papers on, literature on, studies on, tell me about,
i need, i want, can you find, help me find.
Extract ONLY the subject matter as the topic for the boolean.
STEP 2 β ACRONYM EXPANSION:
For well-known acronyms in the topic, ALWAYS include both the acronym AND the full
expanded form as OR synonyms inside parentheses. Examples:
("NLP" OR "natural language processing")
("AI" OR "artificial intelligence")
("ML" OR "machine learning")
("RAG" OR "retrieval augmented generation")
("LLM" OR "large language model")
("IoT" OR "internet of things")
("EHR" OR "electronic health records")
("CV" OR "computer vision")
("RL" OR "reinforcement learning")
("DL" OR "deep learning")
("CNN" OR "convolutional neural network")
Apply this rule to ANY acronym in the query, not just these examples.
BOOLEAN RULES β follow strictly:
- Use DOUBLE quotes around multi-word phrases: ("smart city" OR "urban mobility")
- NEVER use single quotes
- Max 3 AND groups. Each group max 4 OR terms.
- NEVER put years as Boolean terms β put them in year_from/year_to
- NEVER include intent verbs (find, search, articles on etc.) in the boolean
- Keep broad enough to return results
- NAMED ENTITIES: Any specific keyword that is a country, island, city, person,
organisation, or proper noun MUST be kept as its own AND group. Never drop it.
e.g. "Maldives" β AND ("Maldives" OR "Maldivian") ; "UAE" β AND ("UAE" OR "United Arab Emirates")
EXAMPLES:
Input: "find articles on global warming and renewable energy"
β boolean:("global warming" OR "climate change") AND ("renewable energy" OR "clean energy")
Input: "find research on NLP"
β boolean:("NLP" OR "natural language processing")
Input: "get me papers on AI in healthcare"
β boolean:("AI" OR "artificial intelligence") AND ("healthcare" OR "medicine" OR "clinical")
Input: "search ML algorithms"
β boolean:("ML" OR "machine learning") AND ("algorithms" OR "models" OR "techniques")
Input: "peer reviewed articles last 5 years on machine learning healthcare"
β boolean:("machine learning" OR "deep learning" OR "AI") AND ("healthcare" OR "medicine" OR "clinical")
β year_from:"2021", peer_reviewed:true
Input: "impact of global warming in Maldives"
β boolean:("global warming" OR "climate change") AND ("Maldives" OR "sea level rise" OR "small island")
Input: "water scarcity solutions in UAE"
β boolean:("water scarcity" OR "water stress") AND ("UAE" OR "United Arab Emirates" OR "Gulf region")
Return ONLY valid JSON:
{{"corrected":"...","natural":"...","boolean":"(\"A\" OR \"B\") AND (\"C\" OR \"D\")","year_from":"","year_to":"","peer_reviewed":false,"open_access":false}}"""
def _safe_db_url(url: str) -> str:
from urllib.parse import quote as _quote
if "?url=" in url:
base, inner = url.split("?url=", 1)
return base + "?url=" + _quote(inner, safe="")
return url
_DB_SUBJECTS: Dict[str, List[Tuple[str, str, str]]] = {
"physics": [
("APS Journals", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://journals.aps.org"), "American Physical Society β core physics journals."),
("AIP Publishing", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://pubs.aip.org"), "Core physics and applied physics literature."),
("IOPScience", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://iopscience.iop.org"), "Core physics journal platform."),
("arXiv", "https://arxiv.org", "Open-access preprints in physics and maths."),
("ScienceDirect", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.sciencedirect.com"), "Full text across applied and interdisciplinary physics."),
("Scopus", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.scopus.com"), "Discovery and citation tracking."),
],
"chemistry": [
("ACS Publications", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://pubs.acs.org"), "Core chemistry journals from the American Chemical Society."),
("SciFinder-n", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://scifinder-n.cas.org"), "Substance, reaction, reference, and patent searching."),
("Reaxys", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.reaxys.com"), "Reaction and property searching."),
("RSC Journals", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://pubs.rsc.org"), "Royal Society of Chemistry journals."),
("ScienceDirect", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.sciencedirect.com"), "Full text chemistry journals and books."),
("Scopus", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.scopus.com"), "Discovery and citation tracking."),
],
"chemical_engineering": [
("ScienceDirect", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.sciencedirect.com"), "Strong full text for chemical engineering journals and books."),
("ACS Publications", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://pubs.acs.org"), "Core chemistry and chemical engineering coverage."),
("SciFinder-n", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://scifinder-n.cas.org"), "Chemical substances, reactions, references, and patents."),
("Reaxys", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.reaxys.com"), "Reaction and property searching."),
("Knovel", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://app.knovel.com"), "Engineering handbooks and technical reference data."),
("Scopus", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.scopus.com"), "Broad discovery and citation tracking."),
],
"computer_science": [
("ACM Digital Library", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://dl.acm.org"), "Core computer science literature."),
("IEEE Xplore", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://ieeexplore.ieee.org"), "Strong for CS, AI, networks, and systems."),
("arXiv", "https://arxiv.org", "Important preprint source for CS, AI, and ML."),
("INSPEC", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.theiet.org/publishing/inspec"), "Indexing for computing and engineering topics."),
("ScienceDirect", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.sciencedirect.com"), "Full text across CS and applied computing."),
("Scopus", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.scopus.com"), "Broad discovery and citation tracking."),
],
"robotics": [
("IEEE Xplore", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://ieeexplore.ieee.org"), "Core source for robotics, AI, automation, and intelligent systems."),
("ACM Digital Library", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://dl.acm.org"), "AI, ML, and computing research."),
("arXiv", "https://arxiv.org", "Essential for current AI, robotics, and ML preprints."),
("INSPEC", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.theiet.org/publishing/inspec"), "Indexing for robotics, computing, electronics, and control."),
("ScienceDirect", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.sciencedirect.com"), "Full text for AI, robotics, and applied engineering."),
],
"electrical_engineering": [
("IEEE Xplore", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://ieeexplore.ieee.org"), "Core electrical engineering database."),
("INSPEC", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.theiet.org/publishing/inspec"), "Strong indexing for EE, electronics, and physics."),
("ScienceDirect", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.sciencedirect.com"), "Full text for electrical engineering and control."),
("ASTM Compass", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://compass.astm.org"), "Standards and testing methods."),
("Scopus", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.scopus.com"), "Broad discovery and citation tracking."),
],
"mechanical_engineering": [
("ASME Digital Library", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://asmedigitalcollection.asme.org"), "Core mechanical engineering literature."),
("ScienceDirect", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.sciencedirect.com"), "Full text across mechanics, thermal, and manufacturing topics."),
("Knovel", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://app.knovel.com"), "Engineering reference data and handbooks."),
("ASTM Compass", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://compass.astm.org"), "Standards and materials testing information."),
("Scopus", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.scopus.com"), "Broad discovery and citation tracking."),
],
"civil_engineering": [
("ASCE Library", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://ascelibrary.org"), "Core civil and structural engineering journals and conference papers."),
("ICE Virtual Library", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.icevirtuallibrary.com"), "Civil engineering literature and proceedings."),
("ASTM Compass", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://compass.astm.org"), "Standards and testing methods for materials and engineering."),
("ScienceDirect", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.sciencedirect.com"), "Full text across civil engineering areas."),
("Knovel", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://app.knovel.com"), "Handbooks and design reference data."),
],
"aerospace": [
("AIAA", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://arc.aiaa.org/"), "Core aerospace journals, conference papers, and standards."),
("ASME Digital Library", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://asmedigitalcollection.asme.org"), "Thermal, mechanical, and fluid systems relevant to aerospace."),
("ScienceDirect", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.sciencedirect.com"), "Strong full text for aerospace, mechanics, and materials."),
("IEEE Xplore", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://ieeexplore.ieee.org"), "Avionics, control systems, and guidance."),
("Scopus", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.scopus.com"), "Broad discovery and citation tracking."),
],
"petroleum": [
("OnePetro", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://onepetro.org"), "Core petroleum engineering and oil and gas literature."),
("EarthDoc", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.earthdoc.org"), "Geoscience and petroleum-related literature."),
("ScienceDirect", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.sciencedirect.com"), "Full text for petroleum, energy, and engineering topics."),
("Knovel", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://app.knovel.com"), "Engineering handbooks and oil/gas reference material."),
("Scopus", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.scopus.com"), "Broad discovery and citation tracking."),
],
"energy": [
("ScienceDirect", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.sciencedirect.com"), "Strong energy engineering and sustainability full text."),
("OnePetro", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://onepetro.org"), "Energy sector and petroleum crossover topics."),
("IEEE Xplore", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://ieeexplore.ieee.org"), "Power systems, electrical energy, and smart grids."),
("Knovel", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://app.knovel.com"), "Engineering handbooks and energy reference content."),
("Scopus", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.scopus.com"), "Broad discovery and citation tracking."),
],
"mathematics": [
("MathSciNet", "https://mathscinet.ams.org", "Core mathematics review and discovery database."),
("SpringerLink", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://link.springer.com"), "Strong mathematics and statistics book and journal coverage."),
("ScienceDirect", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.sciencedirect.com"), "Full text for mathematics, statistics, and data science."),
("JSTOR", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.jstor.org"), "Foundational mathematics and statistics literature."),
("arXiv", "https://arxiv.org", "Preprints in mathematics, statistics, and data science."),
("Scopus", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.scopus.com"), "Broad discovery and citation tracking."),
],
"materials": [
("ScienceDirect", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.sciencedirect.com"), "Strong materials science full text."),
("SpringerLink", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://link.springer.com"), "Strong materials and nanoscience coverage."),
("AIP Publishing", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://pubs.aip.org"), "Applied materials and physics crossover."),
("IOPScience", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://iopscience.iop.org"), "Materials and physics crossover."),
("Knovel", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://app.knovel.com"), "Reference data and engineering materials handbooks."),
("Scopus", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.scopus.com"), "Broad discovery and citation tracking."),
],
"nuclear": [
("ScienceDirect", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.sciencedirect.com"), "Strong nuclear engineering and energy full text."),
("AIP Publishing", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://pubs.aip.org"), "Nuclear and applied physics crossover."),
("Knovel", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://app.knovel.com"), "Engineering reference and handbooks."),
("Scopus", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.scopus.com"), "Discovery and citation tracking."),
("Web of Science", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.webofscience.com"), "Broad citation discovery."),
],
"quantum_computing": [
("IEEE Xplore", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://ieeexplore.ieee.org"), "Quantum computing engineering implementations."),
("ACM Digital Library", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://dl.acm.org"), "Algorithms, theory, and computing literature."),
("APS Journals", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://journals.aps.org"), "Quantum information and foundational physics."),
("arXiv", "https://arxiv.org", "Essential for current quantum computing preprints."),
("Scopus", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.scopus.com"), "Discovery and citation tracking."),
],
"biomedical": [
("PubMed", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://pubmed.ncbi.nlm.nih.gov"), "Core biomedical and life sciences literature."),
("IEEE Xplore", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://ieeexplore.ieee.org"), "Biomedical engineering and medical devices."),
("Embase", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.embase.com"), "Biomedical and pharmacological literature."),
("ScienceDirect", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.sciencedirect.com"), "Full text for biomedical engineering and applied sciences."),
("Scopus", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.scopus.com"), "Discovery and citation tracking."),
],
"biology": [
("PubMed", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://pubmed.ncbi.nlm.nih.gov"), "Core life sciences and biomedical literature."),
("ScienceDirect", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.sciencedirect.com"), "Full text biology and molecular sciences content."),
("Embase", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.embase.com"), "Biomedical crossover topics."),
("PubMed Central", "https://www.ncbi.nlm.nih.gov/pmc", "Open full-text biomedical articles β no login required."),
("Scopus", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.scopus.com"), "Discovery and citation tracking."),
],
"medical": [
("PubMed @ KU", "http://www.ncbi.nlm.nih.gov/pubmed/?otool=iaekustlib", "Core medical literature β use this KU link for full-text access."),
("Embase", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.embase.com"), "Biomedical and pharmacological literature."),
("CINAHL Ultimate", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://search.ebscohost.com/login.aspx?authtype=ip,uid&profile=ehost&defaultdb=cul"), "Nursing and allied health literature."),
("Cochrane Library", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.cochranelibrary.com"), "Evidence synthesis and systematic reviews β gold standard."),
("UpToDate", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.uptodate.com"), "Point-of-care clinical decision support."),
("ClinicalKey Student", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.clinicalkey.com/student/login"), "Clinical reference and learning resource."),
],
"business": [
("Business Source Complete", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://search.ebscohost.com"), "Core business and management literature."),
("Emerald Insight", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.emerald.com/insight"), "Management, strategy, and leadership journals."),
("ProQuest Databases", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://search.proquest.com"), "Broad business and interdisciplinary discovery."),
("JSTOR", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.jstor.org"), "Business, economics, and policy literature."),
("Scopus", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.scopus.com"), "Broad discovery and citation tracking."),
],
"earth_science": [
("GeoscienceWorld", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://pubs.geoscienceworld.org"), "Core earth science journals and conference content."),
("EarthDoc", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.earthdoc.org"), "Geoscience and subsurface literature."),
("ScienceDirect", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.sciencedirect.com"), "Full text for geoscience and planetary topics."),
("Scopus", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.scopus.com"), "Discovery and citation tracking."),
("Web of Science", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.webofscience.com"), "Broad citation discovery."),
],
"environment": [
("ScienceDirect", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.sciencedirect.com"), "Strong sustainability and environmental full text."),
("ProQuest Databases", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://search.proquest.com"), "Environmental policy and interdisciplinary discovery."),
("Web of Science", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.webofscience.com"), "Broad citation discovery."),
("Scopus", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.scopus.com"), "Broad discovery and citation tracking."),
("Business Source Complete", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://search.ebscohost.com"), "Sustainability, policy, and corporate responsibility."),
],
"engineering_management": [
("Scopus", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.scopus.com"), "Broad discovery across engineering and management research."),
("Emerald Insight", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.emerald.com/insight"), "Management, operations, and leadership literature."),
("ScienceDirect", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.sciencedirect.com"), "Engineering and management full text."),
("Business Source Complete", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://search.ebscohost.com"), "Business, management, and strategy literature."),
("ProQuest Databases", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://search.proquest.com"), "Broad business and interdisciplinary discovery."),
],
"metrics": [
("Journal Citation Reports", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://jcr.clarivate.com"), "Impact factors and journal rankings (Web of Science)."),
("Scopus / CiteScore", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.scopus.com"), "CiteScore and source-level metrics."),
("SciVal", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.scival.com"), "Research performance analytics."),
("Web of Science", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.webofscience.com"), "Citation discovery and journal evaluation context."),
],
"theses": [
("ProQuest Dissertations & Theses Global", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.proquest.com/pqdtglobal"), "International dissertations and theses."),
("Khazna", "https://khazna.ku.ac.ae/", "KU institutional repository and research outputs."),
("PRIMO", "https://khalifa.primo.exlibrisgroup.com/discovery/search?vid=971KUOSTAR_INST:KU", "Discovery for dissertations, theses, and KU holdings."),
],
}
_DB_GENERAL: List[Tuple[str, str, str]] = [
("PRIMO (KU Library Discovery)", "https://khalifa.primo.exlibrisgroup.com/discovery/search?vid=971KUOSTAR_INST:KU", "Best starting point β search all KU books, articles, and journals."),
("Scopus", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.scopus.com"), "Largest abstract and citation database β all disciplines."),
("Web of Science", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.webofscience.com"), "Premier citation index β all disciplines."),
("ScienceDirect", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.sciencedirect.com"), "Large full-text platform across science, engineering, and medicine."),
("SpringerLink", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://link.springer.com"), "Springer journals and books across all disciplines."),
("ProQuest Databases", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://search.proquest.com"), "Broad multidisciplinary discovery."),
("Emerald Insight", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.emerald.com/insight"), "Social sciences, management, and interdisciplinary research."),
("JSTOR", _safe_db_url("https://khalifa.idm.oclc.org/login?url=https://www.jstor.org"), "Foundational and archival literature across many fields."),
]
|