
    4i1                     f   d Z ddlZddlZddlZddlZddlZddlmZ ddlmZ  ed      Z	ej                  j                  d ee	             e	dz  dz  Ze	dz  dz  Ze	dz  d	z  ZeeefD ]  Zej#                  d
d
         ee	dz  dz  dz  dz  dz        Zeej&                  j)                  dd      vr.e dej&                  j)                  dd       ej&                  d<   defdZ G d d      Zd"dededefdZdedefdZdededefdZd  Zed!k(  r ej<                   e              yy)#uX  
GenesisBrowserAgent — Layer 2 Autonomous Browser Agent
Powered by browser-use + Gemini Flash for multi-step browser automation.

Architecture:
  Layer 1 — Playwright MCP (Claude Code native, $0, simple tasks)
  Layer 2 — THIS FILE (browser-use + Gemini Flash, ~$0.005/task, autonomous)
  Layer 3 — Gemini Computer Use (visual fallback, ~$0.01/step, canvas UIs)

Usage:
  from core.browser_agent import GenesisBrowserAgent, run_browser_task
  result = asyncio.run(agent.execute_task("Extract pricing from synthflow.ai/pricing"))

Security:
  - Credentials NEVER hardcoded — loaded from config/secrets.env
  - Session cookies stored at data/browser_sessions/[service].json
  - Screenshots saved to data/screenshots/ as evidence
  - Approved targets defined in BROWSER_USE_MASTERY skill

Author: Genesis Gold Browser Use Team Lead
Date: 2026-02-20
    N)datetime)Pathz/mnt/e/genesis-systemdatabrowser_outputbrowser_sessionsscreenshotsT)parentsexist_okz.venvszplaywright-libsusrlibzx86_64-linux-gnuLD_LIBRARY_PATH :returnc                     t         j                  j                  d      xs t         j                  j                  d      } | st        dz  dz  }|j	                         r}|j                         j                         D ]\  }|j                  d      s|j                  d      s&|j                  dd      d   j                         } | t         j                  d<    n | xs d	S )
z5Load Google API key from environment or secrets file.GOOGLE_API_KEYGEMINI_API_KEYconfigzsecrets.envzGOOGLE_API_KEY=zGEMINI_API_KEY==   r   )
osenvirongetGENESIS_ROOTexists	read_text
splitlines
startswithsplitstrip)keysecrets_pathlines      +/mnt/e/genesis-system/core/browser_agent.py_load_google_api_keyr%   3   s    
**..)
*
Nbjjnn=M.NC#h.> $..0;;= ??#45IZ9[**S!,Q/557C36BJJ/0	
 9"    c                       e Zd ZdZddededefdZd Zdded	ed
e	fdZ
ded
e	fdZdeded
e	fdZdede	d
e	fdZdededed
e	fdZdeded
e	fdZy)GenesisBrowserAgenta  
    Autonomous browser agent powered by browser-use + Gemini Flash.

    Claude orchestrates (plans and synthesises).
    Gemini Flash executes (100x cheaper than Claude for browser actions).

    Example:
        agent = GenesisBrowserAgent()
        result = asyncio.run(agent.execute_task(
            "Go to synthflow.ai/pricing and extract all pricing tiers as JSON"
        ))
    model	max_stepsheadlessc                 z    || _         || _        || _        t               | _        | j                  st        d      y )NzBGOOGLE_API_KEY not found. Set in environment or config/secrets.env)r)   r*   r+   r%   api_key
ValueError)selfr)   r*   r+   s       r$   __init__zGenesisBrowserAgent.__init__O   s=    
" +-||T  r&   c                 L    ddl m}  || j                  | j                  d      S )z
        Build Gemini LLM for browser-use.

        browser-use 0.11.9 uses its own native LLM classes (not langchain).
        Use browser_use.llm.google.chat.ChatGoogle for Gemini integration.
        r   )
ChatGoogleg?)r)   r-   temperature)browser_use.llm.google.chatr2   r)   r-   )r/   r2   s     r$   
_build_llmzGenesisBrowserAgent._build_llmZ   s%     	;**LL
 	
