Download src/agentcore/constants.py from nikeshn/LibBee: direct link, hf CLI and curl.
- Browser
- Download file 48.9 kB
-
https://huggingface.co/spaces/nikeshn/LibBee/resolve/main/src/agentcore/constants.py
- Command line
-
hf download hf://spaces/nikeshn/LibBee/src/agentcore/constants.py
-
curl -L -o constants.py https://huggingface.co/spaces/nikeshn/LibBee/resolve/main/src/agentcore/constants.py
48.9 kB
| """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?|text\s?books?|e[- ]?books?|books?|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?|text\s?books?|e[- ]?books?|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." | |
| ) | |
| FIXED_VERIFIED_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/", | |
| "mailto:libse@ku.ac.ae", | |
| ) | |
| _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: " + " | ".join(FIXED_VERIFIED_URLS) + ". " | |
| "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", "textbook", "textbooks", "ebook", "ebooks", | |
| "latest", "newest", "onwards", "onward", "published", "publication", | |
| } | |
| _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 a research librarian creating precise PRIMO Boolean queries. | |
| Return ONLY the Boolean string, without explanation or markdown. | |
| - Remove request framing and material words (books, textbooks, ebooks, articles). | |
| - Use AND between distinct concepts; preserve every substantive user concept. | |
| - Put multi-word phrases in double quotes. Preserve quoted titles and ISBNs exactly. | |
| - Use OR for genuinely equivalent spellings, synonyms, and unambiguous acronym | |
| expansions. Do not replace a specific topic with broader related disciplines. | |
| - Keep named places, people, organisations and other named entities in the query. | |
| - Keep publication-date instructions out of Boolean terms; they are filters. | |
| Preserve dates that are part of an exact title or a named subject. | |
| - Do not force extra concepts or synonyms when a single exact phrase is sufficient. | |
| Examples: | |
| Electrical Engineering β "Electrical Engineering" | |
| AI in healthcare β ("AI" OR "artificial intelligence") AND ("healthcare" OR "health care") | |
| machine learning in UAE β ("machine learning" OR "ML") AND ("UAE" OR "United Arab Emirates") | |
| "Introduction to Electrical Engineering" β "Introduction to Electrical Engineering" | |
| """ | |
| _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 peer_reviewed and open_access. Publication dates are parsed locally; | |
| do not add years to a Boolean query unless they are part of a named subject/title. | |
| 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. | |
| Remove material requests such as book, textbook, ebook, and article; these are filters. | |
| Preserve quoted titles and ISBN identifiers exactly; do not expand them into synonyms. | |
| Remove publication-date instructions (recent/latest, last N years, since/from a year, | |
| year ranges) from the subject; dates will be applied as separate filters. | |
| Return topic as a concise subject label with the same substantive concepts. | |
| STEP 2 β ACRONYM EXPANSION: | |
| For unambiguous well-known acronyms in the topic, 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") | |
| Do not guess ambiguous acronym expansions. Add only equivalent terms, not broader | |
| subjects or loosely related topics. Do not force synonyms when no useful equivalent exists. | |
| BOOLEAN RULES β follow strictly: | |
| - Use DOUBLE quotes around multi-word phrases: ("smart city" OR "smart cities") | |
| - NEVER use single quotes | |
| - Keep each group to at most 4 equivalent OR terms. Preserve every substantive user concept; | |
| do not drop concepts to meet an arbitrary group count. | |
| - Publication years are separate filters; preserve years that belong to quoted titles or named subjects | |
| - 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" AND "renewable 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 "health care") | |
| Input: "search ML algorithms" | |
| β boolean:("ML" OR "machine learning") AND ("algorithm" OR "algorithms") | |
| Input: "peer reviewed articles last 5 years on machine learning healthcare" | |
| β boolean:("machine learning" OR "ML") AND ("healthcare" OR "health care") | |
| β peer_reviewed:true | |
| Input: "impact of global warming in Maldives" | |
| β boolean:"global warming" AND ("Maldives" OR "Maldivian") | |
| Input: "water scarcity solutions in UAE" | |
| β boolean:"water scarcity" AND ("UAE" OR "United Arab Emirates") | |
| Return ONLY valid JSON: | |
| {{"corrected":"...","natural":"...","topic":"...","boolean":"(\"A\" OR \"B\") AND (\"C\" OR \"D\")","year_from":"","year_to":"","peer_reviewed":false,"open_access":false}}""" | |
| OPENATHENS_REDIRECT_BASE = "https://go.openathens.net/redirector/ku.ac.ae?url=" | |
| def _openathens_url(target: str) -> str: | |
| """Build a KU OpenAthens redirect without double-encoding its target.""" | |
| from urllib.parse import quote as _quote | |
| return OPENATHENS_REDIRECT_BASE + _quote(target, safe="") | |
| _DB_SUBJECTS: Dict[str, List[Tuple[str, str, str]]] = { | |
| "physics": [ | |
| ("APS Journals", _openathens_url("https://journals.aps.org"), "American Physical Society β core physics journals."), | |
| ("AIP Publishing", _openathens_url("https://pubs.aip.org"), "Core physics and applied physics literature."), | |
| ("IOPScience", _openathens_url("https://iopscience.iop.org"), "Core physics journal platform."), | |
| ("arXiv", "https://arxiv.org", "Open-access preprints in physics and maths."), | |
| ("ScienceDirect", _openathens_url("https://www.sciencedirect.com"), "Full text across applied and interdisciplinary physics."), | |
| ("Scopus", _openathens_url("https://www.scopus.com"), "Discovery and citation tracking."), | |
| ], | |
| "chemistry": [ | |
| ("ACS Publications", _openathens_url("https://pubs.acs.org"), "Core chemistry journals from the American Chemical Society."), | |
| ("SciFinder-n", _openathens_url("https://scifinder-n.cas.org"), "Substance, reaction, reference, and patent searching."), | |
| ("Reaxys", _openathens_url("https://www.reaxys.com"), "Reaction and property searching."), | |
| ("RSC Journals", _openathens_url("https://pubs.rsc.org"), "Royal Society of Chemistry journals."), | |
| ("ScienceDirect", _openathens_url("https://www.sciencedirect.com"), "Full text chemistry journals and books."), | |
| ("Scopus", _openathens_url("https://www.scopus.com"), "Discovery and citation tracking."), | |
| ], | |
| "chemical_engineering": [ | |
| ("ScienceDirect", _openathens_url("https://www.sciencedirect.com"), "Strong full text for chemical engineering journals and books."), | |
| ("ACS Publications", _openathens_url("https://pubs.acs.org"), "Core chemistry and chemical engineering coverage."), | |
| ("SciFinder-n", _openathens_url("https://scifinder-n.cas.org"), "Chemical substances, reactions, references, and patents."), | |
| ("Reaxys", _openathens_url("https://www.reaxys.com"), "Reaction and property searching."), | |
| ("Knovel", _openathens_url("https://app.knovel.com"), "Engineering handbooks and technical reference data."), | |
| ("Scopus", _openathens_url("https://www.scopus.com"), "Broad discovery and citation tracking."), | |
| ], | |
| "computer_science": [ | |
| ("ACM Digital Library", _openathens_url("https://dl.acm.org"), "Core computer science literature."), | |
| ("IEEE Xplore", _openathens_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", _openathens_url("https://www.theiet.org/publishing/inspec"), "Indexing for computing and engineering topics."), | |
| ("ScienceDirect", _openathens_url("https://www.sciencedirect.com"), "Full text across CS and applied computing."), | |
| ("Scopus", _openathens_url("https://www.scopus.com"), "Broad discovery and citation tracking."), | |
| ], | |
| "robotics": [ | |
| ("IEEE Xplore", _openathens_url("https://ieeexplore.ieee.org"), "Core source for robotics, AI, automation, and intelligent systems."), | |
| ("ACM Digital Library", _openathens_url("https://dl.acm.org"), "AI, ML, and computing research."), | |
| ("arXiv", "https://arxiv.org", "Essential for current AI, robotics, and ML preprints."), | |
| ("INSPEC", _openathens_url("https://www.theiet.org/publishing/inspec"), "Indexing for robotics, computing, electronics, and control."), | |
| ("ScienceDirect", _openathens_url("https://www.sciencedirect.com"), "Full text for AI, robotics, and applied engineering."), | |
| ], | |
| "electrical_engineering": [ | |
| ("IEEE Xplore", _openathens_url("https://ieeexplore.ieee.org"), "Core electrical engineering database."), | |
| ("INSPEC", _openathens_url("https://www.theiet.org/publishing/inspec"), "Strong indexing for EE, electronics, and physics."), | |
| ("ScienceDirect", _openathens_url("https://www.sciencedirect.com"), "Full text for electrical engineering and control."), | |
| ("ASTM Compass", _openathens_url("https://compass.astm.org"), "Standards and testing methods."), | |
| ("Scopus", _openathens_url("https://www.scopus.com"), "Broad discovery and citation tracking."), | |
| ], | |
| "mechanical_engineering": [ | |
| ("ASME Digital Library", _openathens_url("https://asmedigitalcollection.asme.org"), "Core mechanical engineering literature."), | |
| ("ScienceDirect", _openathens_url("https://www.sciencedirect.com"), "Full text across mechanics, thermal, and manufacturing topics."), | |
| ("Knovel", _openathens_url("https://app.knovel.com"), "Engineering reference data and handbooks."), | |
| ("ASTM Compass", _openathens_url("https://compass.astm.org"), "Standards and materials testing information."), | |
| ("Scopus", _openathens_url("https://www.scopus.com"), "Broad discovery and citation tracking."), | |
| ], | |
| "civil_engineering": [ | |
| ("ASCE Library", _openathens_url("https://ascelibrary.org"), "Core civil and structural engineering journals and conference papers."), | |
| ("ICE Virtual Library", _openathens_url("https://www.icevirtuallibrary.com"), "Civil engineering literature and proceedings."), | |
| ("ASTM Compass", _openathens_url("https://compass.astm.org"), "Standards and testing methods for materials and engineering."), | |
| ("ScienceDirect", _openathens_url("https://www.sciencedirect.com"), "Full text across civil engineering areas."), | |
| ("Knovel", _openathens_url("https://app.knovel.com"), "Handbooks and design reference data."), | |
| ], | |
| "aerospace": [ | |
| ("AIAA", _openathens_url("https://arc.aiaa.org/"), "Core aerospace journals, conference papers, and standards."), | |
| ("ASME Digital Library", _openathens_url("https://asmedigitalcollection.asme.org"), "Thermal, mechanical, and fluid systems relevant to aerospace."), | |
| ("ScienceDirect", _openathens_url("https://www.sciencedirect.com"), "Strong full text for aerospace, mechanics, and materials."), | |
| ("IEEE Xplore", _openathens_url("https://ieeexplore.ieee.org"), "Avionics, control systems, and guidance."), | |
| ("Scopus", _openathens_url("https://www.scopus.com"), "Broad discovery and citation tracking."), | |
| ], | |
| "petroleum": [ | |
| ("OnePetro", _openathens_url("https://onepetro.org"), "Core petroleum engineering and oil and gas literature."), | |
| ("EarthDoc", _openathens_url("https://www.earthdoc.org"), "Geoscience and petroleum-related literature."), | |
| ("ScienceDirect", _openathens_url("https://www.sciencedirect.com"), "Full text for petroleum, energy, and engineering topics."), | |
| ("Knovel", _openathens_url("https://app.knovel.com"), "Engineering handbooks and oil/gas reference material."), | |
| ("Scopus", _openathens_url("https://www.scopus.com"), "Broad discovery and citation tracking."), | |
| ], | |
| "energy": [ | |
| ("ScienceDirect", _openathens_url("https://www.sciencedirect.com"), "Strong energy engineering and sustainability full text."), | |
| ("OnePetro", _openathens_url("https://onepetro.org"), "Energy sector and petroleum crossover topics."), | |
| ("IEEE Xplore", _openathens_url("https://ieeexplore.ieee.org"), "Power systems, electrical energy, and smart grids."), | |
| ("Knovel", _openathens_url("https://app.knovel.com"), "Engineering handbooks and energy reference content."), | |
| ("Scopus", _openathens_url("https://www.scopus.com"), "Broad discovery and citation tracking."), | |
| ], | |
| "mathematics": [ | |
| ("MathSciNet", "https://mathscinet.ams.org", "Core mathematics review and discovery database."), | |
| ("SpringerLink", _openathens_url("https://link.springer.com"), "Strong mathematics and statistics book and journal coverage."), | |
| ("ScienceDirect", _openathens_url("https://www.sciencedirect.com"), "Full text for mathematics, statistics, and data science."), | |
| ("JSTOR", _openathens_url("https://www.jstor.org"), "Foundational mathematics and statistics literature."), | |
| ("arXiv", "https://arxiv.org", "Preprints in mathematics, statistics, and data science."), | |
| ("Scopus", _openathens_url("https://www.scopus.com"), "Broad discovery and citation tracking."), | |
| ], | |
| "materials": [ | |
| ("ScienceDirect", _openathens_url("https://www.sciencedirect.com"), "Strong materials science full text."), | |
| ("SpringerLink", _openathens_url("https://link.springer.com"), "Strong materials and nanoscience coverage."), | |
| ("AIP Publishing", _openathens_url("https://pubs.aip.org"), "Applied materials and physics crossover."), | |
| ("IOPScience", _openathens_url("https://iopscience.iop.org"), "Materials and physics crossover."), | |
| ("Knovel", _openathens_url("https://app.knovel.com"), "Reference data and engineering materials handbooks."), | |
| ("Scopus", _openathens_url("https://www.scopus.com"), "Broad discovery and citation tracking."), | |
| ], | |
| "nuclear": [ | |
| ("ScienceDirect", _openathens_url("https://www.sciencedirect.com"), "Strong nuclear engineering and energy full text."), | |
| ("AIP Publishing", _openathens_url("https://pubs.aip.org"), "Nuclear and applied physics crossover."), | |
| ("Knovel", _openathens_url("https://app.knovel.com"), "Engineering reference and handbooks."), | |
| ("Scopus", _openathens_url("https://www.scopus.com"), "Discovery and citation tracking."), | |
| ("Web of Science", _openathens_url("https://www.webofscience.com"), "Broad citation discovery."), | |
| ], | |
| "quantum_computing": [ | |
| ("IEEE Xplore", _openathens_url("https://ieeexplore.ieee.org"), "Quantum computing engineering implementations."), | |
| ("ACM Digital Library", _openathens_url("https://dl.acm.org"), "Algorithms, theory, and computing literature."), | |
| ("APS Journals", _openathens_url("https://journals.aps.org"), "Quantum information and foundational physics."), | |
| ("arXiv", "https://arxiv.org", "Essential for current quantum computing preprints."), | |
| ("Scopus", _openathens_url("https://www.scopus.com"), "Discovery and citation tracking."), | |
| ], | |
| "biomedical": [ | |
| ("PubMed", _openathens_url("https://pubmed.ncbi.nlm.nih.gov"), "Core biomedical and life sciences literature."), | |
| ("IEEE Xplore", _openathens_url("https://ieeexplore.ieee.org"), "Biomedical engineering and medical devices."), | |
| ("Embase", _openathens_url("https://www.embase.com"), "Biomedical and pharmacological literature."), | |
| ("ScienceDirect", _openathens_url("https://www.sciencedirect.com"), "Full text for biomedical engineering and applied sciences."), | |
| ("Scopus", _openathens_url("https://www.scopus.com"), "Discovery and citation tracking."), | |
| ], | |
| "biology": [ | |
| ("PubMed", _openathens_url("https://pubmed.ncbi.nlm.nih.gov"), "Core life sciences and biomedical literature."), | |
| ("ScienceDirect", _openathens_url("https://www.sciencedirect.com"), "Full text biology and molecular sciences content."), | |
| ("Embase", _openathens_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", _openathens_url("https://www.scopus.com"), "Discovery and citation tracking."), | |
| ], | |
| "medical": [ | |
| ("PubMed", "https://pubmed.ncbi.nlm.nih.gov/", "Core biomedical and life-sciences literature."), | |
| ("Embase", _openathens_url("https://www.embase.com"), "Biomedical and pharmacological literature."), | |
| ("CINAHL Ultimate", _openathens_url("https://search.ebscohost.com/login.aspx?authtype=ip,uid&profile=ehost&defaultdb=cul"), "Nursing and allied health literature."), | |
| ("Cochrane Library", _openathens_url("https://www.cochranelibrary.com"), "Evidence synthesis and systematic reviews β gold standard."), | |
| ("UpToDate", _openathens_url("https://www.uptodate.com"), "Point-of-care clinical decision support."), | |
| ("ClinicalKey Student", _openathens_url("https://www.clinicalkey.com/student/login"), "Clinical reference and learning resource."), | |
| ], | |
| "business": [ | |
| ("Business Source Complete", _openathens_url("https://search.ebscohost.com"), "Core business and management literature."), | |
| ("Emerald Insight", _openathens_url("https://www.emerald.com/insight"), "Management, strategy, and leadership journals."), | |
| ("ProQuest Databases", _openathens_url("https://search.proquest.com"), "Broad business and interdisciplinary discovery."), | |
| ("JSTOR", _openathens_url("https://www.jstor.org"), "Business, economics, and policy literature."), | |
| ("Scopus", _openathens_url("https://www.scopus.com"), "Broad discovery and citation tracking."), | |
| ], | |
| "earth_science": [ | |
| ("GeoscienceWorld", _openathens_url("https://pubs.geoscienceworld.org"), "Core earth science journals and conference content."), | |
| ("EarthDoc", _openathens_url("https://www.earthdoc.org"), "Geoscience and subsurface literature."), | |
| ("ScienceDirect", _openathens_url("https://www.sciencedirect.com"), "Full text for geoscience and planetary topics."), | |
| ("Scopus", _openathens_url("https://www.scopus.com"), "Discovery and citation tracking."), | |
| ("Web of Science", _openathens_url("https://www.webofscience.com"), "Broad citation discovery."), | |
| ], | |
| "environment": [ | |
| ("ScienceDirect", _openathens_url("https://www.sciencedirect.com"), "Strong sustainability and environmental full text."), | |
| ("ProQuest Databases", _openathens_url("https://search.proquest.com"), "Environmental policy and interdisciplinary discovery."), | |
| ("Web of Science", _openathens_url("https://www.webofscience.com"), "Broad citation discovery."), | |
| ("Scopus", _openathens_url("https://www.scopus.com"), "Broad discovery and citation tracking."), | |
| ("Business Source Complete", _openathens_url("https://search.ebscohost.com"), "Sustainability, policy, and corporate responsibility."), | |
| ], | |
| "engineering_management": [ | |
| ("Scopus", _openathens_url("https://www.scopus.com"), "Broad discovery across engineering and management research."), | |
| ("Emerald Insight", _openathens_url("https://www.emerald.com/insight"), "Management, operations, and leadership literature."), | |
| ("ScienceDirect", _openathens_url("https://www.sciencedirect.com"), "Engineering and management full text."), | |
| ("Business Source Complete", _openathens_url("https://search.ebscohost.com"), "Business, management, and strategy literature."), | |
| ("ProQuest Databases", _openathens_url("https://search.proquest.com"), "Broad business and interdisciplinary discovery."), | |
| ], | |
| "metrics": [ | |
| ("Journal Citation Reports", _openathens_url("https://jcr.clarivate.com"), "Impact factors and journal rankings (Web of Science)."), | |
| ("Scopus / CiteScore", _openathens_url("https://www.scopus.com"), "CiteScore and source-level metrics."), | |
| ("SciVal", _openathens_url("https://www.scival.com"), "Research performance analytics."), | |
| ("Web of Science", _openathens_url("https://www.webofscience.com"), "Citation discovery and journal evaluation context."), | |
| ], | |
| "theses": [ | |
| ("ProQuest Dissertations & Theses Global", _openathens_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", _openathens_url("https://www.scopus.com"), "Largest abstract and citation database β all disciplines."), | |
| ("Web of Science", _openathens_url("https://www.webofscience.com"), "Premier citation index β all disciplines."), | |
| ("ScienceDirect", _openathens_url("https://www.sciencedirect.com"), "Large full-text platform across science, engineering, and medicine."), | |
| ("SpringerLink", _openathens_url("https://link.springer.com"), "Springer journals and books across all disciplines."), | |
| ("ProQuest Databases", _openathens_url("https://search.proquest.com"), "Broad multidisciplinary discovery."), | |
| ("Emerald Insight", _openathens_url("https://www.emerald.com/insight"), "Social sciences, management, and interdisciplinary research."), | |
| ("JSTOR", _openathens_url("https://www.jstor.org"), "Foundational and archival literature across many fields."), | |
| ] | |