"""Brave Search executor for cron jobs.""" import logging import os import httpx from .formatter import format_search_results logger = logging.getLogger(__name__) BRAVE_API_KEY = os.environ.get("BRAVE_API_KEY", "") async def execute_brave_search(job: dict, send_text, **_kwargs) -> dict: """Run a Brave Search query, dedup against known keys, post new results to Matrix.""" if not BRAVE_API_KEY: return {"status": "error", "error": "BRAVE_API_KEY not configured"} config = job.get("config", {}) query = config.get("query", "") max_results = config.get("maxResults", 10) target_room = job["targetRoom"] dedup_keys = set(job.get("dedupKeys", [])) if not query: return {"status": "error", "error": "No search query configured"} try: async with httpx.AsyncClient(timeout=15.0) as client: resp = await client.get( "https://api.search.brave.com/res/v1/web/search", headers={ "Accept": "application/json", "X-Subscription-Token": BRAVE_API_KEY, }, params={"q": query, "count": max_results, "text_decorations": False}, ) resp.raise_for_status() data = resp.json() results = data.get("web", {}).get("results", []) if not results: return {"status": "no_results"} # Dedup by URL new_results = [r for r in results if r.get("url") not in dedup_keys] if not new_results: return {"status": "no_results"} msg = format_search_results(job["name"], new_results) await send_text(target_room, msg) new_keys = [r["url"] for r in new_results if r.get("url")] return { "status": "success", "newDedupKeys": new_keys, } except Exception as exc: logger.error("Brave search cron failed: %s", exc, exc_info=True) return {"status": "error", "error": str(exc)}