Ë
    uPêj&5  ã                   óÂ   — U d dl Z d dlZd dlZd dlmZ d dlmZmZ d dlZd dlm	Z	 d dl
mZ ddlmZmZmZmZmZ dZeed	<   d
Zeed<   dZeed<   dZeed<    G d„ d«      Zy)é    N)Údatetime)ÚAnyÚFinal)Úverbose_logger)Ú_get_httpx_clienté   )ÚAPIKeyExpiredErrorÚGetAccessTokenErrorÚGetAPIKeyErrorÚGetDeviceCodeErrorÚRefreshAPIKeyErrorzIv1.b507a08c87ecfe98ÚDEFAULT_GITHUB_CLIENT_IDz$https://github.com/login/device/codeÚDEFAULT_GITHUB_DEVICE_CODE_URLz+https://github.com/login/oauth/access_tokenÚDEFAULT_GITHUB_ACCESS_TOKEN_URLz0https://api.github.com/copilot_internal/v2/tokenÚDEFAULT_GITHUB_API_KEY_URLc                   ó°   — e Zd Zdd„Zdefd„Zdefd„Zdedz  fd„Zdeee	f   fd„Z
dd„Zdd	edz  deeef   fd
„Zdeeef   fd„Zdedefd„Zdefd„Zy)ÚAuthenticatorÚreturnNc                 ó   — t        j                  dt         j                  j                  d«      «      | _        t         j                  j                  | j                  t        j                  dd«      «      | _        t         j                  j                  | j                  t        j                  dd«      «      | _        | j                  «        y)zJInitialize the GitHub Copilot authenticator with configurable token paths.ÚGITHUB_COPILOT_TOKEN_DIRz ~/.config/litellm/github_copilotÚ GITHUB_COPILOT_ACCESS_TOKEN_FILEzaccess-tokenÚGITHUB_COPILOT_API_KEY_FILEzapi-key.jsonN)	ÚosÚgetenvÚpathÚ
expanduserÚ	token_dirÚjoinÚaccess_token_fileÚapi_key_fileÚ_ensure_token_dir©Úselfs    ún/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/llms/github_copilot/authenticator.pyÚ__init__zAuthenticator.__init__   s�   € ô Ÿ™Ø&Ü�G‰G×ÑÐAÓBó
ˆŒô "$§¡§¡Ø�N‰NÜ�I‰IÐ8¸.ÓIó"
ˆÔô ŸG™GŸL™L¨¯©¼¿¹ÐC`ÐbpÓ9qÓrˆÔØ×ÑÕ ó    c                 óÈ  — 	 t        | j                  d«      5 }|j                  «       j                  «       }|r|cddd«       S 	 ddd«       t        d«      D ]`  }t        j                  d|dz   «       	 | j                  «       }	 t        | j                  d«      5 }|j                  |«       ddd«       |c S  t        d
d¬«      ‚# 1 sw Y   Œ„xY w# t        $ r t        j                  d«       Y Œ§w xY w# 1 sw Y   ŒKxY w# t        $ r t        j                  d«       Y Œnw xY w# t        t        t        f$ r%}t        j                  d	|dz   |«       Y d}~�Œd}~ww xY w)z×
        Login to Copilot with retry 3 times.

        Returns:
            str: The GitHub access token.

        Raises:
            GetAccessTokenError: If unable to obtain an access token after retries.
        ÚrNz4No existing access token found or error reading fileé   z%Access token acquisition attempt %s/3r   Úwz!Error saving access token to filezFailed attempt %s: %sz+Failed to get access token after 3 attemptsé‘  ©ÚmessageÚstatus_code)Úopenr   ÚreadÚstripÚOSErrorr   ÚwarningÚrangeÚdebugÚ_loginÚwriteÚerrorr   r
   r   )r#   ÚfÚaccess_tokenÚattemptÚes        r$   Úget_access_tokenzAuthenticator.get_access_token*   sY  € ð	[Ü�d×,Ñ,¨cÓ2ð (°aØ Ÿv™v›xŸ~™~Ó/�ÙØ'÷(ñ (à÷(ô ˜Q“xò 	ˆGÜ× Ñ Ð!HÈ'ÐTUÉ+ÔVð
