Update src/agentcore/intents_search.py
Browse files- src/agentcore/intents_search.py +13 -57
src/agentcore/intents_search.py
CHANGED
|
@@ -17,11 +17,7 @@ from pydantic import BaseModel, ConfigDict, Field
|
|
| 17 |
from src.config import get_settings, LIBBEE_VERSION
|
| 18 |
|
| 19 |
from src.agentcore.models import ClientStatePayload, SearchContextPayload
|
| 20 |
-
from src.agentcore.scholarly import
|
| 21 |
-
_openalex_search,
|
| 22 |
-
_semantic_scholar_search,
|
| 23 |
-
enrich_papers_with_oa,
|
| 24 |
-
)
|
| 25 |
from src.agentcore.constants import (
|
| 26 |
ALT_TERMS_RE,
|
| 27 |
CURRENT_YEAR,
|
|
@@ -582,55 +578,9 @@ async def _research_snapshot(context: SearchContextPayload, model: str) -> Tuple
|
|
| 582 |
f'Search PRIMO for: {_escape(topic)} β</a>'
|
| 583 |
)
|
| 584 |
|
| 585 |
-
#
|
| 586 |
-
papers
|
| 587 |
-
|
| 588 |
-
papers = await _openalex_search(topic, limit=6)
|
| 589 |
-
if not papers:
|
| 590 |
-
papers = await _semantic_scholar_search(topic, limit=6)
|
| 591 |
-
if papers:
|
| 592 |
-
papers = await enrich_papers_with_oa(papers, max_lookups=5)
|
| 593 |
-
except Exception as exc:
|
| 594 |
-
logger.warning(f"Evidence panel skipped for '{topic}': {exc}")
|
| 595 |
-
papers = []
|
| 596 |
-
|
| 597 |
-
if papers:
|
| 598 |
-
rows = ""
|
| 599 |
-
for paper in papers[:5]:
|
| 600 |
-
_t = _escape(str(paper.get("title") or "Untitled"))
|
| 601 |
-
_y = _escape(str(paper.get("year") or "n.d."))
|
| 602 |
-
_v = _escape(str(paper.get("venue") or ""))
|
| 603 |
-
_c = paper.get("cited_by_count")
|
| 604 |
-
_link = paper.get("link") or (f"https://doi.org/{paper['doi']}" if paper.get("doi") else "")
|
| 605 |
-
_oa = paper.get("oa_pdf_url") or ""
|
| 606 |
-
_bits = [b for b in (_y, _v) if b]
|
| 607 |
-
if isinstance(_c, int) and _c > 0:
|
| 608 |
-
_bits.append(f"{_c:,} citations")
|
| 609 |
-
_meta = " Β· ".join(_bits)
|
| 610 |
-
_title_html = (
|
| 611 |
-
f'<a href="{_escape(_link)}" target="_blank" style="color:#003366;font-weight:600">{_t}</a>'
|
| 612 |
-
if _link else f'<span style="font-weight:600">{_t}</span>'
|
| 613 |
-
)
|
| 614 |
-
_oa_html = (
|
| 615 |
-
f' Β· <a href="{_escape(_oa)}" target="_blank" '
|
| 616 |
-
f'style="color:#047857;font-weight:700">π OA full text</a>'
|
| 617 |
-
if _oa else ""
|
| 618 |
-
)
|
| 619 |
-
rows += (
|
| 620 |
-
f'<div style="margin:7px 0;padding-left:2px;font-size:.84rem;line-height:1.55">'
|
| 621 |
-
f'{_title_html}<br>'
|
| 622 |
-
f'<span style="color:#6b7280;font-size:.78rem">{_meta}{_oa_html}</span></div>'
|
| 623 |
-
)
|
| 624 |
-
answer += (
|
| 625 |
-
'<div style="margin-top:16px;padding:12px 14px;border:1px solid #d1fae5;'
|
| 626 |
-
'border-radius:10px;background:#f0fdf9">'
|
| 627 |
-
'<div style="font-weight:700;color:#065f46;font-size:.86rem;margin-bottom:4px">'
|
| 628 |
-
'π Open scholarly evidence</div>'
|
| 629 |
-
'<div style="font-size:.76rem;color:#047857;margin-bottom:8px">'
|
| 630 |
-
'Top open-index results (OpenAlex / Semantic Scholar) with legal open-access '
|
| 631 |
-
'links via Unpaywall where available.</div>'
|
| 632 |
-
f'{rows}</div>'
|
| 633 |
-
)
|
| 634 |
|
| 635 |
answer += _ai_tools_footer(context)
|
| 636 |
return answer, papers, []
|
|
@@ -903,8 +853,13 @@ async def _run_search_mode(
|
|
| 903 |
source_url = _primo_clean_url(context)
|
| 904 |
topic = _escape(context.display_topic or context.topic)
|
| 905 |
|
| 906 |
-
# 3-sentence topic intro
|
| 907 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 908 |
|
| 909 |
answer = _search_trace_block(question, context)
|
| 910 |
if intro:
|
|
@@ -920,9 +875,10 @@ async def _run_search_mode(
|
|
| 920 |
f'π‘ Inside PRIMO you can filter by <strong>Articles</strong>, <strong>Books</strong>, '
|
| 921 |
f'<strong>Peer Reviewed</strong>, date range, and more.</div>'
|
| 922 |
)
|
|
|
|
| 923 |
answer += _ai_tools_footer(context)
|
| 924 |
|
| 925 |
-
return answer,
|
| 926 |
|
| 927 |
|
| 928 |
def _sort_and_trim_contexts(contexts: List[SearchContextPayload]) -> List[SearchContextPayload]:
|
|
|
|
| 17 |
from src.config import get_settings, LIBBEE_VERSION
|
| 18 |
|
| 19 |
from src.agentcore.models import ClientStatePayload, SearchContextPayload
|
| 20 |
+
from src.agentcore.scholarly import fetch_evidence_panel
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
from src.agentcore.constants import (
|
| 22 |
ALT_TERMS_RE,
|
| 23 |
CURRENT_YEAR,
|
|
|
|
| 578 |
f'Search PRIMO for: {_escape(topic)} β</a>'
|
| 579 |
)
|
| 580 |
|
| 581 |
+
# Shared open-evidence panel (see scholarly.fetch_evidence_panel)
|
| 582 |
+
papers, panel_html = await fetch_evidence_panel(topic)
|
| 583 |
+
answer += panel_html
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 584 |
|
| 585 |
answer += _ai_tools_footer(context)
|
| 586 |
return answer, papers, []
|
|
|
|
| 853 |
source_url = _primo_clean_url(context)
|
| 854 |
topic = _escape(context.display_topic or context.topic)
|
| 855 |
|
| 856 |
+
# 3-sentence topic intro AND the open-evidence panel, fetched concurrently:
|
| 857 |
+
# the panel's network time hides inside the intro's LLM latency instead of
|
| 858 |
+
# adding to it. Both degrade independently if they fail.
|
| 859 |
+
intro, (papers, panel_html) = await asyncio.gather(
|
| 860 |
+
_topic_intro(context.display_topic or context.topic, model),
|
| 861 |
+
fetch_evidence_panel(context.display_topic or context.topic),
|
| 862 |
+
)
|
| 863 |
|
| 864 |
answer = _search_trace_block(question, context)
|
| 865 |
if intro:
|
|
|
|
| 875 |
f'π‘ Inside PRIMO you can filter by <strong>Articles</strong>, <strong>Books</strong>, '
|
| 876 |
f'<strong>Peer Reviewed</strong>, date range, and more.</div>'
|
| 877 |
)
|
| 878 |
+
answer += panel_html
|
| 879 |
answer += _ai_tools_footer(context)
|
| 880 |
|
| 881 |
+
return answer, papers, [], source_url
|
| 882 |
|
| 883 |
|
| 884 |
def _sort_and_trim_contexts(contexts: List[SearchContextPayload]) -> List[SearchContextPayload]:
|