o
    ưiY                     @   s   d Z ddlZddlZddlZddlZddlmZmZmZm	Z	m
Z
mZmZmZ ddlZddlmZ ddlmZmZ ddlmZ erQddlmZ ddlmZmZ eZneZeZeZG d	d
 d
Ze ZdS )a  
Handler for Azure Foundry Agent Service API.

This handler executes the multi-step agent flow:
1. Create thread (or use existing)
2. Add messages to thread
3. Create and poll a run
4. Retrieve the assistant's response messages

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'

Supports both polling-based and native streaming (SSE) modes.

See: https://learn.microsoft.com/en-us/azure/ai-foundry/agents/quickstart
    N)TYPE_CHECKINGAnyAsyncIteratorCallableDictListOptionalTuple)verbose_logger)AzureAIAgentsConfigAzureAIAgentsError)ModelResponse)Logging)AsyncHTTPHandlerHTTPHandlerc                   @   s  e Zd ZdZdd ZdededefddZded	ededefd
dZded	ededefddZded	edededef
ddZ	ded	ededefddZ
dededefddZdedefddZdededed	edeeeef  defddZdedededed ee defd!d"Zd#ejd$ee d%efd&d'Z	(	(d;dedeeeef  dededed)eded*ed+ed,ee d ee defd-d.Zd/ededed0ed	ee deeeef  dedeeef fd1d2Z 	(	(d;dedeeeef  dededed)eded*ed+ed,ee! d ee defd3d4Z"d/ededed0ed	ee deeeef  dedeeef fd5d6Z#	(d<dedeeeef  deded)eded*ed+ed ee de$fd7d8Z%d#ejdede$fd9d:Z&d(S )=AzureAIAgentsHandlerzz
    Handler for Azure AI Agent Service.
    
    Executes the complete agent flow which requires multiple API calls.
    c                 C   s   t  | _d S N)r   config)self r   [/home/app/Keep/.python/lib/python3.10/site-packages/litellm/llms/azure_ai/agents/handler.py__init__?   s   zAzureAIAgentsHandler.__init__api_baseapi_versionreturnc                 C      | d| S )Nz/threads?api-version=r   r   r   r   r   r   r   _build_thread_urlH   s   z&AzureAIAgentsHandler._build_thread_url	thread_idc                 C      | d| d| S N	/threads/z/messages?api-version=r   r   r   r   r   r   r   r   _build_messages_urlK      z(AzureAIAgentsHandler._build_messages_urlc                 C   r   )Nr!   z/runs?api-version=r   r"   r   r   r   _build_runs_urlN   r$   z$AzureAIAgentsHandler._build_runs_urlrun_idc                 C   s   | d| d| d| S )Nr!   z/runs/z?api-version=r   )r   r   r   r&   r   r   r   r   _build_run_status_urlQ   s   z*AzureAIAgentsHandler._build_run_status_urlc                 C   r   r    r   r"   r   r   r   _build_list_messages_urlT   r$   z-AzureAIAgentsHandler._build_list_messages_urlc                 C   r   )z@URL for the create-thread-and-run endpoint (supports streaming).z/threads/runs?api-version=r   r   r   r   r    _build_create_thread_and_run_urlW   s   z5AzureAIAgentsHandler._build_create_thread_and_run_urlmessages_datac                 C   s`   | dg D ]'}| ddkr-| dg D ]}| ddkr,| di  dd    S qqdS )	z5Extract assistant content from the messages response.datarole	assistantcontenttypetextvalue )get)r   r*   msgcontent_itemr   r   r   _extract_content_from_messages^   s   z3AzureAIAgentsHandler._extract_content_from_messagesmodelr.   model_responsemessagesc              
   C   s   ddl m}m}m} |dd||dddg|_||_t|dr$|jdu r'i |_||jd	< z#dd
lm	}	 |	d|d}
|	d|dd}t
|d||
||
| d W |S  tyl } ztdt|  W Y d}~|S d}~ww )z*Build the ModelResponse from agent output.r   )ChoicesMessageUsagestopr-   r.   r,   )finish_reasonindexmessage_hidden_paramsNr   )token_counterzgpt-3.5-turbo)r7   r9   T)r7   r0   Zcount_response_tokensusage)prompt_tokenscompletion_tokensZtotal_tokensz!Failed to calculate token usage: )litellm.types.utilsr:   r;   r<   choicesr7   hasattrrB   Zlitellm.utilsrC   setattr	Exceptionr
   warningstr)r   r7   r.   r8   r   r9   r:   r;   r<   rC   rE   rF   er   r   r   _build_model_responseg   s4   	
z*AzureAIAgentsHandler._build_model_responseapi_keyoptional_paramsheadersc           	      C   s|   |du ri }d|d< |rd| |d< | d| jj}| j||}| d}|d}td	| d
|  |||||fS )aU  Prepare common parameters for completion.
        
        Azure Foundry Agents API uses Bearer token authentication:
        - Authorization: Bearer <token> (Azure AD token from 'az account get-access-token --resource https://ai.azure.com')
        
        See: https://learn.microsoft.com/en-us/azure/ai-foundry/agents/quickstart
        Nzapplication/jsonzContent-TypezBearer Authorizationr   r   /z'Azure AI Agents completion - api_base: z, agent_id: )r3   r   ZDEFAULT_API_VERSIONZ_get_agent_idrstripr
   debug)	r   r7   r   rP   rQ   rR   r   agent_idr   r   r   r   _prepare_completion_params   s   

z/AzureAIAgentsHandler._prepare_completion_paramsresponseexpected_codes	error_msgc                 C   s(   |j |vrt|j | d|j ddS )z6Check response status and raise error if not expected.: status_coderA   N)r^   r   r0   )r   rY   rZ   r[   r   r   r   _check_response   s   
z$AzureAIAgentsHandler._check_responseNlogging_objlitellm_paramstimeoutclientc              	      s   ddl m}  du r|d|ddid | ||||\}}}}ddtdtdtt d	tjf fd
d}| j	|||||||d\}}| 
|||||S )z9Execute synchronous completion using Azure Agent Service.r   )_get_httpx_clientN
ssl_verify)paramsmethodurl	json_datar   c                    s8   | dkr j |dS  j||rt|dS d dS NGET)rh   rR   )rh   rR   r+   r3   postjsondumpsrg   rh   ri   rc   rR   r   r   make_request   s   "z5AzureAIAgentsHandler.completion.<locals>.make_requestrr   r   r   rW   r   r9   rQ   r   )&litellm.llms.custom_httpx.http_handlerrd   r3   rX   rM   r   dicthttpxResponse_execute_agent_flow_syncrO   )r   r7   r9   r   rP   r8   r`   rQ   ra   rb   rc   rR   rd   r   rW   r   rr   r.   r   rq   r   
completion   s"   
(

zAzureAIAgentsHandler.completionrr   rW   c              	   C   s  |s/t d| ||  |d| ||i }| |ddgd | d }t d|  |dus5J |D ]&}	|	d	d
v r]| |||}
|d|
d|	ddd}| |ddgd q7d|i}d|v rl|d |d< |d| ||||}| |ddgd | d }t d|  | ||||}t	| j
jD ]G}|d|}| |dgd | d}t d|  |dkr n*|dv r| di dd}tdd| d| d t| j
j qtd!d"d |d| |||}| |dgd# | | }||fS )$zCExecute the agent flow synchronously. Returns (thread_id, content).Creating thread at: POST      Failed to create threadidCreated thread: Nr,   usersystemr   r.   r2   r,   r.   Failed to add messageassistant_idinstructionsFailed to create runCreated run: rk   Failed to get run statusstatusRun status: 	completedfailed	cancelledZexpired
last_errorrA   Unknown error  Run r\   r]     $Run timed out waiting for completionFailed to get messages)r
   rV   r   r_   rn   r3   r#   r%   r'   ranger   MAX_POLL_ATTEMPTSr   timesleepPOLL_INTERVAL_SECONDSr(   r6   r   rr   r   r   rW   r   r9   rQ   rY   r4   rh   Zrun_payloadr&   Z
