from langchain.tools import tool import subprocess from langchain_community.tools import DuckDuckGoSearchRun web_search = DuckDuckGoSearchRun() @tool def run_python(code: str) -> str: """Eksekusi kode Python secara lokal dan kembalikan output. Gunakan ini untuk melakukan kalkulasi matematika atau memanipulasi data sederhana.""" try: result = subprocess.run( ["python", "-c", code], capture_output=True, text=True, timeout=10 ) return result.stdout or result.stderr except subprocess.TimeoutExpired: return "Error: Timeout" except Exception as e: return f"Error: {str(e)}" import requests import json from docx import Document import os import uuid from bs4 import BeautifulSoup from gtts import gTTS import pytesseract from PIL import Image try: from api.agent.knowledge_graph import add_paper_relation, query_graph except ImportError: pass @tool def search_crossref(query: str) -> str: """Cari jurnal asli dan peer-reviewed di database Crossref.""" try: url = f"https://api.crossref.org/works?query={query}&select=title,author,DOI,published&rows=3" response = requests.get(url, timeout=10) data = response.json() items = data.get("message", {}).get("items", []) if not items: return "Tidak ada jurnal yang ditemukan di Crossref." result = "Hasil Pencarian Crossref:\n" for item in items: title = item.get("title", [""])[0] doi = item.get("DOI", "") result += f"- Judul: {title} (DOI: {doi})\n" return result except Exception as e: return f"Error mencari di Crossref: {str(e)}" @tool def export_to_docx(content: str, title: str = "Hasil Analisis") -> str: """Simpan teks yang panjang atau laporan menjadi file Microsoft Word (.docx).""" try: doc = Document() doc.add_heading(title, 0) doc.add_paragraph(content) # Simpan di folder public/exports agar bisa di-download user os.makedirs("public/exports", exist_ok=True) filename = f"{uuid.uuid4().hex[:8]}.docx" filepath = os.path.join("public/exports", filename) doc.save(filepath) return f"File Word berhasil dibuat! Link download: /exports/{filename}" except Exception as e: return f"Gagal membuat file Word: {str(e)}" @tool def read_image_ocr(image_path: str) -> str: """Ekstrak teks dari gambar, foto, atau grafik (membutuhkan Tesseract OCR terinstal di sistem).""" try: if not os.path.exists(image_path): return "Gambar tidak ditemukan." img = Image.open(image_path) text = pytesseract.image_to_string(img, lang='ind+eng') return f"Teks yang diekstrak dari gambar:\n{text}" except Exception as e: return f"Error OCR (Pastikan Tesseract terinstal di sistem operasi): {str(e)}" @tool def scrape_website(url: str) -> str: """Baca seluruh isi teks dari sebuah halaman web atau jurnal (Web Scraping).""" try: headers = {'User-Agent': 'Mozilla/5.0'} response = requests.get(url, headers=headers, timeout=15) soup = BeautifulSoup(response.text, 'html.parser') # Ekstrak semua paragraf paragraphs = soup.find_all('p') text = "\n".join([p.get_text() for p in paragraphs]) # Batasi output agar tidak terlalu panjang return f"Isi Web:\n{text[:3000]}..." if len(text) > 3000 else text except Exception as e: return f"Gagal membaca website: {str(e)}" @tool def synthesize_audio(text: str) -> str: """Ubah teks laporan atau rangkuman menjadi file suara Audio (.mp3).""" try: tts = gTTS(text=text[:5000], lang='id', slow=False) os.makedirs("public/audio", exist_ok=True) filename = f"{uuid.uuid4().hex[:8]}.mp3" filepath = os.path.join("public/audio", filename) tts.save(filepath) return f"Audio berhasil dibuat! Dengarkan di: /audio/{filename}" except Exception as e: return f"Gagal membuat audio: {str(e)}" @tool def add_to_knowledge_graph(source_paper: str, target_paper: str, relation: str) -> str: """Tambahkan relasi antar jurnal ke dalam memori Knowledge Graph (relation: cites, refutes, supports).""" try: return add_paper_relation(source_paper, target_paper, relation) except Exception as e: return str(e) @tool def query_knowledge_graph(paper_name: str) -> str: """Cari jurnal dan silsilah hubungannya di dalam Knowledge Graph.""" try: return query_graph(paper_name) except Exception as e: return str(e) # Kumpulan tools yang tersedia untuk agent AVAILABLE_TOOLS = [ run_python, calculate_academic_score, web_search, search_crossref, export_to_docx, read_image_ocr, scrape_website, synthesize_audio, add_to_knowledge_graph, query_knowledge_graph ]