import re import os from typing import List from app.tool.base import BaseTool from app.utils.signal_registry import signal_registry from app.tool.rss_matrix_sync import RSSMatrixSync from app.logger import logger class ContextDiscovery(BaseTool): """ Scans the project/session context for 'Signals' (URLs, RSS feeds, API endpoints). Auto-configures and initializes RSS-CPs to populate the Signal Mesh. """ name: str = "context_discovery" description: str = "Scan project files and environment for data signals to auto-initialize antennae." parameters: dict = { "type": "object", "properties": { "search_depth": { "type": "integer", "default": 1, "description": "How deep to scan the local project structure for signal sources." } } } async def execute(self, search_depth: int = 1) -> str: signals_found = [] # 1. Scan .env and README for URLs files_to_scan = [".env", "README.md", "GEMINI.md", "package.json", "requirements.txt"] url_pattern = re.compile(r'https?://[^\s<>"]+|www\.[^\s<>"]+') for filename in files_to_scan: if os.path.exists(filename): try: with open(filename, 'r') as f: content = f.read() urls = url_pattern.findall(content) for url in urls: # Heuristic: Prefer RSS/Atom/XML URLs if any(ext in url.lower() for ext in ["rss", "atom", "xml", "feed"]): signals_found.append(url) except Exception: continue if not signals_found: # Fallback: Suggest common signals based on project keywords signals_found.append("https://news.ycombinator.com/rss") # Global tech signal # 2. Engage/Initialize the RSS-CPs sync_tool = RSSMatrixSync() engaged = [] for url in list(set(signals_found)): logger.info(f"📡 Auto-tuning to discovered signal: {url}") result = await sync_tool.execute(url=url) engaged.append(f"{url}: {result[:50]}...") # Also register the raw feed as a broadcast signal_registry.broadcast(name=f"feed_{url}", source_type="rss_cp", data=url) report = f"Context Discovery complete. Engaged {len(engaged)} Signal Providers:\n" + "\n".join(engaged) return report