status_url_r   r[   r.   r   r   r   rx      sJ   
z-AzureAIAgentsHandler._execute_agent_flow_syncc              	      s   ddl }ddlm}  du r||jjd|ddid | ||||\}}}}ddtdtdtt	 d	t
jf fd
d}| j|||||||dI dH \}}| |||||S )z:Execute asynchronous completion using Azure Agent Service.r   Nget_async_httpx_clientre   Zllm_providerrf   rg   rh   ri   r   c                    sB   | dkr j |dI d H S  j||rt|nd dI d H S rj   rl   rp   rq   r   r   rr   D  s   $z6AzureAIAgentsHandler.acompletion.<locals>.make_requestrs   r   )litellmrt   r   LlmProvidersAZURE_AIr3   rX   rM   r   ru   rv   rw   _execute_agent_flow_asyncrO   )r   r7   r9   r   rP   r8   r`   rQ   ra   rb   rc   rR   r   r   r   rW   r   rr   r.   r   rq   r   acompletion(  s,   
(
z AzureAIAgentsHandler.acompletionc              	      s4  |s3t d| ||  |d| ||i I dH }| |ddgd | d }t d|  |dus9J |D ])}	|	d	d
v rd| |||}
|d|
d|	dddI dH }| |ddgd q;d|i}d|v rs|d |d< |d| ||||I dH }| |ddgd | d }t d|  | ||||}t	| j
jD ]M}|d|I dH }| |dgd | d}t d|  |dkr n-|dv r| di dd}tdd| d| d t| j
jI dH  qtd!d"d |d| |||I dH }| |dgd# | | }||fS )$zDExecute the agent flow asynchronously. Returns (thread_id, content).rz   r{   Nr|   r}   r~   r   r   r,   r   r   r.   r2   r   r   r   r   r   r   rk   r   r   r   r   r   r   rA   r   r   r   r\   r]   r   r   r   )r
   rV   r   r_   rn   r3   r#   r%   r'   r   r   r   r   asyncior   r   r(   r6   r   r   r   r   r   V  sL    z.AzureAIAgentsHandler._execute_agent_flow_asyncc
                 C  s@  ddl }
ddlm} | |||||	\}	}}}}g }|D ]}|ddv r2|d|ddd	 q|d
d}|s@d|i|d< d|v rJ|d |d< | ||}td|  ||
j	j
d|ddid}|j||	t|d
dI dH }|jdvr| I dH }t|jd|  d| ||2 z	3 dH W }|V  q6 dS )zMExecute async streaming completion using Azure Agent Service with native SSE.r   Nr   r,   r   r   r.   r2   r   T)r   streamr9   threadr   z!Azure AI Agents streaming - URL: re   r   )rh   rR   r+   r   )r|   r}   zStreaming request failed: r]   )r   rt   r   rX   r3   appendr)   r
   rV   r   r   rm   rn   ro   r^   Zareadr   decode_process_sse_stream)r   r7   r9   r   rP   r`   rQ   ra   rb   rR   r   r   r   rW   r   Zthread_messagesr4   payloadrh   rc   rY   Z