r&   Ntasktask_idr   c           
        K   ddl m} ddlm}m} |s#t        j                         j                  d      }t        d|        t        d|dd  d	       t        j                         }d
}d}d}		 | j                         }
 || j                  g d      } |||
 ||      | j                        }|j                          d{   }t        |      }d}t        dt        j                         |z
  dd       ||||	|| j                   t#        t        j                         |z
  d      t        j                         j%                         d}t&        | dz  }|j)                  t+        j,                  |d             t        |      |d<   t        d|        |S 7 # t        $ r#}t        |      }	t        d|        Y d}~d}~ww xY ww)a`  
        Execute a natural language browser task autonomously.

        Args:
            task: Natural language description of what to do in the browser
            task_id: Optional ID for output file naming (auto-generated if not provided)

        Returns:
            dict with keys: task_id, task, result, timestamp, success, output_path
        r   )Agent)BrowserProfileBrowserSession%Y%m%d_%H%M%Sz[BrowserAgent] Starting task: z[BrowserAgent] Task: Nd   z...Fr   )z--no-sandboxz--disable-dev-shm-usagez--disable-gpu)r+   args)browser_profile)r6   llmbrowser_sessionr*   Tz![BrowserAgent] Task completed in z.1fsz[BrowserAgent] Task failed: r   )r7   r6   resulterrorsuccessr)   duration_seconds	timestampz.json   indentoutput_pathz[BrowserAgent] Output saved: )browser_user9   browser_use.browserr:   r;   r   nowstrftimeprinttimer5   r+   r*   runstr	Exceptionr)   round	isoformat
OUTPUT_DIR
write_textjsondumps)r/   r6   r7   r9   r:   r;   
start_timerE   result_text
error_textr@   r?   agentrC   eoutputrK   s                    r$   execute_taskz GenesisBrowserAgent.execute_taskh   s     	&Flln--o>G.wi89%d4Cj\56YY[

	6//#C,O  . O..	E !99;&Ff+KG5diikJ6Ns5SSTUV !ZZ %diikJ&> B!113	
 !gYe#44tzz&;< #K 0}-k];<3 '
  	6QJ0455	6sD   A.G1AF$ F"6F$ >B$G"F$ $	G-GGGGurlc                    K   |j                  dd      j                  dd      dd }d| d}| j                  |d| 	       d{   S 7 w)
z
        Extract pricing tiers from a URL as structured JSON.

        Returns JSON with keys: tiers (list of {name, price, billing_period, features})
        z://_/N(   Go to ao   and extract ALL pricing tiers, prices, billing periods, and features. Return as a JSON object with key 'tiers' containing a list of objects, each with: name (tier name), price (number or 'custom'), currency, billing_period ('monthly' or 'annual'), features (list of strings). If pricing is 'Contact us' or 'Custom', note that. Include all plans including free tiers.pricing_r7   )replacera   )r/   rb   safe_urlr6   s       r$   scrape_pricingz"GenesisBrowserAgent.scrape_pricing   sg      ;;uc*223<SbASE 6 7 	 &&txz5J&KKKKs   AAAAcompetitorstopicc                    K   dj                  |      }d| d| d}dt        j                         j                  d       }| j	                  ||       d{   S 7 w)	z|
        Research multiple competitor sites on a given topic.

        Returns JSON array with one object per site.
        z, zVisit each of these URLs: z. For each site, extract: zS. Return as a JSON array with one object per site, each with 'url' and 'data' keys.competitor_research_r<   ri   N)joinr   rN   rO   ra   )r/   rm   rn   urls_strr6   r7   s         r$   research_competitorsz(GenesisBrowserAgent.research_competitors   sr      99[)(
 3'',g ./0 	 ))@)@)Q(RS&&tW&====s   AA AA 	form_datac           	        K   dj                  |j                         D cg c]  \  }}| d|  c}}      }d| d| d}dt        j                         j	                  d       }| j                  ||       d	{   S c c}}w 7 
w)
z
        Navigate to a URL, fill a form with provided data, and submit it.

        Returns dict with success status and confirmation message.
        z; z: rg   z&. Fill in the form with these values: z_. Submit the form. Report whether submission was successful and any confirmation message shown.form_r<   ri   N)rq   itemsr   rN   rO   ra   )r/   rb   rt   kv