Ø#Ÿ{™{›}�ðNÜ˜d×4Ñ4°cÓ:ð .¸aØŸ™ Ô-÷.ð $Ò#ð	ô "ØAØô
ð 	
÷+(ð (ûô ò 	[Ü×"Ñ"Ð#YÖZð	[ú÷.ð .ûäò NÜ"×(Ñ(Ð)LÖMðNûô 'Ô(;Ô=OÐPò Ü×&Ñ&Ð'>ÀÈ!ÁÈQÔOÝûðús�   ‚C ˜"Cº	C ÁC Á5D(ÂDÂC8Â.DÂ6D(ÃCÃC ÃC5Ã4C5Ã8D	Ã=DÄD%Ä"D(Ä$D%Ä%D(Ä(E!Ä<EÅE!c                 ó²  — 	 t        | j                  d«      5 }t        j                  |«      }|j	                  dd«      t        j                  «       j                  «       kD  r|j	                  d«      cddd«       S t        j                  d«       t        dd¬	«      ‚# 1 sw Y   nxY wne# t        $ r t        j                  d
«       Y nEt        j                  t        f$ r }t        j                  d|«       Y d}~nd}~wt        $ r Y nw xY w	 | j                  «       }t        | j                  d«      5 }t        j                  ||«       ddd«       n# 1 sw Y   nxY w|j	                  d«      }|r|S t!        dd¬	«      ‚# t        $ r+}t        j"                  d|«       t!        d|› �d¬	«      ‚d}~wt$        $ r}t!        d|› �d¬	«      ‚d}~ww xY w)zÇ
        Get the API key, refreshing if necessary.

        Returns:
            str: The GitHub Copilot API key.

        Raises:
            GetAPIKeyError: If unable to obtain an API key.
        r(   Ú
expires_atr   ÚtokenNzAPI key expired, refreshingzAPI key expiredr+   r,   z+No API key file found or error opening filez#Error reading API key from file: %sr*   zAPI key response missing tokenz Error saving API key to file: %szFailed to save API key: iô  zFailed to refresh API key: )r/   r    ÚjsonÚloadÚgetr   ÚnowÚ	timestampr   r3   r	   r2   ÚJSONDecodeErrorÚKeyErrorÚ_refresh_api_keyÚdumpr   r8   r   )r#   r9   Úapi_key_infor<   r@   s        r$   Úget_api_keyzAuthenticator.get_api_keyO   sÅ  € ð	Ü�d×'Ñ'¨Ó-ð 	°Ü#Ÿy™y¨›|�Ø×#Ñ# L°!Ó4´x·|±|³~×7OÑ7OÓ7QÒQØ'×+Ñ+¨GÓ4÷	ñ 	ô
 #×*Ñ*Ð+HÔIÜ,Ø 1Ø$'ôð ÷	ð 	úð 	øô ò 	RÜ×"Ñ"Ð#PÖQÜ×$Ñ$¤hÐ/ò 	MÜ×"Ñ"Ð#HÈ!×LÑLûÜ!ò 	Ùð	úð	Ø×0Ñ0Ó2ˆLÜ�d×'Ñ'¨Ó-ð +°Ü—	‘	˜,¨Ô*÷+÷ +ñ +úà'×+Ñ+¨GÓ4ˆEÙØ�ä$Ø<Ø #ôð øô ò 	Ü× Ñ Ð!CÀQÔGÜ Ø2°1°#Ð6Øôð ûô "ò 	Ü Ø5°a°SÐ9Øôð ûð	úsƒ   ‚B, ˜ABÁ3	B, Á="BÂB(Â$B, Â,DÃDÃ$C?Ã?DÄDÄ&F Ä8EÅ	F ÅE!ÅF Å9F Æ	GÆ&F5Æ5GÇGÇGc                 óR  — 	 t        | j                  d«      5 }t        j                  |«      }|j	                  di «      }|j	                  d«      }|cddd«       S # 1 sw Y   yxY w# t
        t        j                  t        f$ r }t        j                  d|«       Y d}~yd}~ww xY w)z¦
        Get the API endpoint from the api-key.json file.

        Returns:
            Optional[str]: The GitHub Copilot API endpoint, or None if not found.
        r(   Ú	endpointsÚapiNz(Error reading API endpoint from file: %s)
r/   r    rA   rB   rC   r2   rF   rG   r   r3   )r#   r9   rJ   rM   Úapi_endpointr<   s         r$   Úget_api_basezAuthenticator.get_api_baseƒ   s�   € ð	Ü�d×'Ñ'¨Ó-ð $°Ü&*§i¡i°£l�Ø#/×#3Ñ#3°KÀÓ#D�	Ø&/§m¡m°EÓ&:�Ø#÷	$÷ $ò $ûô
 œ×-Ñ-¬xÐ8ò 	Ü×"Ñ"Ð#MÈqÔQÜûð	ús4   ‚A( ˜:AÁ	A( ÁA%Á!A( Á%A( Á(B&ÂB!Â!B&c                 ó2  — | j                  «       }| j                  |«      }t        j                  dt        «      }d}t        |«      D ]^  }	 t        «       }|j                  ||¬«      }|j                  «        |j                  «       }d|v r|c S t        j                  d|«       Œ` t!        d
