Ë
    uPêjß6  ã                   óÊ   — 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mZ ddlmZ ddlmZ erddlZdd	lmZ dd
lmZmZ eZneZeZeZ G d„ de«      Z G d„ de«      Zy)an  
Transformation for Azure Foundry Agent Service API.

Azure Foundry Agent Service provides an Assistants-like API for running agents.
This follows the OpenAI Assistants pattern: create thread -> add messages -> create/poll run.

Model format: azure_ai/agents/<agent_id>

API Base format: https://<AIFoundryResourceName>.services.ai.azure.com/api/projects/<ProjectName>

Authentication: Uses Azure AD Bearer tokens (not API keys)
  Get token via: az account get-access-token --resource 'https://ai.azure.com'

The API uses these endpoints:
- POST /threads - Create a thread
- POST /threads/{thread_id}/messages - Add message to thread
- POST /threads/{thread_id}/runs - Create a run
- GET /threads/{thread_id}/runs/{run_id} - Poll run status
- GET /threads/{thread_id}/messages - List messages in thread

See: https://learn.microsoft.com/en-us/azure/ai-foundry/agents/quickstart
é    )ÚTYPE_CHECKINGÚAnyÚFinalN)Úverbose_logger)Úconvert_content_list_to_str)Ú
BaseConfigÚBaseLLMException)ÚAllMessageValues)ÚModelResponse)ÚLogging)ÚAsyncHTTPHandlerÚHTTPHandlerc                   ó   — e Zd ZdZy)ÚAzureAIAgentsErrorz6Exception class for Azure AI Agent Service API errors.N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__© ó    úp/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/llms/azure_ai/agents/transformation.pyr   r   1   s   „ Ú@r   r   c                   óâ  ‡ — e Zd ZdZdZdZdZˆ fd„Zede	de
fd„«       Zede	de	fd	„«       Zd
e	dz  de	dz  dee	dz  e	dz  f   fd„Zde	dee	   fd„Zdedede	de
def
d„Zdede	fd„Z	 d.d
e	dz  de	dz  de	dedede
dz  de	fd„Zde	dede	fd„Zde	dee   dedededefd„Z	 	 d/dede	dee   dedede	dz  d
e	dz  defd„Zde	dedeej6                  z  defd„Z	 d.de	dz  de
dz  de	dz  de
fd „Zede
fd!„«       Z ede
fd"„«       Z!	 	 d/de	d#ejD                  d$e#d%e$d&edee   deded'd(de	dz  d)e
dz  de#fd*„Z%e	 	 d0de	ded
e	de	dz  d$e#d%e$deded+e&e'z  d,e
de
dz  dedz  de'fd-„«       Z(ˆ xZ)S )1ÚAzureAIAgentsConfigaŽ  
    Configuration for Azure AI Agent Service API.

    Azure AI Agent Service is a fully managed service for building AI agents
    that can understand natural language and perform tasks.

    Model format: azure_ai/agents/<agent_id>

    The flow is:
    1. Create a thread
    2. Add user messages to the thread
    3. Create and poll a run
    4. Retrieve the assistant's response messages
    z