fields_strr6   r7   s           r$   fill_and_submit_formz(GenesisBrowserAgent.fill_and_submit_form   s      YY	8IJ11#RsJK
SE 33=, ?[\ 	 (,,.11/BCD&&tW&===  K >s   BB
AB?B
 Bcategorylocationc                    K   d| d| d}d| d| dt        j                         j                  d       }| j                  ||       d{   S 7 w)	z
        Scrape business leads from a directory page.

        Returns JSON array of businesses with: name, phone, website, address
        rg   z. Find all z businesses listed on the page. For each business extract: business_name, phone_number, website_url, address. Return as JSON array. Include as many businesses as visible on the page.leads_rd   r<   ri   Nr   rN   rO   ra   )r/   rb   r|   r}   r6   r7   s         r$   scrape_directory_leadsz*GenesisBrowserAgent.scrape_directory_leads   sr      SE  z "WX 	 8*AhZq1H1H1Y0Z[&&tW&====s   AAAAextraction_specc                    K   d| d| d}dt        j                         j                  d       }| j                  ||       d{   S 7 w)z
        Generic page data extraction with custom spec.

        Args:
            url: Target URL
            extraction_spec: Natural language description of what to extract
        rg   z. Extract: z%. Return the data as structured JSON.extract_r<   ri   Nr   )r/   rb   r   r6   r7   s        r$   extract_page_dataz%GenesisBrowserAgent.extract_page_data   sX      uK'88]^X\\^44_EFG&&tW&====s   AAA	A)gemini-2.5-flash   T)N)__name__
__module____qualname____doc__rS   intboolr0   r5   dictra   rl   listrs   r{   r   r    r&   r$   r(   r(   A   s    	c 	3 	W[ 	
Es ES ED ENL L L">d >3 >4 > >c >d >t > > >s >c >VZ >
>3 
> 
> 
>r&   r(   r6   r)   c                 b    t        |      }t        j                  |j                  |             S )z
    Synchronous wrapper for executing a browser task.
    Use this when you need to call from synchronous code.

    Example:
        result = run_browser_task("Go to google.com and search for AI voice agents")
    r)   )r(   asynciorR   ra   )r6   r)   r^   s      r$   run_browser_taskr      s(      e,E;;u))$/00r&   rb   c                 ^    t               }t        j                  |j                  |             S )zSynchronous pricing scraper.)r(   r   rR   rl   )rb   r^   s     r$   scrape_pricing_syncr   
  s$    !E;;u++C011r&   rm   rn   c                 `    t               }t        j                  |j                  | |            S )z Synchronous competitor research.)r(   r   rR   rs   )rm   rn   r^   s      r$   research_competitors_syncr     s&    !E;;u11+uEFFr&   c                     ddl } | j                  d      }|j                  dt        d       |j                  dt        d	       |j                  d
g dd       |j                  ddd       |j	                         }t        |j                        }|j                  dk(  r;|j                  r/t        j                  |j                  |j                              }n|j                  dk(  rM|j                  rA|j                  j                  d      }t        j                  |j                  |d            }nj|j                  r/t        j                  |j                  |j                              }n/t!        d       t        j                  |j                  d            }t!        d       t!        t#        j$                  |d             |j'                  d      rdS dS )z,CLI interface for the Genesis Browser Agent.r   Nu<   Genesis Browser Agent — Layer 2 Autonomous Browser Control)descriptionz--taskz Natural language task to execute)typehelpz--urlz URL for pricing/extraction tasksz--mode)r6   pricingrm   r6   )choicesdefaultz--modelr   zGemini model to use)r   r   r   r   rm   ,zpricing and key featuresz*[GenesisBrowserAgent] Running demo task...zINavigate to example.com and tell me the page title and main heading text.z	
[RESULT]rH   rI   rE   r   )argparseArgumentParseradd_argumentrS   
parse_argsr(   r)   moderb   r   rR   rl   r   rs   r6   ra   rP   rY   rZ   r   )r   parserr>   r^   rC   urlss         r$   mainr     s~   $$1o$pF
s1ST
c0RS
*LV\]
	+=DYZDdjj1EyyI$((U11$((;<	m	#xx~~c"U77>XYZ	U//		:; 	:;U//W
  
,	$**VA
&'

9%1,1,r&   __main__)r   )r   r   rY   r   sysrQ   r   pathlibr   r   pathinsertrS   rW   SESSION_DIRSCREENSHOT_DIRdmkdir	LIBS_PATHr   r   r%   r(   r   r   r   r   r   r   r   exitr   r&   r$   <module>r      s  .   	 
    +, 3|$ % F"%55
V#&88&6
k>	2 )AGGD4G() x'*;;eCeKN``a	BJJNN#4b99'0k2::>>BSUW3X2Y$ZBJJ !c x> x>z	13 	1s 	1D 	12S 2T 2G4 G G G-@ zCHHTV r&   