
    Poi(                         d Z ddlmZmZmZ ddlZddlmZ ddlmZ ddl	m
Z
 ddlmZmZ ddlmZ dd	lmZ  G d
 dee
          ZdS )a.  
Browser Navigator Hub for Browser Operations

This module provides the BrowserNavigator class that serves as a central orchestrator
for all browser operations, hosting core browser management while providing access
to specialized/scripted operations through primitive operations and executor methods.
    )OptionalDictAnyN)datetime)BrowserContext)PersistentBrowserBase)IntelligentPagePoolManagedPage)PrimitiveBrowserOps)llmc            	       6    e Zd ZdZddededef fdZdd	ee         d
efdZ	e
ddededefd            Z fdZd Zd
ee         fdZd
ee         fdZdd	ee         d
eeef         fdZd	ed
eeef         fdZdded	ee         d
eeef         fdZ xZS )BrowserNavigatoraI  
    Central hub for all browser operations.
    
    The BrowserNavigator consolidates browser management and provides primitive operations
    for scraping and fingerprinting. It serves as the main entry point for all browser
    automation tasks while maintaining a shared browser context and page pool.
    
    Core Responsibilities:
    - Browser context lifecycle management (initialize, maintain, cleanup)
    - Page pool management and coordination
    - Providing factory methods for specialized operations
    - Exposing primitive/atomic operations for custom workflows
         user_data_dirslowmo	max_pagesc                     t                                          ||           || _        d| _        t	          d           t	          d|            t	          d| d           t	          d|            dS )a  
        Initialize the BrowserNavigator with full browser setup.
        
        Args:
            user_data_dir (str): Path to Firefox profile directory for persistence
            slowmo (int): Delay in milliseconds between browser actions (default: 500)
        Nu    🧭 BrowserNavigator configuredu   📁 Profile directory:    ⏱️  Slowmo delay: ms   📄 Max pages: )super__init__r   
_page_poolprint)selfr   r   r   	__class__s       :/home/byschii/byschiidev/penelope/lib/browser_navigator.pyr   zBrowserNavigator.__init__$   s     	///"9=12228889991v111222,,,-----    Npage_idreturnc                   K   | j         st          d          |r5| j         j                            |          }|st          d| d          n2| j                             d           d{V }|st          d          |S )z
        Helper method to get a managed page to use.

        Args:
            page_id (str, optional): Specific page ID to use, or None for any available page

        Returns:
            ManagedPage: The managed page to use
        Page pool not initializedzPage z
 not found   )wait_timeoutNzNo pages available)r   	Exceptionpagesgetget_available_page)r   r    managed_pages      r   _get_page_to_usez!BrowserNavigator._get_page_to_use6   s        	97888  	6?044W==L = ; ; ; ;<<<= "&!C!CQS!C!T!TTTTTTTL 6 4555r     browser_contextc                 $  K   |                      |           }d|_        ||_        ||_        d|_        ||_        d|_        |                                 d{V  t          d           t          d| d           t          d|            |S )a  
        Create BrowserNavigator from an existing browser context.
        
        Args:
            browser_context (BrowserContext): Existing Playwright browser context
            slowmo (int): Delay in milliseconds between browser actions (default: 1000)
            max_pages (int): Maximum number of pages in the pool (default: 3)
            
        Returns:
            BrowserNavigator: Instance using the shared browser context
        external_contextNu7   🧭 BrowserNavigator initialized from existing contextr   r   r   )	__new__r   r   r   
