From 5697cd0c402563d8ca866c7ee28be72e4685be6b Mon Sep 17 00:00:00 2001 From: Marco Costa Date: Mon, 26 Oct 2026 17:01:50 -0300 Subject: [PATCH] perf(agent): cache scraped pages and retry failed fetches Adds a disk-backed scrape cache under workspace/web_cache keyed by the SHA-256 of the URL, honoring WEB_SEARCH_SCRAPE_CACHE_TTL so repeated lookups within the window skip the network entirely. Fetches now retry twice with exponential backoff before giving up, and URLs are screened against SCRAPING_BLOCKED_EXTENSIONS and SCRAPING_BLOCKED_DOMAINS to avoid downloading binaries or denylisted hosts. New scraping knobs (enable flag, max chars, cache TTL, blocklists) are exposed via .env, alongside a provider switch to stepfun with the step-3.7-flash default model. --- .env | 11 +- __pycache__/psagentai_agent.cpython-311.pyc | Bin 346117 -> 355577 bytes contexts/2026-10-26.json | 140 +++++++++---------- psagentai_agent.py | 146 ++++++++++++++++++-- 4 files changed, 216 insertions(+), 81 deletions(-) diff --git a/.env b/.env index 3935ecf..e4a1b56 100755 --- a/.env +++ b/.env @@ -5,10 +5,10 @@ TELEGRAM_CHAT_ID=7889499475 # AI Provider (openrouter | stepfun | qwencloud | llamacpp) -AI_PROVIDER=openrouter +AI_PROVIDER=stepfun # Default AI Model -DEFAULT_MODEL=xiaomi/mimo-v2.6-flash +DEFAULT_MODEL=step-3.7-flash @@ -39,6 +39,13 @@ MAX_HISTORY_LENGTH=50 WEB_SEARCH_ENABLED=true WEB_SEARCH_MAX_RESULTS=5 +# Scraping configuration +WEB_SEARCH_SCRAPE_ENABLED=true +WEB_SEARCH_SCRAPE_MAX_CHARS=2500 +WEB_SEARCH_SCRAPE_CACHE_TTL=3600 +SCRAPING_BLOCKED_DOMAINS= +SCRAPING_BLOCKED_EXTENSIONS=.pdf,.jpg,.jpeg,.png,.gif,.svg,.zip,.rar,.exe,.dmg,.bin + # Vision / image analysis model VISION_MODEL=meta-llama/llama-4-maverick-17b-128e-instruct VISION_PROVIDER=openrouter diff --git a/__pycache__/psagentai_agent.cpython-311.pyc b/__pycache__/psagentai_agent.cpython-311.pyc index 7f011a488a4bb619740100810d1eab547a9227dc..8f26fe1261750dca3e3e22bed96a238a224db5e5 100644 GIT binary patch delta 54551 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 str: Extracted text content, or an empty string on any failure. """ try: + # Check cache first + from urllib.parse import urlparse + import hashlib + parsed = urlparse(url) + netloc = parsed.netloc.lower() + # Extension blacklist + path_lower = parsed.path.lower() + if any(path_lower.endswith(ext) for ext in SCRAPING_BLOCKED_EXTENSIONS): + print(f"[SCRAPE] blocked extension url={url}") + return "" + # Blocked domains + if any(netloc == blocked or netloc.endswith("." + blocked) for blocked in SCRAPING_BLOCKED_DOMAINS): + print(f"[SCRAPE] blocked domain url={url}") + return "" + # Build cache key + cache_key = hashlib.sha256(url.encode("utf-8")).hexdigest() + cache_dir = Path("workspace") / "web_cache" + cache_dir.mkdir(parents=True, exist_ok=True) + cache_file = cache_dir / f"{cache_key}.json" + # Check cache TTL + if cache_file.exists(): + try: + with open(cache_file, "r", encoding="utf-8") as f: + cache_entry = json.load(f) + cached_at = cache_entry.get("cached_at", 0) + if time.time() - cached_at < WEB_SEARCH_SCRAPE_CACHE_TTL: + content = cache_entry.get("content", "") + if content: + print(f"[SCRAPE] cache hit url={url}") + return content[:max_chars] if len(content) > max_chars else content + else: + cache_file.unlink(missing_ok=True) + except Exception: + cache_file.unlink(missing_ok=True) headers = { "User-Agent": ( "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " @@ -288,10 +338,41 @@ def _fetch_page_content(url: str, max_chars: int = 3000) -> str: "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.9,pt-BR;q=0.8,pt;q=0.7", } - response = requests.get(url, headers=headers, timeout=10) - response.raise_for_status() + # Retry + backoff + session = requests.Session() + retries = 2 + backoff = 1 + response = None + for attempt in range(retries): + try: + response = session.get(url, headers=headers, timeout=10) + if response.status_code == 429: + time.sleep(backoff) + backoff *= 2 + continue + response.raise_for_status() + break + except requests.exceptions.RequestException: + if attempt < retries - 1: + time.sleep(backoff) + backoff *= 2 + else: + print(f"[SCRAPE] fail url={url} status=error") + return "" + if response is None or response.status_code != 200: + print(f"[SCRAPE] fail url={url} status={response.status_code if response else 'none'}") + return "" + # CAPTCHA / block detection content_type = response.headers.get("Content-Type", "") if "text/html" not in content_type.lower() and "application/xhtml" not in content_type.lower(): + print(f"[SCRAPE] blocked non-html url={url}") + return "" + lowered = response.text.lower() + if "attention required" in lowered or "captcha" in lowered or "cloudflare" in lowered: + print(f"[SCRAPE] blocked captcha url={url}") + return "" + if response.status_code in (403, 429): + print(f"[SCRAPE] blocked status={response.status_code} url={url}") return "" from bs4 import BeautifulSoup soup = BeautifulSoup(response.text, "lxml") @@ -303,6 +384,13 @@ def _fetch_page_content(url: str, max_chars: int = 3000) -> str: cleaned = "\n".join(lines) if len(cleaned) > max_chars: cleaned = cleaned[:max_chars] + "..." + # Save to cache + try: + with open(cache_file, "w", encoding="utf-8") as f: + json.dump({"url": url, "content": cleaned, "cached_at": time.time()}, f, ensure_ascii=False) + except Exception: + pass + print(f"[SCRAPE] ok url={url} chars={len(cleaned)}") return cleaned except Exception: return "" @@ -1082,6 +1170,7 @@ def ensure_workspace_dirs(): """ Path(UPLOADS_DIR).mkdir(parents=True, exist_ok=True) Path(WORKSPACE_PROJECTS_DIR).mkdir(parents=True, exist_ok=True) + Path("workspace", "web_cache").mkdir(parents=True, exist_ok=True) def save_workspace_file(relative_path: str, content: str) -> str: @@ -6000,6 +6089,7 @@ Examples: - "search about the new iPhone" - "what is the weather forecast for São Paulo" - "who is the president of Brazil" +- /sources - Show the sources used in the last web search ━━━━━━━━━━━━━━━━━━━━━━ 8️⃣ SCHEDULING AND ROUTINE @@ -6110,6 +6200,7 @@ Utilities: /configai - Configure the AI provider and model interactively with button selection /viewvision - Shows the current vision provider and model /configvision - Configure the vision model interactively with button selection +/sources - Show the sources used in the last web search /about - Displays system information, version, author and license Tip: just send a normal message to chat with me! """ @@ -6767,12 +6858,17 @@ async def process_text_message(update: Update, context: ContextTypes.DEFAULT_TYP if search_query: web_results = _web_search(search_query, max_results=WEB_SEARCH_MAX_RESULTS) # Fetch page content for each result to provide richer context. - for result in web_results: - page_url = result.get("url", "") - if page_url: - page_text = _fetch_page_content(page_url, max_chars=2500) - if page_text: - result["content"] = page_text + if WEB_SEARCH_SCRAPE_ENABLED: + # Dynamic content limit: reserve ~60% of remaining context for content, + # capped by WEB_SEARCH_SCRAPE_MAX_CHARS. + remaining_chars = max(1000, 12000 - len(modified)) + per_result_max = min(WEB_SEARCH_SCRAPE_MAX_CHARS, max(500, int(remaining_chars * 0.6 / max(len(web_results), 1)))) + for result in web_results: + page_url = result.get("url", "") + if page_url: + page_text = _fetch_page_content(page_url, max_chars=per_result_max) + if page_text: + result["content"] = page_text else: web_results = [] if web_results: @@ -6782,8 +6878,13 @@ async def process_text_message(update: Update, context: ContextTypes.DEFAULT_TYP page_content = result.get("content") if page_content: web_context += f"Content:\n{page_content}\n" - web_context += "\n[END OF WEB SEARCH RESULTS - Base your answer ONLY on the information above. If the information is not sufficient, say so. NEVER invent facts, URLs, or references.]" + web_context += "\n[END OF WEB SEARCH RESULTS - IMPORTANT: Base your answer ONLY on the information above. Use the Content sections when available. If the information is not sufficient or you could not read the pages, say so clearly. NEVER invent facts, URLs, or references.]" modified = modified + "\n\n" + web_context + # Store sources for /sources command + context.user_data["last_web_sources"] = [ + {"title": r.get("title", ""), "url": r.get("url", ""), "content": r.get("content", "")} + for r in web_results + ] else: web_results = [] @@ -6800,6 +6901,32 @@ async def process_text_message(update: Update, context: ContextTypes.DEFAULT_TYP else: await update.message.reply_text("Sorry, I'm having a little problem right now. Can you try again? 😔") +async def sources_command(update: Update, context: ContextTypes.DEFAULT_TYPE): + """Handle /sources: show sources from the last web search. + + Args: + update: Telegram update. + context: PTB callback context. + + Returns: + None. + """ + await auto_detect_chat_id(update) + sources = context.user_data.get("last_web_sources", []) + if not sources: + await update.message.reply_text("No recent web search sources available. Try asking a search question first!") + return + lines = ["📚 Sources from last search:"] + for i, src in enumerate(sources, 1): + title = src.get("title", "Untitled") + url = src.get("url", "") + content = src.get("content", "") + lines.append(f"{i}. {title}\n{url}") + if content: + preview = content[:300] + ("..." if len(content) > 300 else "") + lines.append(f"Preview: {preview}") + await update.message.reply_text("\n\n".join(lines)) + async def debug_command(update: Update, context: ContextTypes.DEFAULT_TYPE): """Handle /debug: print connectivity and configuration diagnostics. @@ -7342,6 +7469,7 @@ def main(): app_instance.add_handler(CommandHandler("debug", debug_command)) app_instance.add_handler(CommandHandler("reload", reload_command)) app_instance.add_handler(CommandHandler("about", about_command)) + app_instance.add_handler(CommandHandler("sources", sources_command)) app_instance.add_handler(CommandHandler("viewai", viewai_command)) app_instance.add_handler(CommandHandler("configai", configai_command)) app_instance.add_handler(CommandHandler("updatesystem", updatesystem_command))