Spaces:
Sleeping
Sleeping
File size: 6,053 Bytes
00b591a | 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 | import sys
import io
import requests
from bs4 import BeautifulSoup
import pandas as pd
from pypdf import PdfReader
from langchain_core.tools import tool
from langchain_community.tools import DuckDuckGoSearchRun
import pptx
import docx # If missing, run: pip install python-docx
# 1. Native LangChain Search Tool
web_search = DuckDuckGoSearchRun(
description=(
"A wrapper around DuckDuckGo Search. Useful for searching the web for current facts, "
"academic papers, and conference proceedings. When looking for specific journal articles "
"like Nature Scientific Reports 2012, do not search full complex sentences. Instead, "
"pass clean, broad keyword queries (e.g., 'Nature Scientific Reports 2012 conference proceedings nano compound') "
"to get the best results. If this tool returns no relevant text, immediately fall back to "
"using `execute_python_code` to fetch resources programmatically."
)
)
# 2. Resilient Web Scraping Tool
@tool
def fetch_webpage_content(url: str) -> str:
"""Useful when you need to read the full text content of a specific URL webpage.
It strips away HTML tags and returns clean text snippets."""
try:
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}
# Enforce strict 10s connect and read timeouts
response = requests.get(url, headers=headers, timeout=(5, 10), stream=False)
response.raise_for_status()
soup = BeautifulSoup(response.text, "html.parser")
# Remove script and style elements
for script in soup(["script", "style"]):
script.decompose()
text = soup.get_text(separator=" ")
lines = (line.strip() for line in text.splitlines())
chunks = (phrase.strip() for line in lines for phrase in line.split(" "))
clean_text = "\n".join(chunk for chunk in chunks if chunk)
return clean_text[:6000]
except Exception as e:
return f"Error reading page content: {e}"
# 3. Robust Code Sandbox (Standard Output Redirected)
@tool
def execute_python_code(code: str) -> str:
"""Useful to run complex calculations, logical processing, or data manipulation.
Write full code blocks using print() statements to view target evaluation values."""
old_stdout = sys.stdout
redirected_output = sys.stdout = io.StringIO()
local_vars = {}
try:
# Execute code in a clean workspace context
exec(code, {"pd": pd, "openpyxl": openpyxl if 'openpyxl' in sys.modules else None}, local_vars)
sys.stdout = old_stdout
captured_out = redirected_output.getvalue()
if not captured_out and local_vars:
return f"Execution succeeded. Captured workspace variables: {str(local_vars)}"
return captured_out if captured_out else "Execution complete with no output print statements."
except Exception as e:
sys.stdout = old_stdout
return f"Execution Error: {e}"
# 4. Specialized Document Analysis Tools
@tool
def read_local_pdf(file_path: str) -> str:
"""Extracts raw string text layout from a target local PDF file document."""
try:
reader = PdfReader(file_path)
extracted_text = ""
for page in reader.pages[:10]: # Safe chunk limits
extracted_text += page.extract_text() + "\n"
return extracted_text[:6000]
except Exception as e:
return f"Failed to parse PDF document: {e}"
@tool
def inspect_excel_sheets(file_path: str) -> str:
"""Reads names of all tabs and displays preview slices of spreadsheets for data inspection."""
try:
# Read file bytes into memory first to avoid thread deadlocks on Windows
with open(file_path, "rb") as f:
file_bytes = io.BytesIO(f.read())
xl = pd.ExcelFile(file_bytes)
summary = f"Available sheets/tabs: {xl.sheet_names}\n\n"
for sheet in xl.sheet_names[:3]:
df = pd.read_excel(file_bytes, sheet_name=sheet)
summary += f"--- Sheet: {sheet} (Shape: {df.shape}) ---\n"
summary += df.head(5).to_string() + "\n\n"
return summary[:6000]
except Exception as e:
return f"Failed to analyze spreadsheet structure: {e}"
@tool
def read_local_docx(file_path: str) -> str:
"""Useful to extract raw text paragraph contents layout from a target local Word document (.docx)."""
try:
# Read file bytes completely first to prevent thread deadlock issues on Windows systems
with open(file_path, "rb") as f:
file_bytes = io.BytesIO(f.read())
doc = docx.Document(file_bytes)
full_text = [para.text for para in doc.paragraphs if para.text]
return "\n".join(full_text)[:6000]
except Exception as e:
return f"Failed to parse Word document: {e}"
@tool
def read_local_pptx(file_path: str) -> str:
"""Useful to extract raw text slide-by-slide from a target PowerPoint presentation (.pptx)."""
try:
with open(file_path, "rb") as f:
file_bytes = io.BytesIO(f.read())
prs = pptx.Presentation(file_bytes)
summary = ""
for i, slide in enumerate(prs.slides, start=1):
slide_text = []
for shape in slide.shapes:
if shape.has_text_frame:
slide_text.append(shape.text_frame.text.strip())
text_content = " | ".join(t for t in slide_text if t)
summary += f"Slide {i}: {text_content}\n"
return summary[:6000]
except Exception as e:
return f"Failed to parse PowerPoint file: {e}"
# Expose complete toolkit array to LangGraph agent executor
all_tools = [
web_search,
fetch_webpage_content,
execute_python_code,
read_local_pdf,
inspect_excel_sheets,
read_local_docx,
read_local_pptx
] |