|
|
""" |
|
|
Stealth Browser Agent - Persistent Session with Visible Browser |
|
|
================================================================ |
|
|
Uses browser-use with headless=False for VNC visibility. |
|
|
Maintains a persistent browser session for efficiency. |
|
|
""" |
|
|
|
|
|
import os |
|
|
import logging |
|
|
from typing import Dict, Any, Optional |
|
|
from dotenv import load_dotenv |
|
|
|
|
|
load_dotenv() |
|
|
|
|
|
|
|
|
if os.getenv("OPENROUTER_API_KEY") and not os.getenv("OPENAI_API_KEY"): |
|
|
os.environ["OPENAI_API_KEY"] = os.getenv("OPENROUTER_API_KEY") |
|
|
|
|
|
from langchain_openai import ChatOpenAI |
|
|
from browser_use import Agent, Controller, Browser |
|
|
|
|
|
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') |
|
|
logger = logging.getLogger(__name__) |
|
|
|
|
|
controller = Controller() |
|
|
|
|
|
|
|
|
class BrowserSession: |
|
|
"""Persistent browser session for efficiency.""" |
|
|
|
|
|
def __init__(self, browser: Browser): |
|
|
self.browser = browser |
|
|
self.is_active = True |
|
|
|
|
|
@classmethod |
|
|
async def create(cls) -> "BrowserSession": |
|
|
"""Create a new persistent browser session.""" |
|
|
logger.info(f"π₯οΈ Creating browser on display {os.environ.get('DISPLAY', ':99')}") |
|
|
browser = Browser(headless=False) |
|
|
return cls(browser) |
|
|
|
|
|
async def close(self): |
|
|
"""Close the browser session.""" |
|
|
if self.browser: |
|
|
try: |
|
|
await self.browser.close() |
|
|
except: |
|
|
pass |
|
|
self.is_active = False |
|
|
|
|
|
|
|
|
async def validate_order(order_data: Dict[str, Any], session: Optional[BrowserSession] = None) -> Dict[str, Any]: |
|
|
"""Validates order with VISIBLE browser - watch via Cloudflare tunnel!""" |
|
|
logger.info(f"π Starting validation - WATCH VIA CLOUDFLARE TUNNEL!") |
|
|
|
|
|
logs = [] |
|
|
def log(msg): |
|
|
logger.info(msg) |
|
|
logs.append(msg) |
|
|
|
|
|
email = order_data.get('email', '') |
|
|
phone = order_data.get('phone', '') |
|
|
zip_code = order_data.get('zip', '') |
|
|
city = order_data.get('city', '') |
|
|
state = order_data.get('state', '') |
|
|
task_id = order_data.get('task_id', 'unknown') |
|
|
|
|
|
log(f"π§ Email: {email}") |
|
|
log(f"π Phone: {phone}") |
|
|
log(f"π Geo: {zip_code}, {city}, {state}") |
|
|
log(f"πΊ Display: {os.environ.get('DISPLAY', 'NOT SET')} - VISIBLE MODE!") |
|
|
|
|
|
task = f""" |
|
|
You are a Validation Expert. Perform these 3 steps: |
|
|
|
|
|
STEP 1: EMAIL VALIDATION (Browser) |
|
|
- Go to 'https://email-checker.net/' |
|
|
- Input '{email}' and check result. |
|
|
- Extract: 'Valid', 'Invalid', or 'Risky'. |
|
|
|
|
|
STEP 2: PHONE VALIDATION (Browser) |
|
|
- Use a phone validator tool. |
|
|
- Input '{phone}' and check status. |
|
|
|
|
|
STEP 3: GEO VALIDATION (Internal Knowledge ONLY) |
|
|
- Does Zip '{zip_code}' belong to City '{city}' in State '{state}'? |
|
|
- Return 'Match' or 'Mismatch'. |
|
|
|
|
|
OUTPUT JSON: |
|
|
{{ |
|
|
"email_status": "Valid/Invalid/Risky", |
|
|
"phone_status": "Valid/Invalid", |
|
|
"geo_match": true/false, |
|
|
"summary": "explanation" |
|
|
}} |
|
|
""" |
|
|
|
|
|
api_key = os.getenv("OPENROUTER_API_KEY") |
|
|
base_url = "https://openrouter.ai/api/v1" |
|
|
|
|
|
if not api_key: |
|
|
return {"task_id": task_id, "decision": "UNKNOWN", "error": "No API key", "logs": logs} |
|
|
|
|
|
llm_primary = ChatOpenAI( |
|
|
model="nvidia/nemotron-nano-12b-v2-vl:free", |
|
|
api_key=api_key, |
|
|
base_url=base_url, |
|
|
temperature=0.1, |
|
|
default_headers={"HTTP-Referer": "https://altyzen.com", "X-Title": "Altyzen Stealth Worker"} |
|
|
) |
|
|
|
|
|
llm_fallback = ChatOpenAI( |
|
|
model="google/gemini-2.0-flash-exp:free", |
|
|
api_key=api_key, |
|
|
base_url=base_url, |
|
|
temperature=0.1, |
|
|
default_headers={"HTTP-Referer": "https://altyzen.com", "X-Title": "Altyzen Stealth Worker"} |
|
|
) |
|
|
|
|
|
|
|
|
browser = session.browser if session and session.is_active else Browser(headless=False) |
|
|
owns_browser = session is None or not session.is_active |
|
|
result = None |
|
|
|
|
|
try: |
|
|
log("π€ Attempt 1: Using Nvidia Nemotron...") |
|
|
agent = Agent(task=task, llm=llm_primary, browser=browser, controller=controller, use_vision=True, validate_output=False) |
|
|
history = await agent.run() |
|
|
result = history.final_result() |
|
|
log("β
Nvidia Nemotron completed!") |
|
|
except Exception as e: |
|
|
log(f"β οΈ Primary failed: {str(e)[:100]}") |
|
|
log("π Switching to Gemini fallback...") |
|
|
|
|
|
try: |
|
|
agent = Agent(task=task, llm=llm_fallback, browser=browser, controller=controller, use_vision=True, validate_output=False) |
|
|
history = await agent.run() |
|
|
result = history.final_result() |
|
|
log("β
Gemini completed!") |
|
|
except Exception as fallback_err: |
|
|
log(f"β Fallback also failed: {str(fallback_err)[:100]}") |
|
|
result = None |
|
|
|
|
|
|
|
|
if owns_browser: |
|
|
try: |
|
|
await browser.close() |
|
|
log("π Browser closed") |
|
|
except: |
|
|
pass |
|
|
|
|
|
parsed = _parse_result(result, order_data) |
|
|
parsed["logs"] = logs |
|
|
parsed["task_id"] = task_id |
|
|
return parsed |
|
|
|
|
|
|
|
|
def _parse_result(result, order_data): |
|
|
import json |
|
|
if result is None: |
|
|
return {"decision": "UNKNOWN", "email_valid": False, "phone_valid": False, "geo_valid": False, "reasoning": "All models failed"} |
|
|
|
|
|
parsed = {} |
|
|
if isinstance(result, str): |
|
|
try: |
|
|
if "{" in result: |
|
|
json_start = result.find("{") |
|
|
json_end = result.rfind("}") + 1 |
|
|
parsed = json.loads(result[json_start:json_end]) |
|
|
except: |
|
|
parsed = {"raw": result} |
|
|
elif isinstance(result, dict): |
|
|
parsed = result |
|
|
|
|
|
email_valid = "valid" in str(parsed.get("email_status", "")).lower() and "invalid" not in str(parsed.get("email_status", "")).lower() |
|
|
phone_valid = "valid" in str(parsed.get("phone_status", "")).lower() and "invalid" not in str(parsed.get("phone_status", "")).lower() |
|
|
geo_valid = parsed.get("geo_match", False) if isinstance(parsed.get("geo_match"), bool) else str(parsed.get("geo_match", "")).lower() == "true" |
|
|
|
|
|
decision = "APPROVED" if email_valid and phone_valid and geo_valid else "BLOCKED" |
|
|
|
|
|
return { |
|
|
"order_id": order_data.get("order_id", "UNKNOWN"), |
|
|
"decision": decision, |
|
|
"email_valid": email_valid, |
|
|
"phone_valid": phone_valid, |
|
|
"geo_valid": geo_valid, |
|
|
"reasoning": parsed.get("summary", "Validation completed"), |
|
|
"raw_result": parsed |
|
|
} |
|
|
|