
    .iZ<              	       .   % S r SSKrSSKrSSKrSSKJrJrJrJrJ	r	  SSK
JrJr  SSKJr  \R                  " \5      r " S S\5      r\ " S S	5      5       r\ " S
 S5      5       r " S S5      rSq\\   \S'   S!S\S\S\4S jjrS"S\S\4S jjrS"S\S\S\\\4   4S jjrS\S\\\4   4S jrS\S\S\\\4   4S jrS\\\4   4S jr S\\\4   4S jr!\S:X  a5  \RD                  " \RF                  S9  S  r$\RJ                  " \$" 5       5        gg)#u  
Genesis V2 Browser Controller
==============================
Native browser control via Chrome Extension + WebSocket bridge.

Architecture:
    ADK Agent → BrowserController → WebSocket → Chrome Extension → DOM

This replaces the stub auto_browse_tool with real browser actuation.
The Chrome Extension runs in the user's browser and receives commands
from the Python backend via WebSocket.
    N)DictAnyOptionalCallableList)	dataclassfield)Enumc                   <    \ rS rSrSrSrSrSrSrSr	Sr
S	rS
rSrSrg)
ActionType   z8Browser action types matching Chrome Extension protocol.navigateclicktypescroll
screenshotget_domget_textwait
execute_js N)__name__
__module____qualname____firstlineno____doc__NAVIGATECLICKTYPESCROLL
SCREENSHOTGET_DOMGET_TEXTWAIT
EXECUTE_JS__static_attributes__r       ,E:\genesis-system\genesis_v2\core\browser.pyr   r      s2    BHEDFJGHDJr'   r   c                       \ rS rSr% Sr\\S'   Sr\\	   \S'   Sr
\\	   \S'   Sr\\	   \S'   \" \S9r\\	\4   \S	'   S
\\	\4   4S jrSrg)BrowserAction)   zA browser action to execute.action_typeNselectorvalueurldefault_factorymetadatareturnc                     U R                   R                  U R                  U R                  U R                  S.U R                  E$ )N)r   r-   r.   r/   )r,   r.   r-   r/   r2   selfs    r(   to_dictBrowserAction.to_dict2   s>    $$**ZZ88	

 mm
 	
r'   r   )r   r   r   r   r   r   __annotations__r-   r   strr.   r/   r	   dictr2   r   r   r7   r&   r   r'   r(   r*   r*   )   s`    &"Hhsm"E8C=C#$T:Hd38n:
c3h 
r'   r*   c                       \ rS rSr% Sr\\S'   \\S'   \" \	S9r
\\\4   \S'   Sr\\   \S'   Sr\\   \S	'   \S
\SS 4S j5       rSrg)BrowserResult<   zResult from a browser action.successr,   r0   dataNerrorscreenshot_base64dr3   c           	          U " UR                  SS5      [        UR                  SS5      5      UR                  S0 5      UR                  S5      UR                  S5      S9$ )	Nr?   Fr   r   r@   rA   r   )r?   r,   r@   rA   rB   )getr   )clsrC   s     r(   	from_dictBrowserResult.from_dictE   sU    EE)U+"155#<=vr"%%.eeL1
 	
r'   r   )r   r   r   r   r   boolr9   r   r	   r;   r@   r   r:   r   rA   r   rB   classmethodrG   r&   r   r'   r(   r=   r=   <   sd    'M 6D$sCx.6E8C='+x}+
$ 
? 
 
r'   r=   c                   @   \ rS rSrSr   S S\S\S\4S jjrS\4S jr	S	 r
\S\4S
 j5       rS\S\4S jrS\S\4S jrS\S\S\4S jrS!S\S\S\4S jjrS\4S jrS\4S jrS"S\\   S\4S jjrS#S\S\S\4S jjrS\S\4S jrS\S\4S jrS\S\4S jrSrg)$BrowserControllerT   a  
Native browser controller using Chrome Extension bridge.

This controller sends commands to a Chrome Extension via WebSocket,
which then executes them in the browser context.

For testing/development, it can operate in stub mode without
an actual Chrome Extension connection.
ws_hostws_port	stub_modec                     Xl         X l        X0l        S U l        SU l        [
        R                  " 5       U l        [
        R                  " 5       U l        g )NF)	rN   rO   rP   _ws
_connectedasyncioQueue_action_queue_result_queue)r6   rN   rO   rP   s       r(   __init__BrowserController.__init___   s=     ",3MMO,3MMOr'   r3   c                   #    U R                   (       a  [        R                  S5        SU l        g SSKnSU R
                   SU R                   3nUR                  U5      I Sh  vN U l        SU l        [        R                  SU 35        g N)! [         a"  n[        R                  SU 35         SnAg	SnAff = f7f)
z-Connect to Chrome Extension WebSocket server.z&BrowserController running in STUB modeTr   Nzws://:z!Connected to Chrome Extension at z Failed to connect to extension: F)rP   loggerinforS   
websocketsrN   rO   connectrR   	ExceptionrA   )r6   r^   uries       r(   r_   BrowserController.connectq   s     >>KK@A"DO		$,,q7C'//44DH"DOKK;C5AB 5  	LL;A3?@	s@   /C4B &B'(B CB 
B>B94C9B>>Cc                    #    U R                   (       a"  U R                   R                  5       I Sh  vN   SU l        [        R	                  S5        g N!7f)z!Disconnect from Chrome Extension.NFz"Disconnected from Chrome Extension)rR   closerS   r\   r]   r5   s    r(   
disconnectBrowserController.disconnect   s9     88((.."""89 #s   /AA"Ac                     U R                   $ N)rS   r5   s    r(   is_connectedBrowserController.is_connected   s    r'   r/   c                 p   #    [        [        R                  US9nU R                  U5      I Sh  vN $  N7f)zNavigate to a URL.)r,   r/   N)r*   r   r   _execute)r6   r/   actions      r(   r   BrowserController.navigate   s2     "++
 ]]6****   -646r-   c                 p   #    [        [        R                  US9nU R                  U5      I Sh  vN $  N7f)z!Click an element by CSS selector.r,   r-   N)r*   r   r   rm   r6   r-   rn   s      r(   r   BrowserController.click   s2     "((
 ]]6****rp   textc                 r   #    [        [        R                  UUS9nU R                  U5      I Sh  vN $  N7f)zType text into an element.)r,   r-   r.   N)r*   r   r   rm   )r6   r-   ru   rn   s       r(   	type_textBrowserController.type_text   s3     "

 ]]6****s   .757	directionamountc                 t   #    [        [        R                  XS.S9nU R                  U5      I Sh  vN $  N7f)zScroll the page.)ry   rz   )r,   r2   N)r*   r   r    rm   )r6   ry   rz   rn   s       r(   r   BrowserController.scroll   s5     "))#,?
 ]]6****s   /868c                 n   #    [        [        R                  S9nU R                  U5      I Sh  vN $  N7f)zCapture viewport screenshot.r,   N)r*   r   r!   rm   r6   rn   s     r(   r   BrowserController.screenshot   s*     :+@+@A]]6****   ,535c                 n   #    [        [        R                  S9nU R                  U5      I Sh  vN $  N7f)zGet current page DOM/HTML.r~   N)r*   r   r"   rm   r   s     r(   r   BrowserController.get_dom   s*     :+=+=>]]6****r   Nc                 p   #    [        [        R                  US9nU R                  U5      I Sh  vN $  N7f)z1Get text content (full page or specific element).rr   N)r*   r   r#   rm   rs   s      r(   r   BrowserController.get_text   s2     "++
 ]]6****rp   
timeout_msc                 v   #    [        [        R                  USU0S9nU R                  U5      I Sh  vN $  N7f)zWait for element to appear.timeout)r,   r-   r2   N)r*   r   r$   rm   )r6   r-   r   rn   s       r(   r   BrowserController.wait   s8     ",

 ]]6****s   0979scriptc                 p   #    [        [        R                  US9nU R                  U5      I Sh  vN $  N7f)z#Execute JavaScript in page context.)r,   r.   N)r*   r   r%   rm   )r6   r   rn   s      r(   r   BrowserController.execute_js   s2     "--
 ]]6****rp   rn   c                   #    U R                   (       d  U R                  5       I Sh  vN   U R                  (       a  U R                  U5      $  U R                  R                  [        R                  " UR                  5       5      5      I Sh  vN   [        R                  " U R                  R                  5       SS9I Sh  vN n[        R                  " U5      n[        R                  U5      $  N Nf N3! [        R                   a    [        SUR                   SS9s $ ["         a(  n[        SUR                   [%        U5      S9s SnA$ SnAff = f7f)zExecute a browser action.Ng      >@r   Fz$Timeout waiting for browser response)r?   r,   rA   )rS   r_   rP   _stub_executerR   sendjsondumpsr7   rT   wait_forrecvloadsr=   rG   TimeoutErrorr,   r`   r:   )r6   rn   responseresult_datarb   s        r(   rm   BrowserController._execute   s    ,,.  >>%%f--	((--

6>>+; <=== %-- H
 **X.K **;77! ! > ## 	 "..< 
  	 "..!f 	sp   %EC4&EA C: C64C: C8.C: 3E6C: 8C: :)E#E%	E.EEEEEc                    [         R                  SUR                  R                   35        [        R
                  UR                  SUR                   3SS.[        R                  UR                  SS.[        R                  UR                  UR                  S.[        R                  SS	S
S.[        R                  SSS.[        R                  SUR                  S.[        R                  UR                  R                  SS5      SS.[        R                   UR                  SS.[        R"                  SS00	n[%        SUR                  UR                  UR                  0 5      S9$ )z4Stub execution for testing without Chrome Extension.z[STUB] Browser action: z[STUB] Page at loaded)r/   titlestatusT)r-   clicked)r-   typedpngi  i8  )formatwidthheightz$<html><body>[STUB DOM]</body></html>*   )htmllengthz[STUB] Page text content)ru   r-   ry   down)ry   scrolled)r-   foundresultz[STUB] JS execution result)r?   r,   r@   )r\   r]   r,   r.   r   r   r/   r   r-   r   r!   r"   r#   r    r2   rE   r$   r%   r=   )r6   rn   	stub_datas      r(   r   BrowserController._stub_execute   sW   -f.@.@.F.F-GHI zz*6::,7""
 "OO OO"OO !!$
 >! 2"OO" #__00fE   OO"OO !!6$G&
	P **v1126
 	
r'   )rV   rS   rW   rR   rP   rN   rO   )	localhost="  T)r   i,  ri   )i  )r   r   r   r   r   r:   intrI   rX   r_   rf   propertyrj   r=   r   r   rw   r   r   r   r   r   r   r   r*   rm   r   r&   r   r'   r(   rL   rL   T   s<    #	<< < 	<$t $: d  +# +- ++C +M ++ +3 += ++c +C +- ++- +
+} +
+x} + ++3 +C += ++s +} + ]  }  D0
M 0
m 0
r'   rL   _browserhostportr3   c                     SSK n UR                  X4SS9    SSS5        g! , (       d  f       g= f! [        [        UR                  4 a     gf = f)z0Check if the WebSocket bridge server is running.r   Ng      ?r   TF)socketcreate_connectionConnectionRefusedErrorOSErrorr   )r   r   r   s      r(   _detect_ws_serverr   7  sK    %%tlC%@ A@@"GV^^< s#   3 "3 
03 3 AArP   c                     [         c6  U (       a&  [        5       (       a  [        R                  S5        Sn [	        U S9q [         $ )znGet or create browser controller instance.
Auto-detects real mode if WS bridge server is running on port 8765.z7WS bridge detected on port 8765, switching to real modeFrP   )r   r   r\   r]   rL   r   s    r(   get_browser_controllerr   A  s7     *,,KKQRI$y9Or'   r/   wait_for_loadc                     [        5       n[        R                  " 5       nUR                  UR	                  U 5      5      nUR
                  U UR                  UR                  S.$ )z
Navigate browser to URL.

Args:
    url: Target URL to navigate to
    wait_for_load: Wait for page to fully load
    
Returns:
    Dict with navigation result including page title
)r?   r/   r@   rA   )r   rT   get_event_looprun_until_completer   r?   r@   rA   )r/   r   
controllerloopr   s        r(   browser_navigater   N  sW     ()J!!#D$$Z%8%8%=>F>>	 r'   r-   c                     [        5       n[        R                  " 5       nUR                  UR	                  U 5      5      nUR
                  U UR                  UR                  S.$ )z
Click element by CSS selector.

Args:
    selector: CSS selector of element to click
    
Returns:
    Dict with click result
)r?   r-   r@   rA   )r   rT   r   r   r   r?   r@   rA   )r-   r   r   r   s       r(   browser_clickr   d  sW     ()J!!#D$$Z%5%5h%?@F>>	 r'   ru   c                     [        5       n[        R                  " 5       nUR                  UR	                  X5      5      nUR
                  U UUR                  UR                  S.$ )z
Type text into form field.

Args:
    selector: CSS selector of input element
    text: Text to type
    
Returns:
    Dict with typing result
)r?   r-   ru   r@   rA   )r   rT   r   r   rw   r?   r@   rA   )r-   ru   r   r   r   s        r(   browser_typer   y  sZ     ()J!!#D$$Z%9%9(%IJF>> r'   c                      [        5       n [        R                  " 5       nUR                  U R	                  5       5      nUR
                  UR                  UR                  UR                  S.$ )zd
Capture current viewport screenshot.

Returns:
    Dict with screenshot data (base64 if available)
)r?   r   r@   rA   )	r   rT   r   r   r   r?   rB   r@   rA   r   r   r   s      r(   browser_screenshotr     s[     ()J!!#D$$Z%:%:%<=F>>..	 r'   c                      [        5       n [        R                  " 5       nUR                  U R	                  5       5      nUR
                  UR                  R                  SS5      UR                  UR                  S.$ )zW
Get current page text content for analysis.

Returns:
    Dict with page text content
ru    )r?   ru   r@   rA   )	r   rT   r   r   r   r?   r@   rE   rA   r   s      r(   browser_get_contentr     sd     ()J!!#D$$Z%8%8%:;F>>+	 r'   __main__)levelc                  L  #    [        SS9n U R                  5       I S h  vN   [        S5        [        S5        U R                  S5      I S h  vN n[        SUR                   SUR
                   35        U R                  S5      I S h  vN n[        S	UR                   SUR
                   35        U R                  S
S5      I S h  vN n[        SUR                   SUR
                   35        U R                  5       I S h  vN n[        SUR                   SUR
                   35        U R                  5       I S h  vN n[        SUR                   SUR
                   35        U R                  5       I S h  vN   [        S5        g  GNt GNH GN N N NZ N7f)NTr   u)   
🌐 Browser Controller Test (Stub Mode)z2==================================================zhttps://example.comz
Navigate: z - z#submit-buttonzClick: z#searchz
Genesis V2zType: zScreenshot: z
Get Text: u   
✅ All browser tests passed!)rL   r_   printr   r?   r@   r   rw   r   r   rf   )r   r   s     r(   test_browserr     sp    &6
  """:;h "**+@AA
6>>*#fkk];< "''(899's6;;-89 "++I|DDv~~&c&++78 ",,..V^^,C}=> "**,,
6>>*#fkk];<##%%%/05 	# B : E / - 	&s{   F$F.F$F=F$F>F$F<F$F	<F$F <F$F"F$F$F$F$F$ F$"F$)r   r   )T)&r   rT   r   loggingtypingr   r   r   r   r   dataclassesr   r	   enumr
   	getLoggerr   r\   r   r*   r=   rL   r   r9   r:   r   rI   r   r   r   r   r   r   r   basicConfigINFOr   runr   r'   r(   <module>r      sz      6 6 ( 			8	$
 
 
 
 
$ 
 
 
.X
 X
@ )-($
% ,C S D 	d 	6G 	# d d38n ,C DcN *3 c d38n .DcN $T#s(^ , zgll+1< KKC r'   