d¬«      ‚# t        j                  $ r%}	t        j                  d|dz   ||	«       Y d}	~	Œ¡d}	~	wt        $ r }	t        j                  d	|	«       Y d}	~	ŒÈd}	~	ww xY w)zö
        Refresh the API key using the access token.

        Returns:
            Dict[str, Any]: The API key information including token and expiration.

        Raises:
            RefreshAPIKeyError: If unable to refresh the API key.
        ÚGITHUB_COPILOT_API_KEY_URLr)   )Úheadersr@   z"API key response missing token: %sz1HTTP error refreshing API key (attempt %s/%s): %sr   Nz'Unexpected error refreshing API key: %sz/Failed to refresh API key after maximum retriesr+   r,   )r=   Ú_get_github_headersr   r   r   r4   r   rC   Úraise_for_statusrA   r   r3   ÚhttpxÚHTTPStatusErrorr8   Ú	Exceptionr   )
r#   r:   rS   Úapi_key_urlÚmax_retriesr;   Úsync_clientÚresponseÚresponse_jsonr<   s
             r$   rH   zAuthenticator._refresh_api_key”   s  € ð #×3Ñ3Ó5ˆØ×1Ñ1°,Ó?ˆÜŸY™YÐ'CÔE_Ó`ˆàˆÜ˜[Ó)ò 	SˆGðSÜ/Ó1�Ø&Ÿ?™?¨;À˜?ÓH�Ø×)Ñ)Ô+à (§¡£�à˜mÑ+Ø(Ò(ä"×*Ñ*Ð+OÐQ^Õ_ð	Sô" !ØEØô
ð 	
øô ×(Ñ(ò wÜ×$Ñ$Ð%XÐZaÐdeÑZeÐgrÐtu×vÑvûÜò SÜ×$Ñ$Ð%NÐPQ×RÑRûðSús+   ÁAB7ÂB7Â7DÃ
C*Ã*DÃ6DÄDc                 óš   — t         j                  j                  | j                  «      s"t        j                  | j                  d¬«       yy)z"Ensure the token directory exists.T)Úexist_okN)r   r   Úexistsr   Úmakedirsr"   s    r$   r!   zAuthenticator._ensure_token_dir¹   s-   € ä�w‰w�~‰~˜dŸn™nÔ-Ü�K‰K˜Ÿ™°Ö6ð .r&   r:   c                 ó<   — ddddddœ}|rd|› �|d<   d	|vrd|d	<   |S )
zí
        Generate standard GitHub headers for API requests.

        Args:
            access_token: Optional access token to include in the headers.

        Returns:
            Dict[str, str]: Headers for GitHub API requests.
        zapplication/jsonzvscode/1.85.1zcopilot/1.155.0zGithubCopilot/1.155.0zgzip,deflate,br)Úacceptzeditor-versionzeditor-plugin-versionz