playwrightr-   r   _initialize_page_poolr   )clsr-   r   r   instances        r   from_existing_contextz&BrowserNavigator.from_existing_contextO   s       ;;s## "4 &"#2 " ,,.........HIII1v111222,,,---r   c                    K   t                                                       d{V  |                                  d{V  dS )z-Initialize the browser context and page pool.N)r   
initializer2   )r   r   s    r   r7   zBrowserNavigator.initializep   s]       gg  """"""""" ((***********r   c                    K   | j         st          d          t          | j         | j                  | _        | j                            d           d{V  t          d| j         d           dS )z9Initialize the page pool with the active browser context.z4Browser context must be initialized before page pool)r-   r      )initial_pagesNu   ✅ Page pool initialized with z
 max pages)r-   r&   r	   r   r   r7   r   r   s    r   r2   z&BrowserNavigator._initialize_page_poolx   s      # 	TRSSS- 0n
 
 
 o((q(999999999JJJJKKKKKr   c                     | j         S )z Get the current browser context.)r-   r;   s    r   get_browser_contextz$BrowserNavigator.get_browser_context   s    ##r   c                     | j         S )zGet the current page pool.)r   r;   s    r   get_page_poolzBrowserNavigator.get_page_pool   s
    r   c                   K   | j         sddiS 	 t          d|pd            | j                             |           d{V }d|j        d|j         d|j        j        |j        j        t          | j         j	                  d	}t          d
|j                    |S # t          $ r2}dt          |           }t          d|            d|icY d}~S d}~ww xY w)z
        Create a new page/tab in the browser.

        Args:
            page_id (str, optional): Custom page ID. If None, auto-generated ID will be used.

        Returns:
            Dict[str, Any]: Result containing page information
        errorr#   u    🆕 Creating new page with ID: zauto-generatedNTPage 'z' created successfully)successr    messageurlstatetotal_pagesu   ✅ Page created successfully: zFailed to create page:    ❌ )r   r   create_pager    pagerE   rF   valuelenr'   r&   strr   r    r*   resulte	error_msgs         r   rI   zBrowserNavigator.create_page   s5       	:899	(RW5P@PRRSSS!%!<!<W!E!EEEEEEEL  '/PL$8PPP#(,%+1"4?#899 F JL4HJJKKKM 	( 	( 	(:#a&&::I$$$%%%Y'''''''	(s   BB 
C('CCCc                   K   | j         sddiS 	 t          d|            || j         j        vrdd| diS | j         j        |         }|j                                         d{V  | j         j        |= d|d| dt          | j         j                  d	}t          d
|            |S # t          $ r2}dt          |           }t          d|            d|icY d}~S d}~ww xY w)z
        Destroy/close a page/tab in the browser.

        Args:
            page_id (str): ID of the page to destroy

        Returns:
            Dict[str, Any]: Result containing destruction status
        rA   r#   u!   🗑️ Destroying page with ID: rB   z' not foundNTz' destroyed successfully)rC   r    rD   rG   u!   ✅ Page destroyed successfully: zFailed to destroy page: rH   )r   r   r'   rJ   closerL   r&   rM   rN   s         r   destroy_pagezBrowserNavigator.destroy_page   s]       	:899	(?g??@@@ do333!>'!>!>!>???09L #))+++++++++ %g.  "EGEEE"4?#899	 F ?g??@@@M 	( 	( 	(;3q66;;I$$$%%%Y'''''''	(s#   'B+ A3B+ +
C'5'C"C'"C'descriptionc           
      d  K   t          j                    }|                     |           d{V }	 |                    d|            d{V  t	          d|            t	          d           |j                                         d{V }t          j        |          	                    d          }t	          d           t          j        ||          }t          j                    }||z
                                  }	t	          d|j         d	|j                    d
||j        |j        |j        d         |j        d         |                                |                                |	d	|                                 d{V  S # t&          $ rw}
t	          d|
            |                    t+          |
                     d{V  d||j        t+          |
          dcY d}
~
|                                 d{V  S d}
~
ww xY w# |                                 d{V  w xY w)ai  
        Search for an object on the page based on description using vision AI.

        Args:
            description (str): Description of the object to search for
            page_id (str, optional): Specific page ID to use, or None for any available page

        Returns:
            Dict containing search result with bounding box and coordinates
        Nzsearching for object: u   🔍 Searching for object: u   📸 Taking screenshotzutf-8u   🤖 Calling Gemini vision API)object_descriptionimage_base64u   ✅ Object found at center: z, bounding box: Txy)	rC   rU   r    bounding_boxcenter_xcenter_ytokens_used	costs_usdduration_secondsu   ❌ Object search failed: F)rC   rU   r    rA   )r   nowr+   set_busyr   rJ   
screenshotbase64	b64encodedecoder   detect_bounding_boxestotal_secondscenterr[   r    token_total
cost_totalset_idler&   	set_errorrM   )r   rU   r    
start_timer*   screenshot_bytesscreenshot_base64rO   end_timedurationrP   s              r   do_search_objectz!BrowserNavigator.do_search_object   s      \^^
!227;;;;;;;;.	*''(N(N(NOOOOOOOOO===>>> *+++%1%6%A%A%C%CCCCCCC & 01A B B I I' R R 2333.#..  F  |~~H :-<<>>HeeePVPceefff*'/ & 3"M#."M#.%1133#..00$,
 
. ''))))))))))  	 	 	2q22333((Q000000000 *'/Q	       ''))))))))))	 ''))))))))))s1   EF 
HAH+H,H HH H/)r   r   )N)r,   r   )__name__
__module____qualname____doc__rM   intr   r   r
   r+   classmethodr   r5   r7   r2   r=   r	   r?   r   r   rI   rT   rs   __classcell__)r   s   @r   r   r      s        . .c .3 . . . . . . .$ hsm {    2  . RU il    [@+ + + + +L L L$Xn%= $ $ $ $x(;<     (  (#  ($sCx.  (  (  (  (D)(# )($sCx. )( )( )( )(V<* <*# <* <*Y]^acf^fYg <* <* <* <* <* <* <* <*r   r   )rw   typingr   r   r   rd   r   patchright.async_apir   lib.browser_baser   lib.page_managementr	   r
   lib.browser_primitivesr   r   r    r   r   <module>r      s     ' & & & & & & & & &        0 0 0 0 0 0 2 2 2 2 2 2 @ @ @ @ @ @ @ @ 6 6 6 6 6 6      C* C* C* C* C**,A C* C* C* C* C*r   