error_textchunkr   r   r   acompletion_stream  sT   


z'AzureAIAgentsHandler.acompletion_streamc                 C  s  ddl m}m}m} dt jdd  }tt }d}d}	|	 2 z3 dH W }
|

 }
|
dr=|
dd 
 }	q%|
dr|
d	d 
 }|d
krm||||d|dd|dddgd}|rgd|i|_|V   dS zt|}W n
 tjy~   Y q%w |	dkrd|v r|d }td|  |	dkr|di dg }|D ]2}|ddkr|di dd}|r||||d|dd||dddgd}|rd|i|_|V  qq%6 dS )z@Process SSE stream and yield OpenAI-compatible streaming chunks.r   )DeltaModelResponseStreamStreamingChoicesz	chatcmpl-N   zevent:   zdata:   z[DONE]zchat.completion.chunkr=   )r.   )r?   r@   delta)r   createdr7   objectrH   r   zthread.createdr   zStream created thread: zthread.message.deltar   r.   r/   r0   r1   r2   r-   r>   )rG   r   r   r   uuiduuid4hexintr   Zaiter_linesstrip
startswithrB   rn   loadsJSONDecodeErrorr
   rV   r3   )r   rY   r7   r   r   r   Zresponse_idr   r   Zcurrent_eventlineZdata_strZfinal_chunkr+   Zdelta_contentr5   Z
text_valuer   r   r   r   r     sz   




z(AzureAIAgentsHandler._process_sse_stream)NNr   )'__name__
__module____qualname____doc__r   rM   r   r#   r%   r'   r(   r)   ru   r6   r   r   r   r   rO   r   tuplerX   rv   rw   r   r_   LiteLLMLoggingObjfloatr   ry   r   r	   rx   r   r   r   r   r   r   r   r   r   r   r   8   s4   		
)
!	

*
	
P	

.
	
O	

Cr   )r   r   rn   r   r   typingr   r   r   r   r   r   r   r	   rv   Zlitellm._loggingr
   Z+litellm.llms.azure_ai.agents.transformationr   r   rG   r   Z*litellm.litellm_core_utils.litellm_loggingr   Z_LiteLLMLoggingObjrt   r   r   r   r   Zazure_ai_agents_handlerr   r   r   r   <module>   s,    (   
y