user-agentzaccept-encodingztoken Úauthorizationzcontent-type© )r#   r:   rS   s      r$   rT   z!Authenticator._get_github_headers¾   sG   € ð )Ø-Ø%6Ø1Ø0ñ
ˆñ Ø)/°¨~Ð'>ˆG�OÑ$à Ñ(Ø&8ˆG�NÑ#àˆr&   c                 óä  ‡— 	 t        «       }t        j                  dt        «      }t        j                  dt        «      }|j                  || j                  «       |ddœ¬«      }|j                  «        |j                  «       Šg d¢}t        ˆfd„|D «       «      s#t        j                  d‰«       t        d	d
¬«      ‚‰S # t        j                  $ r+}t        j                  d|«       t        d|› �d
¬«      ‚d}~wt        j                  $ r+}t        j                  d|«       t        d|› �d
¬«      ‚d}~wt         $ r+}t        j                  d|«       t        d|› �d
¬«      ‚d}~ww xY w)zÖ
        Get a device code for GitHub authentication.

        Returns:
            Dict[str, str]: Device code information.

        Raises:
            GetDeviceCodeError: If unable to get a device code.
        ÚGITHUB_COPILOT_DEVICE_CODE_URLÚGITHUB_COPILOT_CLIENT_IDz	read:user)Ú	client_idÚscope©rS   rA   )Údevice_codeÚ	user_codeÚverification_uric              3   ó&   •K  — | ]  }|‰v –— Œ
 y ­w©Nre   )Ú.0ÚfieldÚ	resp_jsons     €r$   ú	<genexpr>z1Authenticator._get_device_code.<locals>.<genexpr>ï   s   øè ø€ ÒG¨e�u 	Ô)ÑGùs   ƒz$Response missing required fields: %sz Response missing required fieldsé�  r,   z"HTTP error getting device code: %szFailed to get device code: Nú Error decoding JSON response: %sz'Failed to decode device code response: z(Unexpected error getting device code: %s)r   r   r   r   r   ÚpostrT   rU   rA   Úallr   r8   r   rV   rW   rF   rX   )r#   r[   Údevice_code_urlri   ÚrespÚrequired_fieldsr<   rs   s          @r$   Ú_get_device_codezAuthenticator._get_device_codeØ   sk  ø€ ð&	Ü!2Ó!4ˆKÜ%'§Y¡YÐ/OÔQoÓ%pˆOÜ!Ÿy™yÐ)CÔE]Ó^ˆIØ%×*Ñ*ØØ×0Ñ0Ó2Ø#,°{ÑCð +ó ˆDð
 ×!Ñ!Ô#Ø#Ÿy™y›{ˆIâ%UˆOÜÓG°ÔGÔGÜ×$Ñ$Ð%KÈYÔWÜ(Ø>Ø #ôð ð
 ÐøÜ×$Ñ$ò 	Ü× Ñ Ð!EÀqÔIÜ$Ø5°a°SÐ9Øôð ûô ×#Ñ#ò 	Ü× Ñ Ð!CÀQÔGÜ$ØAÀ!ÀÐEØôð ûô ò 	Ü× Ñ Ð!KÈQÔOÜ$Ø5°a°SÐ9Øôð ûð	ús0   ƒB?C ÃE/Ã&C<Ã<E/Ä&D8Ä8E/Å&E*Å*E/rl   c           	      ó¤  — t        «       }d}t        j                  dt        «      }t        j                  dt        «      }t        |«      D ]Ç  }	 |j                  || j                  «       ||ddœ¬«      }|j                  «        |j                  «       }d|v rt        j                  d«       |d   c S d	|v r/|j                  d	«      d
k(  rt        j                  d|dz   |«       nt        j                  d|«       t+        j,                  d«       ŒÉ t%        dd¬«      ‚# t        j                   $ r+}	t        j"                  d|	«       t%        d|	› �d¬«      ‚d}	~	wt        j&                  $ r+}	t        j"                  d|	«       t%        d|	› �d¬«      ‚d}	~	wt(        $ r+}	t        j"                  d|	«       t%        d|	› �d¬«      ‚d}	~	ww xY w)a  
        Poll for an access token after user authentication.

        Args:
            device_code: The device code to use for polling.

        Returns:
            str: The access token.

        Raises:
            GetAccessTokenError: If unable to get an access token.
        é   ÚGITHUB_COPILOT_ACCESS_TOKEN_URLrh   z,urn:ietf:params:oauth:grant-type:device_code)ri   rl   Ú
