Create alerts.py
Browse files- mcp/alerts.py +48 -0
mcp/alerts.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# mcp/alerts.py
|
| 2 |
+
"""
|
| 3 |
+
Saved-query alert helper.
|
| 4 |
+
• Stores the last 30 PubMed/arXiv links per query.
|
| 5 |
+
• Returns a dict of {query: [new_links]} when fresh papers appear.
|
| 6 |
+
Implementation is intentionally simple: JSON on disk + orchestrate_search.
|
| 7 |
+
"""
|
| 8 |
+
|
| 9 |
+
import json, asyncio
|
| 10 |
+
from pathlib import Path
|
| 11 |
+
from typing import List, Dict
|
| 12 |
+
|
| 13 |
+
from mcp.orchestrator import orchestrate_search
|
| 14 |
+
|
| 15 |
+
_ALERT_DB = Path("saved_alerts.json")
|
| 16 |
+
_MAX_IDS = 30 # keep last N links per query
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
def _read_db() -> Dict[str, List[str]]:
|
| 20 |
+
if _ALERT_DB.exists():
|
| 21 |
+
return json.loads(_ALERT_DB.read_text())
|
| 22 |
+
return {}
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def _write_db(data: Dict[str, List[str]]):
|
| 26 |
+
_ALERT_DB.write_text(json.dumps(data, indent=2))
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
async def check_alerts(queries: List[str]) -> Dict[str, List[str]]:
|
| 30 |
+
"""
|
| 31 |
+
For each saved query, run a quick orchestrate_search and detect new paper links.
|
| 32 |
+
Returns {query: [fresh_links]} (empty dict if nothing new).
|
| 33 |
+
"""
|
| 34 |
+
db = _read_db()
|
| 35 |
+
new_map = {}
|
| 36 |
+
|
| 37 |
+
async def _check(q: str):
|
| 38 |
+
res = await orchestrate_search(q)
|
| 39 |
+
links = [p["link"] for p in res["papers"]]
|
| 40 |
+
prev = set(db.get(q, []))
|
| 41 |
+
fresh = [l for l in links if l not in prev]
|
| 42 |
+
if fresh:
|
| 43 |
+
new_map[q] = fresh
|
| 44 |
+
db[q] = links[:_MAX_IDS] # save trimmed
|
| 45 |
+
# run in parallel
|
| 46 |
+
await asyncio.gather(*[_check(q) for q in queries])
|
| 47 |
+
_write_db(db)
|
| 48 |
+
return new_map
|