2025-05-01é<   g      ð?c                 ó$   •— t        ‰| �  di |¤Ž y )Nr   )ÚsuperÚ__init__)ÚselfÚkwargsÚ	__class__s     €r   r   zAzureAIAgentsConfig.__init__N   s   ø€ Ü‰ÑÑ"˜6Ó"r   ÚmodelÚreturnc                 ó
   — d| v S )zs
        Check if the model is an Azure AI Agents route.

        Model format: azure_ai/agents/<agent_id>
        úagents/r   )r!   s    r   Úis_azure_ai_agents_routez,AzureAIAgentsConfig.is_azure_ai_agents_routeQ   s   € ð ˜EÐ!Ð!r   c                 óX   — d| v r%| j                  dd«      }t        |«      dk(  r|d   S | S )z¥
        Extract agent ID from the model string.

        Model format: azure_ai/agents/<agent_id> -> <agent_id>
        or: agents/<agent_id> -> <agent_id>
        r$   é   é   )ÚsplitÚlen)r!   Úpartss     r   Úget_agent_id_from_modelz+AzureAIAgentsConfig.get_agent_id_from_modelZ   s5   € ð ˜Ñà Ÿ;™; y°!Ó4ˆEÜ�5‹z˜QŠØ˜Q‘x�Øˆr   Úapi_baseNÚapi_keyc                 óF   — ddl m} |xs  |d«      }|xs  |d«      }||fS )z”
        Get Azure AI Agent Service API base and key from params or environment.

        Returns:
            Tuple of (api_base, api_key)
        r   )Úget_secret_strÚAZURE_AI_API_BASEÚAZURE_AI_API_KEY)Úlitellm.secret_managers.mainr0   )r   r-   r.   r0   s       r   Ú$_get_openai_compatible_provider_infoz8AzureAIAgentsConfig._get_openai_compatible_provider_infoi   s3   € õ 	@àÒB™~Ð.AÓBˆØÒ?™^Ð,>Ó?ˆà˜Ð Ð r   c                 ó   — dgS )zZ
        Azure Agents supports minimal OpenAI params since it's an agent runtime.
        Ústreamr   )r   r!   s     r   Úget_supported_openai_paramsz/AzureAIAgentsConfig.get_supported_openai_params{   s   € ð ˆzÐr   Únon_default_paramsÚoptional_paramsÚdrop_paramsc                 ó   — |S )z;
        Map OpenAI params to Azure Agents params.
        r   )r   r8   r9   r!   r:   s        r   Úmap_openai_paramsz%AzureAIAgentsConfig.map_openai_params�   s
   € ð Ðr   c                 ó:   — |j                  d| j                  «      S )z4Get API version from optional params or use default.Úapi_version)ÚgetÚDEFAULT_API_VERSION)r   r9   s     r   Ú_get_api_versionz$AzureAIAgentsConfig._get_api_version�   s   € à×"Ñ" =°$×2JÑ2JÓKÐKr   Úlitellm_paramsr6   c                 óB   — |€t        d«      ‚|j                  d«      }|S )ay  
        Get the base URL for Azure AI Agent Service.

        The actual endpoint will vary based on the operation:
        - /openai/threads for creating threads
        - /openai/threads/{thread_id}/messages for adding messages
        - /openai/threads/{thread_id}/runs for creating runs

        This returns the base URL that will be modified for each operation.
        zeapi_base is required for Azure AI Agents. Set it via AZURE_AI_API_BASE env var or api_base parameter.ú/)Ú
ValueErrorÚrstrip)r   r-   r.   r!   r9   rB   r6   s          r   Úget_complete_urlz$AzureAIAgentsConfig.get_complete_url‘   s1   € ð& ÐÜØwóð ð
 —?‘? 3Ó'ˆð ˆr   c                 ót   — |j                  d«      xs |j                  d«      }|r|S | j                  |«      S )z¡
        Get the agent ID from model or optional_params.

        model format: "azure_ai/agents/<agent_id>" or "agents/<agent_id>" or just "<agent_id>"
        Úagent_idÚassistant_id)r?   r,   )r   r!   r9   rI   s       r   Ú_get_agent_idz!AzureAIAgentsConfig._get_agent_id¯   s@   € ð *×-Ñ-¨jÓ9Ò`¸_×=PÑ=PÐQ_Ó=`ˆÙØˆOð ×+Ñ+¨EÓ2Ð2r   ÚmessagesÚheadersc                 óž  — | j                  ||«      }g }|D ]p  }|j                  dd«      }	|j                  dd«      }
t        |
t        «      rt	        |«      }
t        |
t
        «      st        |
«      }
|j                  |	|
dœ«       Œr ||| j                  |«      dœ}d|v r|d   |d<   d|v r|d   |d<   t        j                  d	|«       |S )
z»
        Transform the request for Azure Agents.

        This stores the necessary data for the multi-step agent flow.
        The actual API calls happen in the custom handler.
        ÚroleÚuserÚcontentÚ )rO   rQ   )rI   rL   r>   Ú	thread_idÚinstructionsz#Azure AI Agents request payload: %s)
