Spaces:
Running on Zero
Running on Zero
File size: 15,448 Bytes
1b38924 | 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 | import requests
from typing import Dict, Any
import xml.etree.ElementTree as ET
import database
def search_arxiv_papers(query:str, max_results:int=10) -> Dict[str, Any]:
"""
Arxiv üzerinden kullanıcı sorgusunu arar ve başlık, yazar, özet ve PDF linklerini döner.
Inputs:
query: Kullanıcı sorgusu (Örneğin kullanıcı son 2 yılda çıkan Machine Learning makalelerini ara diyebilir.)
max_results: Dönen sonuçlar içerisinden seçilecek maksimum makale miktarı
Outputs:
Dict : {status: "success" or "error", count: int, papers: List[Dict] | None, message: str | None}
"""
try:
url = f"http://export.arxiv.org/api/query?search_query=all:{query}&start=0&max_results={max_results}"
response = requests.get(url, timeout=10)
root = ET.fromstring(response.text)
ns = {
"atom": "http://www.w3.org/2005/Atom"
}
papers = []
for entry in root.findall("atom:entry", ns):
arxiv_id_elem = entry.find('atom:id', ns)
raw_id = arxiv_id_elem.text if arxiv_id_elem is not None else ""
paper_id = raw_id.split('/abs/')[-1] if '/abs/' in raw_id else raw_id
title = entry.find("atom:title", ns).text.strip()
summary = entry.find("atom:summary", ns).text.strip()
authors = [author.find("atom:name", ns).text for author in entry.findall("atom:author", ns)]
pdf = None
for link in entry.findall("atom:link", ns):
if link.attrib.get("title") == "pdf":
pdf = link.attrib["href"]
published_elem = entry.find('atom:published', ns)
published = published_elem.text[:10] if published_elem is not None else ""
year = published[:4] if published else ""
authors = []
for author in entry.findall('atom:author', ns):
name_elem = author.find('atom:name', ns)
if name_elem is not None and name_elem.text:
authors.append(name_elem.text)
authors_str = ", ".join(authors)
paper_url = f"https://arxiv.org/abs/{paper_id}"
papers.append({
"paper_id": f"arxiv_{paper_id}",
"title": title,
"authors": authors_str,
"summary": summary[:350] + "..." if len(summary) > 350 else summary,
"url": paper_url,
"published_year": year,
"source": "ArXiv"
})
return {"status": "success", "count": len(papers), "papers": papers}
except Exception as e:
return {"status": "error", "message": str(e)}
def search_openalex(query: str, limit: int = 5) -> Dict[str, Any]:
"""OpenAlex üzerinden atıf sayıları (citations) ile zenginleştirilmiş akademik makaleleri getirir.
Inputs:
query: Kullanıcı sorgusu (Örneğin kullanıcı son 2 yılda çıkan Machine Learning makalelerini ara diyebilir.)
limit: Dönen sonuçlar içerisinden seçilecek maksimum makale miktarı
Outputs:
Dict : {status: "success" or "error", count: int, papers: List[Dict] | None, message: str | None}
"""
url = "https://api.openalex.org/works"
params = {
"search": query,
"per_page": limit,
"select": "id,title,publication_year,cited_by_count,authorships,doi,primary_location"
}
response = requests.get(url, params=params, timeout=10)
if response.status_code != 200:
print("OpenAlex API rate limit hatası oluştu, Arxiv API kullanılıyor...")
return search_arxiv_papers(query=query, max_results=limit)
data = response.json()
papers = []
for item in data.get("results", []):
paper_id = item.get("id", "").split("/")[-1]
title = item.get("title", "")
authors = [
author["author"]["display_name"]
for author in item.get("authorships", [])
]
authors_str = ", ".join(authors)
summary = ""
if "abstract" in item:
summary = item["abstract"]
year = item.get("publication_year", "")
citation_count = item.get("cited_by_count", 0)
location = item.get("primary_location", {})
paper_url = (
location.get("landing_page_url")
or item.get("doi")
or item.get("id")
)
papers.append({
"paper_id": f"openalex_{paper_id}",
"title": title,
"authors": authors_str,
"summary": summary[:350] + "..." if len(summary) > 350 else summary,
"citation_count": citation_count,
"published_year": year,
"url": paper_url,
"source": "OpenAlex"
})
return {
"status": "success",
"count": len(papers),
"papers": papers
}
def save_paper_to_library(paper_id: str, title: str, authors: str = "",
summary: str = "", url: str = "", source: str = "ArXiv", citation_count: int = 0,
published_year: str = "", tags: str = "") -> Dict[str, Any]:
"""Seçilen makaleyi SQLite kişisel veritabanına kaydeder.
Inputs:
paper_id: Makalenin benzersiz ID'si
title: Makalenin başlığı
authors: Makalenin yazarları
summary: Makalenin özeti
url: Makalenin URL'si
source: Makalenin kaynağı
citation_count: Makalenin atıf sayısı
published_year: Makalenin yayınlanma yılı
tags: Makalenin etiketleri
Outputs:
Dict : {status: "success" or "error", message: str}
"""
return database.save_paper(
paper_id=paper_id,
title=title,
authors=authors,
summary=summary,
url=url,
source=source,
citation_count=citation_count,
published_year=published_year,
tags=tags
)
def get_saved_library(status_filter: str = "hepsi", tag_filter: str = "", query: str = "") -> Dict[str, Any]:
"""Kayıtlı makale kütüphanesini okur ve listeler.
Inputs:
status_filter: Durum
tag_filter: Etiket
query: Arama sorgusu
Outputs:
Dict : {status: "success" or "error", count: int, papers: List[Dict] | None, message: str | None}
"""
papers = database.get_saved_papers(status_filter=status_filter, tag_filter=tag_filter, query=query)
return {
"status": "success",
"saved_count": len(papers),
"library": papers
}
def update_paper_status_or_note(paper_id: str, status: str = "", notes: str = "", tags: str = "") -> Dict[str, Any]:
"""Kayıtlı bir makalenin okuma durumunu ('unread', 'reading', 'completed') veya kişisel notlarını günceller.
Inputs:
paper_id: Makalenin benzersiz ID'si
status: Makalenin okuma durumu
notes: Makalenin kişisel notları
tags: Makalenin etiketleri
Outputs:
Dict : {status: "success" or "error", message: str}
"""
return database.update_paper_status_or_note(paper_id=paper_id, status=status if status else None, notes=notes if notes else None, tags=tags if tags else None)
def execute_tool(tool_name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:
"""LLM tarafından çağrılan fonksiyonu eşleştirir ve çalıştırır.
Inputs:
tool_name: Fonksiyonun adı
arguments: Fonksiyonun argümanları
Outputs:
Dict : {status: "success" or "error", message: str}
"""
if not isinstance(arguments, dict):
arguments = {}
cleaned_args = {k: v for k, v in arguments.items() if v is not None}
if tool_name == "search_arxiv_papers":
return search_arxiv_papers(**cleaned_args)
elif tool_name == "search_openalex":
return search_openalex(**cleaned_args)
elif tool_name == "save_paper_to_library":
return save_paper_to_library(**cleaned_args)
elif tool_name == "get_saved_library":
return get_saved_library(**cleaned_args)
elif tool_name == "update_paper_status_or_note":
return update_paper_status_or_note(**cleaned_args)
elif tool_name in ["delete_paper", "delete_paper_from_library"]:
return delete_paper(**cleaned_args)
elif tool_name in ["clear_library", "clear_entire_library"]:
return clear_library()
else:
return {"status": "error", "message": f"Bilinmeyen fonksiyon: {tool_name}"}
def delete_paper(paper_id:str) -> Dict[str, Any]:
"""Kayıtlı bir makaleyi veritabanından siler.
Inputs:
paper_id: Makalenin benzersiz ID'si
Outputs:
Dict : {status: "success" or "error", message: str}
"""
return database.delete_paper(paper_id=paper_id)
def clear_library() -> Dict[str, Any]:
"""Kütüphanedeki TÜM makaleleri veritabanından tamamen siler ve temizler.
Inputs:
None
Outputs:
Dict : {status: "success" or "error", message: str}
"""
return database.clear_library()
TOOLS_SCHEMA = [
{
"type": "function",
"function": {
"name": "search_arxiv_papers",
"description": "ArXiv akademik platformundan verilen konu veya kelimelere göre en güncel makaleleri arar ve getirir.",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Aranacak akademik konu veya anahtar kelimeler (örn: 'quantum machine learning', 'LLM tool calling')"
},
"max_results": {
"type": "integer",
"description": "Getirilecek maksimum makale sayısı (Varsayılan 10)",
"default": 10
}
},
"required": ["query"]
}
}
},
{
"type": "function",
"function": {
"name": "search_openalex",
"description": "OpenAlex platformundan makaleleri atıf sayıları (citations) ve yayın yılı bilgisi ile getirir.",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Aranacak makale konusu"
},
"limit": {
"type": "integer",
"description": "Getirilecek makale sayısı",
"default": 5
}
},
"required": ["query"]
}
}
},
{
"type": "function",
"function": {
"name": "save_paper_to_library",
"description": "Arama sonuçlarında bulunan bir makaleyi veritabanındaki kişisel kütüphaneye kaydeder.",
"parameters": {
"type": "object",
"properties": {
"paper_id": {"type": "string", "description": "Makalenin benzersiz kimliği (örn: arxiv_2303.08774)"},
"title": {"type": "string", "description": "Makale başlığı"},
"authors": {"type": "string", "description": "Yazarlar", "default": ""},
"summary": {"type": "string", "description": "Makale özeti", "default": ""},
"url": {"type": "string", "description": "Makale web/PDF bağlantısı", "default": ""},
"source": {"type": "string", "description": "Kaynak platform (ArXiv, OpenAlex)", "default": "ArXiv"},
"citation_count": {"type": "integer", "description": "Atıf sayısı", "default": 0},
"published_year": {"type": "string", "description": "Yayın yılı", "default": ""},
"tags": {"type": "string", "description": "Kullanıcı etiketleri", "default": ""}
},
"required": ["paper_id", "title"]
}
}
},
{
"type": "function",
"function": {
"name": "get_saved_library",
"description": "Veritabanına önceden kaydedilmiş makaleleri ve okuma listesini getirir. Filtre kullanılmayacaksa query ve tag_filter parametrelerine boş metin '' verilmeli veya dahil edilmemelidir.",
"parameters": {
"type": "object",
"properties": {
"status_filter": {
"type": "string",
"description": "Filtreleme durumu: 'hepsi', 'unread', 'reading', 'completed'",
"default": "hepsi"
},
"tag_filter": {
"type": "string",
"description": "Etikete göre filtreleme. Özel filtre yoksa '' (boş metin) kullanın.",
"default": ""
},
"query": {
"type": "string",
"description": "Başlık veya özet içinde kelime araması. Özel filtre yoksa '' (boş metin) kullanın.",
"default": ""
}
}
}
}
},
{
"type": "function",
"function": {
"name": "update_paper_status_or_note",
"description": "Kütüphanede kayıtlı bir makalenin okuma durumunu ('unread', 'reading', 'completed') günceller veya kişisel not/etiket ekler.",
"parameters": {
"type": "object",
"properties": {
"paper_id": {"type": "string", "description": "Güncellenecek makalenin kimliği veya ID'si"},
"status": {"type": "string", "description": "Yeni okuma durumu: 'unread', 'reading', 'completed'", "default": ""},
"notes": {"type": "string", "description": "Kullanıcının makaleye eklemek istediği özel not", "default": ""},
"tags": {"type": "string", "description": "Güncellenecek etiketler", "default": ""}
},
"required": ["paper_id"]
}
}
},
{
"type": "function",
"function": {
"name": "delete_paper",
"description": "Kütüphanede kayıtlı bir makaleyi veritabanından siler.",
"parameters": {
"type": "object",
"properties": {
"paper_id": {"type": "string", "description": "Silinecek makalenin kimliği veya ID'si"}
},
"required": ["paper_id"]
}
}
},
{
"type": "function",
"function": {
"name": "clear_library",
"description": "Kütüphanedeki TÜM makaleleri veritabanından tamamen siler ve temizler.",
"parameters": {
"type": "object",
"properties": {},
"required": []
}
}
}
]
|