Paritosh Upadhyay commited on
Commit ·
fa0757c
1
Parent(s): a4277f4
Aggressive Tactical Upgrade: Parallel Foraging & Search Identity Juggling
Browse files- backend/app/services/holocron.py +21 -12
- backend/app/services/tools/search.py +15 -13
backend/app/services/holocron.py
CHANGED
|
@@ -11,6 +11,7 @@ import threading
|
|
| 11 |
import time
|
| 12 |
from app.services.tools import search
|
| 13 |
from app.services import state_sync, watchdog, state
|
|
|
|
| 14 |
|
| 15 |
logger = logging.getLogger("friday.holocron")
|
| 16 |
|
|
@@ -217,20 +218,28 @@ def batch_mine_priorities():
|
|
| 217 |
]
|
| 218 |
random.shuffle(domains) # Jitter topic order to avoid pattern matching
|
| 219 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 220 |
def _run_batch():
|
| 221 |
-
logger.info("Holocron: Initiating Sovereign
|
| 222 |
-
|
| 223 |
-
if _check_halt()
|
| 224 |
-
|
| 225 |
-
break
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
time.sleep(random.randint(15, 30))
|
| 233 |
logger.info("Holocron: Sovereign Priority Ingestion Cycle Complete.")
|
|
|
|
| 234 |
|
| 235 |
threading.Thread(target=_run_batch, daemon=True).start()
|
| 236 |
|
|
|
|
| 11 |
import time
|
| 12 |
from app.services.tools import search
|
| 13 |
from app.services import state_sync, watchdog, state
|
| 14 |
+
import concurrent.futures
|
| 15 |
|
| 16 |
logger = logging.getLogger("friday.holocron")
|
| 17 |
|
|
|
|
| 218 |
]
|
| 219 |
random.shuffle(domains) # Jitter topic order to avoid pattern matching
|
| 220 |
|
| 221 |
+
def _threaded_mine(d: str):
|
| 222 |
+
"""Thread wrapper for mining a specific topic."""
|
| 223 |
+
if _check_halt(): return
|
| 224 |
+
_active_foraging_threads.add(d)
|
| 225 |
+
try:
|
| 226 |
+
_mine_sync(d, depth=1)
|
| 227 |
+
finally:
|
| 228 |
+
_active_foraging_threads.remove(d)
|
| 229 |
+
|
| 230 |
def _run_batch():
|
| 231 |
+
logger.info("Holocron: Initiating Sovereign Parallel Ingestion (Workers: 3)...")
|
| 232 |
+
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
|
| 233 |
+
futures = [executor.submit(_threaded_mine, d) for d in domains if not _check_halt()]
|
| 234 |
+
for future in concurrent.futures.as_completed(futures):
|
| 235 |
+
if _check_halt(): break
|
| 236 |
+
try:
|
| 237 |
+
future.result()
|
| 238 |
+
except Exception as e:
|
| 239 |
+
logger.error(f"Parallel Worker Error: {e}")
|
| 240 |
+
|
|
|
|
|
|
|
| 241 |
logger.info("Holocron: Sovereign Priority Ingestion Cycle Complete.")
|
| 242 |
+
time.sleep(random.randint(45, 90)) # Increased sleep after a parallel burst to cool down IP
|
| 243 |
|
| 244 |
threading.Thread(target=_run_batch, daemon=True).start()
|
| 245 |
|
backend/app/services/tools/search.py
CHANGED
|
@@ -37,6 +37,7 @@ def search_web(query: str, max_results: int = 5, bypass_cache: bool = False) ->
|
|
| 37 |
logger.info(f"Memory hit for: {query}. Using local cache.")
|
| 38 |
return [{"title": "Cached Local Memory", "href": "local://memory", "body": cached_result}]
|
| 39 |
|
|
|
|
| 40 |
for attempt in range(max_retries):
|
| 41 |
# INSTANT KILL-SWITCH CHECK
|
| 42 |
if state.is_sovereign_locked() or state.is_learning_locked():
|
|
@@ -44,17 +45,16 @@ def search_web(query: str, max_results: int = 5, bypass_cache: bool = False) ->
|
|
| 44 |
return []
|
| 45 |
|
| 46 |
try:
|
| 47 |
-
# [STEALH]
|
| 48 |
-
|
| 49 |
-
time.sleep(jitter)
|
| 50 |
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
# [STEALTH] User-Agent Rotation
|
| 54 |
ua = random.choice(user_agents)
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
|
|
|
|
|
|
| 58 |
results = [r for r in ddgs.text(query, max_results=max_results, backend=backend)]
|
| 59 |
|
| 60 |
# Consolidate into memory if useful
|
|
@@ -64,16 +64,18 @@ def search_web(query: str, max_results: int = 5, bypass_cache: bool = False) ->
|
|
| 64 |
memory.embed_conversation("knowledge_cache", summary, entities=query)
|
| 65 |
|
| 66 |
return results
|
| 67 |
-
except
|
| 68 |
err_str = str(e).lower()
|
| 69 |
is_transient = any(k in err_str for k in ["ratelimit", "timeout", "202", "connection"])
|
| 70 |
|
| 71 |
if is_transient and attempt < max_retries - 1:
|
| 72 |
-
|
| 73 |
-
|
|
|
|
| 74 |
time.sleep(wait_time)
|
| 75 |
else:
|
| 76 |
-
|
|
|
|
| 77 |
|
| 78 |
except Exception as e:
|
| 79 |
logger.error(f"Web search failed after critical retries: {e}")
|
|
|
|
| 37 |
logger.info(f"Memory hit for: {query}. Using local cache.")
|
| 38 |
return [{"title": "Cached Local Memory", "href": "local://memory", "body": cached_result}]
|
| 39 |
|
| 40 |
+
backends = ["lite", "html", "auto"]
|
| 41 |
for attempt in range(max_retries):
|
| 42 |
# INSTANT KILL-SWITCH CHECK
|
| 43 |
if state.is_sovereign_locked() or state.is_learning_locked():
|
|
|
|
| 45 |
return []
|
| 46 |
|
| 47 |
try:
|
| 48 |
+
# [STEALH] Smaller Jitter for speed (3-6s)
|
| 49 |
+
time.sleep(random.uniform(3, 6))
|
|
|
|
| 50 |
|
| 51 |
+
# [STEALTH] Identity Juggling: UA + Backend Rotation
|
|
|
|
|
|
|
| 52 |
ua = random.choice(user_agents)
|
| 53 |
+
backend = backends[attempt % len(backends)]
|
| 54 |
+
|
| 55 |
+
logger.info(f"Searching [{backend}] for: {query} (Attempt {attempt+1}/{max_retries})")
|
| 56 |
+
|
| 57 |
+
with DDGS(headers={"User-Agent": ua}, timeout=40) as ddgs:
|
| 58 |
results = [r for r in ddgs.text(query, max_results=max_results, backend=backend)]
|
| 59 |
|
| 60 |
# Consolidate into memory if useful
|
|
|
|
| 64 |
memory.embed_conversation("knowledge_cache", summary, entities=query)
|
| 65 |
|
| 66 |
return results
|
| 67 |
+
except Exception as e:
|
| 68 |
err_str = str(e).lower()
|
| 69 |
is_transient = any(k in err_str for k in ["ratelimit", "timeout", "202", "connection"])
|
| 70 |
|
| 71 |
if is_transient and attempt < max_retries - 1:
|
| 72 |
+
# [TACTICAL] 2-5s burst retry with NEW identity
|
| 73 |
+
wait_time = random.uniform(2, 5)
|
| 74 |
+
logger.warning(f"Search Tactical Maneuver: {e}. Swapping Identity & Retrying in {wait_time:.1f}s...")
|
| 75 |
time.sleep(wait_time)
|
| 76 |
else:
|
| 77 |
+
logger.error(f"Search Exhausted: {e}")
|
| 78 |
+
return []
|
| 79 |
|
| 80 |
except Exception as e:
|
| 81 |
logger.error(f"Web search failed after critical retries: {e}")
|