rK   r?   Ú
isinstanceÚlistr   ÚstrÚappendrA   r   Údebug)r   r!   rL   r9   rB   rM   rI   Úconverted_messagesÚmsgrO   rQ   Úpayloads               r   Útransform_requestz%AzureAIAgentsConfig.transform_request¼   sò   € ð ×,Ñ,¨U°OÓDˆð %'ÐØò 	JˆCØ—7‘7˜6 6Ó*ˆDØ—g‘g˜i¨Ó,ˆGô ˜'¤4Ô(Ü5°cÓ:�ô ˜g¤sÔ+Ü˜g›,�à×%Ñ%¨tÀÑ&HÕIð	Jð !Ø*Ø×0Ñ0°ÓAñ*
ˆð ˜/Ñ)Ø#2°;Ñ#?ˆG�KÑ ð ˜_Ñ,Ø&5°nÑ&EˆG�NÑ#ä×ÑÐBÀGÔLØˆr   c                 ó$   — d|d<   |rd|› �|d<   |S )aQ  
        Validate and set up environment for Azure Foundry Agents requests.

        Azure Foundry Agents uses Bearer token authentication with Azure AD tokens.
        Get token via: az account get-access-token --resource 'https://ai.azure.com'

        See: https://learn.microsoft.com/en-us/azure/ai-foundry/agents/quickstart
        zapplication/jsonzContent-TypezBearer ÚAuthorizationr   )r   rM   r!   rL   r9   rB   r.   r-   s           r   Úvalidate_environmentz(AzureAIAgentsConfig.validate_environmentí   s)   € ð$ #5ˆ�Ññ Ø)0°°	Ð':ˆG�OÑ$àˆr   Úerror_messageÚstatus_codec                 ó   — t        ||¬«      S )N)rb   Úmessage)r   )r   ra   rb   rM   s       r   Úget_error_classz#AzureAIAgentsConfig.get_error_class  s   € Ü!¨kÀ=ÔQÐQr   Úcustom_llm_providerc                  ó   — y)z_
        Azure Agents uses polling, so we fake stream by returning the final response.
        Tr   )r   r!   r6   rf   s       r   Úshould_fake_streamz&AzureAIAgentsConfig.should_fake_stream  s   € ð r   c                  ó   — y)z>Azure Agents doesn't have native streaming - uses fake stream.Fr   ©r   s    r   Úhas_custom_stream_wrapperz-AzureAIAgentsConfig.has_custom_stream_wrapper  s   € ð r   c                  ó   — y)zK
        Azure Agents does not use a stream param in request body.
        Fr   rj   s    r   Ú%supports_stream_param_in_request_bodyz9AzureAIAgentsConfig.supports_stream_param_in_request_body  s   € ð
 r   Úraw_responseÚmodel_responseÚlogging_objÚrequest_dataÚencodingztiktoken.Encoding | NoneÚ	json_modec                 ó   — |S )zV
        Transform the Azure Agents response to LiteLLM ModelResponse format.
        r   )r   r!   rn   ro   rp   rq   rL   r9   rB   rr   r.   rs   s               r   Útransform_responsez&AzureAIAgentsConfig.transform_response"  s
   € ð$ Ðr   ÚtimeoutÚacompletionc                 ó0  — ddl m} ddlm} ddlm} |€"|rt        |«      ni }d|d<    | |d
i |¤Ž«      }|€t        d«      ‚|	r7|
r|j                  | ||||||||¬«	      S |j                  | |||||||||¬	«
      S |j                  | |||||||||¬	«
      S )aT  
        Dispatch method for Azure Foundry Agents completion.

        Routes to sync or async completion based on acompletion flag.
        Supports native streaming via SSE when stream=True and acompletion=True.

        Authentication: Uses Azure AD Bearer tokens.
        - Pass api_key directly as an Azure AD token
        - Or set up Azure AD credentials via environment variables for automatic token retrieval:
          - AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET (Service Principal)

        See: https://learn.microsoft.com/en-us/azure/ai-foundry/agents/quickstart
        r   )Úget_azure_ad_token)Úazure_ai_agents_handler)ÚGenericLiteLLMParamszhttps://ai.azure.com/.defaultÚazure_scopea  api_key (Azure AD token) is required for Azure Foundry Agents. Either pass api_key directly, or set AZURE_TENANT_ID, AZURE_CLIENT_ID, and AZURE_CLIENT_SECRET environment variables for Service Principal auth. Manual token: az account get-access-token --resource 'https://ai.azure.com')	r!   rL   r-   r.   rp   r9   rB   rv   rM   )