grant_typerk   r:   zAuthentication successful!r8   Úauthorization_pendingz%Authorization pending (attempt %s/%s)r   zUnexpected response: %sz'HTTP error polling for access token: %szFailed to get access token: ru   r,   Nrv   z(Failed to decode access token response: z-Unexpected error polling for access token: %sé   z2Timed out waiting for user to authorize the device)r   r   r   r   r   r4   rw   rT   rU   rA   r   ÚinforC   r5   r3   rV   rW   r8   r
   rF   rX   ÚtimeÚsleep)
r#   rl   r[   Úmax_attemptsÚaccess_token_urlri   r;   rz   rs   r<   s
             r$   Ú_poll_for_access_tokenz$Authenticator._poll_for_access_token
  sÜ  € ô /Ó0ˆØ ˆä"$§)¡)Ð,MÔOnÓ"oÐÜŸ9™9Ð%?ÔAYÓZˆ	ä˜\Ó*ò (	ˆGð%Ø"×'Ñ'Ø$Ø ×4Ñ4Ó6à%.Ø'2Ø&Tñð (ó �ð ×%Ñ%Ô'Ø ŸI™I›K�	à! YÑ.Ü"×'Ñ'Ð(DÔEØ$ ^Ñ4Ò4Ø 	Ñ)¨i¯m©m¸GÓ.DÐH_Ò._Ü"×(Ñ(Ð)PÐRYÐ\]ÑR]Ð_kÕlä"×*Ñ*Ð+DÀiÔPô( �J‰J�q�MðQ(	ôT "ØHØô
ð 	
øô+ ×(Ñ(ò Ü×$Ñ$Ð%NÐPQÔRÜ)Ø:¸1¸#Ð>Ø #ôð ûô ×'Ñ'ò Ü×$Ñ$Ð%GÈÔKÜ)ØFÀqÀcÐJØ #ôð ûô ò Ü×$Ñ$Ð%TÐVWÔXÜ)Ø:¸1¸#Ð>Ø #ôð ûðús8   ÁA#D#Â6A	D#Ä#GÄ6&EÅGÅ2&FÆGÆ$&G
Ç
Gc                 óŠ   — | j                  «       }|d   }|d   }|d   }t        d|› d|› d�d¬«       | j                  |«      S )	a  
        Login to GitHub Copilot using device code flow.

        Returns:
            str: The GitHub access token.

        Raises:
            GetDeviceCodeError: If unable to get a device code.
            GetAccessTokenError: If unable to get an access token.
        rl   rm   rn   zPlease visit z and enter code z to authenticate.T)Úflush)r|   Úprintrˆ   )r#   Údevice_code_inforl   rm   rn   s        r$   r6   zAuthenticator._loginL  si   € ð #'×"7Ñ"7Ó"9Ðà-¨mÑ<ˆØ+¨KÑ8ˆ	Ø"2Ð3EÑ"FÐäØÐ,Ð-Ð-=¸i¸[ÐHYÐZð õ		
ð ×*Ñ*¨;Ó7Ð7r&   )r   Nrp   )Ú__name__Ú
__module__Ú__qualname__r%   Ústrr=   rK   rP   Údictr   rH   r!   rT   r|   rˆ   r6   re   r&   r$   r   r      s£   „ ó!ð#
 #ó #
ðJ2˜Só 2ðh˜c D™jó ð"#
 $ s¨C x¡.ó #
óJ7ñ
°°d±
ð ÀdÈ3ÐPSÈ8Ánó ð40 $ s¨C x¡.ó 0ðd@
°#ð @
¸#ó @
ðD8˜ô 8r&   r   )rA   r   r„   r   Útypingr   r   rV   Úlitellm._loggingr   Ú&litellm.llms.custom_httpx.http_handlerr   Úcommon_utilsr	   r
   r   r   r   r   Ú__annotations__r   r   r   r   re   r&   r$   ú<module>r—      sa   ðÜ Û 	Û Ý ß ã å +Ý D÷õ ð #9Ð ˜%Ó 8Ø(NÐ  Ó NØ)VÐ  Ó VØ$VÐ ˜EÓ V÷I8ò I8r&   