r!   rL   r-   r.   ro   rp   r9   rB   rv   rM   r   )Úlitellm.llms.azure.common_utilsry   Ú$litellm.llms.azure_ai.agents.handlerrz   Úlitellm.types.routerr{   ÚdictrE   Úacompletion_streamrw   Ú
completion)r!   rL   r-   r.   ro   rp   r9   rB   rv   rw   r6   rM   ry   rz   r{   Úazure_auth_paramss                   r   r‚   zAzureAIAgentsConfig.completion6  s  € õ8 	GÝPÝ=ð ˆ?ñ @N¤t¨NÔ';ÐSUÐØ/NÐ˜mÑ,Ù(Ñ)=Ñ)RÐ@QÑ)RÓSˆGàˆ?Üð^óð ñ Ùà.×AÑAØØ%Ø%Ø#Ø +Ø$3Ø#1Ø#Ø#ð Bó 
ð 
ð /×:Ñ:ØØ%Ø%Ø#Ø#1Ø +Ø$3Ø#1Ø#Ø#ð ;ó ð ð +×5Ñ5ØØ!Ø!ØØ-Ø'Ø /Ø-ØØð 6ó ð r   )N)NN)FN)*r   r   r   r   r@   ÚMAX_POLL_ATTEMPTSÚPOLL_INTERVAL_SECONDSr   ÚstaticmethodrW   Úboolr%   r,   Útupler4   rV   r7   r€   r<   rA   rG   rK   r
   r]   r`   ÚintÚhttpxÚHeadersr	   re   rh   Úpropertyrk   rm   ÚResponser   ÚLiteLLMLoggingObjru   Úfloatr   r‚   Ú__classcell__)r    s   @r   r   r   5   s  ø„ ñð$ 'Ðð ÐØÐô#ð ð"¨ð "°ò "ó ð"ð ð sð ¨sò ó ðð!à˜‘*ð!ð �t‘ð!ð 
ˆs�T‰z˜3 ™:Ð%Ñ	&ó	!ð$°ð ¸¸c¹ó ð
à ð
ð ð
ð ð	
ð
 ð
ð 
ó
ðL°ð L¸ó Lð #ñà˜‘*ðð �t‘ðð ð	ð
 ðð ðð �t‘ðð 
óð<3 3ð 3¸ð 3À#ó 3ð/àð/ð Ð'Ñ(ð/ð ð	/ð
 ð/ð ð/ð 
ó/ðp #Ø#ñàðð ðð Ð'Ñ(ð	ð
 ðð ðð �t‘ðð ˜‘*ðð 
óð6R¨Sð R¸sð RÈTÐTY×TaÑTaÑMað RÐfvó Rð +/ñ		à�T‰zð	ð �t‘ð	ð ! 4™Zð		ð
 
ó	ð ð¨4ò ó ðð ð°tò ó ðð" #Ø!%ñàðð —n‘nðð &ð	ð
 'ðð ðð Ð'Ñ(ðð ðð ðð -ðð �t‘ðð ˜$‘;ðð 
óð( ð $Ø#ñWØðWàðWð ðWð �t‘ð	Wð
 &ðWð 'ðWð ðWð ðWð ˜‘ðWð ðWð �t‘ðWð ˜‘ðWð 
òWó ôWr   r   )r   Útypingr   r   r   rŠ   Úlitellm._loggingr   Ú8litellm.litellm_core_utils.prompt_templates.common_utilsr   Ú)litellm.llms.base_llm.chat.transformationr   r	   Úlitellm.types.llms.openair
   Úlitellm.types.utilsr   ÚtiktokenÚ*litellm.litellm_core_utils.litellm_loggingr   Ú_LiteLLMLoggingObjÚ&litellm.llms.custom_httpx.http_handlerr   r   rŽ   r   r   r   r   r   ú<module>r›      si   ðñ÷. -Ñ ,ã å +õ÷ SÝ 6Ý -áÛåXßTà*ÑàÐØ€KØÐôAÐ)ô AôY˜*õ Yr   