o
    ưig                     @   s  U d 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 ddlZddlmZmZ ddlm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 erkddlm Z! ddl"m#Z#m$Z$m%Z% dZ&dZ'ee(d< dZ)ee(d< z
ddlm Z) dZ&W n	 e*y   Y nw ddl+m,Z, ddl-m.Z.m/Z/ ddl0m1Z1 e,Z'de	e2ef de3de3ddfddZ4de	e2ef de
e2 ddfddZ5dede	e2ef de2fdd Z6d!d"d#e2d$e
e2 d%e	e2ef def
d&d'Z7ded!ed(ed)e
e2 d$e
e2 d*e
e2 defd+d,Z8e						dCde
d- d!e
d" d$e
e2 d%e
e	e2ef  de
e2 d.e
e	e2e2f  dedefd/d0Z9edd-d!d"dedeeeeeef f fd1d2Z:d!d3d*e2de
e2 d%e
e	e2ef  d4e
e	e2ef  d5e
e	e2ef  defd6d7Z;								dDde
d- d!e
d3 d$e
e2 d%e
e	e2ef  de
e2 d4e
e	e2ef  d5e
e	e2ef  d.e
e	e2e2f  dee fd8d9Z<	:	dEd;e2d<e=d=e
e	e2e2f  dd-fd>d?Z>edfd;e2d<e=d=e
e	e2e2f  dd@fdAdBZ?dS )Fzs
LiteLLM A2A SDK functions.

Provides standalone functions with @client decorator for LiteLLM logging integration.
    N)TYPE_CHECKINGAnyAsyncIterator	CoroutineDictOptionalUnion)verbose_loggerverbose_proxy_logger)A2AStreamingIterator)A2ARequestUtils)DEFAULT_A2A_AGENT_TIMEOUT)Logging)get_async_httpx_clienthttpxSpecialProvider)LiteLLMSendMessageResponse)client)	A2AClient)	AgentCardSendMessageRequestSendStreamingMessageRequestFA2ACardResolver
_A2AClientT)LiteLLMA2ACardResolver)handle_a2a_localhost_retrymap_a2a_exception)A2ALocalhostURLErrorkwargsprompt_tokenscompletion_tokensreturnc                 C   s8   |  d}|durtj|||| d}||jd< dS dS )z
    Set usage on litellm_logging_obj for standard logging payload.

    Args:
        kwargs: The kwargs dict containing litellm_logging_obj
        prompt_tokens: Number of input tokens
        completion_tokens: Number of output tokens
    litellm_logging_objN)r   r   Ztotal_tokensusage)getlitellmUsagemodel_call_details)r   r   r   r!   r"    r'   P/home/app/Keep/.python/lib/python3.10/site-packages/litellm/a2a_protocol/main.py_set_usage_on_logging_obj5   s   
r)   agent_idc                 C   s0   |du rdS |  d}|dur||jd< dS dS )z
    Set agent_id on litellm_logging_obj for SpendLogs tracking.

    Args:
        kwargs: The kwargs dict containing litellm_logging_obj
        agent_id: The A2A agent ID
    Nr!   r*   )r#   r&   )r   r*   r!   r'   r'   r(   _set_agent_id_on_logging_objL   s   
r+   
a2a_clientc                 C   s   d}t | dd}|du rt | dd}|durt |ddpd}d| }d}|d}|dur>||_||_||jd	< ||jd
< |S )z
    Extract agent info and set model/custom_llm_provider for cost tracking.

    Sets model info on the litellm_logging_obj if available.
    Returns the agent name for logging.
    unknown_litellm_agent_cardN
agent_cardname
a2a_agent/	a2a_agentr!   modelcustom_llm_provider)getattrr#   r3   r4   r&   )r,   r   
agent_namer/   r3   r4   r!   r'   r'   r(   _get_a2a_model_info`   s    


r7   requestr   r4   api_baselitellm_paramsc                    sp   t d| d|  ddlm} t| jdr| jjddnt| j}|jt	| j
|||dI d	H }t|S )
z
    Route a send_message through the LiteLLM completion bridge (e.g. LangGraph, Bedrock AgentCore).

    Requires request; api_base is optional for providers that derive endpoint from model.
    z&A2A using completion bridge: provider=z, api_base=r   A2ACompletionBridgeHandler
model_dumpjsonmodeZ
request_idparamsr:   r9   N)r	   info6litellm.a2a_protocol.litellm_completion_bridge.handlerr<   hasattrrB   r=   dictZhandle_non_streamingstridr   	from_dict)r8   r4   r9   r:   r<   rB   response_dictr'   r'   r(   #_send_message_via_completion_bridge   s    

rK   r/   card_urlr6   c           
         s  d}t dD ]w}z| |I dH }W  nj ty5 } zt||| dd} |r)|jnd}W Y d}~qd}~w ty~ } z>z
t||||d W n- tyl }	 zt|	|| dd} |r[|jnd}W Y d}	~	W Y d}~qd}	~	w tys    w W Y d}~qd}~ww |du rtd|S )z>Send an A2A message with retry logic for localhost URL errors.N   Ferrorr/   r,   Zis_streamingr3   zCA2A send_message failed: no response received after retry attempts.)rangesend_messager   r   url	Exceptionr   RuntimeError)
r,   r8   r/   rL   r9   r6   a2a_response_elocalhost_errr'   r'   r(   _execute_a2a_send_with_retry   sN   	rZ   A2AClientTypeagent_extra_headersc                    s  |pi }| d}|rt|ddnd}| d}	|	r.|du r#tdt||	||dI dH S |du r6td| du rd|du rBtd|pItt }d	|i}
|rT||
d
< |r[|
| t||
dI dH } | dusjJ t	| |}t
d|j d|  t| ddpt| dd}|rt|ddnd}|ptt }|jj}t|tr| ddu r||d< nt|dddu r||_t| |||||dI dH }t
d|j  t|}|jddd}tj||d\}}}t|||d t||d |S )as  
    Async: Send a message to an A2A agent.

    Uses the @client decorator for LiteLLM logging and tracking.
    If litellm_params contains custom_llm_provider, routes through the completion bridge.

    Args:
        a2a_client: An initialized a2a.client.A2AClient instance (optional if using completion bridge)
        request: SendMessageRequest from a2a.types (optional if using completion bridge with api_base)
        api_base: API base URL (required for completion bridge, optional for standard A2A)
        litellm_params: Optional dict with custom_llm_provider, model, etc. for completion bridge
        agent_id: Optional agent ID for tracking in SpendLogs
        **kwargs: Additional arguments passed to the client decorator

    Returns:
        LiteLLMSendMessageResponse (wraps a2a SendMessageResponse with _hidden_params)

    Example (standard A2A):
        ```python
        from litellm.a2a_protocol import asend_message, create_a2a_client
        from a2a.types import SendMessageRequest, MessageSendParams
        from uuid import uuid4

        a2a_client = await create_a2a_client(base_url="http://localhost:10001")
        request = SendMessageRequest(
            id=str(uuid4()),
            params=MessageSendParams(
                message={"role": "user", "parts": [{"kind": "text", "text": "Hello!"}], "messageId": uuid4().hex}
            )
        )
        response = await asend_message(a2a_client=a2a_client, request=request)
        ```

    Example (completion bridge with LangGraph):
        ```python
        from litellm.a2a_protocol import asend_message
        from a2a.types import SendMessageRequest, MessageSendParams
        from uuid import uuid4

        request = SendMessageRequest(
            id=str(uuid4()),
            params=MessageSendParams(
                message={"role": "user", "parts": [{"kind": "text", "text": "Hello!"}], "messageId": uuid4().hex}
            )
        )
        response = await asend_message(
            request=request,
            api_base="http://localhost:2024",
            litellm_params={"custom_llm_provider": "langgraph", "model": "agent"},
        )
        ```
    r!   Zlitellm_trace_idNr4   )request is required for completion bridge)r8   r4   r9   r:   request is required?Either a2a_client or api_base is required for standard A2A flowX-LiteLLM-Trace-IdX-LiteLLM-Agent-Idbase_urlextra_headerszA2A send_message request_id=z, agent=r.   r/   rS   
context_id)r,   r8   r/   rL   r9   r6   z'A2A send_message completed, request_id=r>   T)r@   Zexclude_none)r8   rJ   )r   r   r   )r   r*   )r#   r5   
ValueErrorrK   rG   uuiduuid4updatecreate_a2a_clientr7   r	   rC   rH   rB   message
isinstancerF   re   rZ   r   Zfrom_a2a_responser=   r   Z%calculate_usage_from_request_responser)   r+   )r,   r8   r9   r:   r*   r\   r   logging_objZtrace_idr4   rd   r6   r/   rL   re   rk   rV   responserJ   r   r   rW   r'   r'   r(   asend_message   s   >




	
ro   c                 K   sZ   zt  }W n ty   d}Y nw |dur td| |d|S t td| |d|S )a  
    Sync: Send a message to an A2A agent.

    Uses the @client decorator for LiteLLM logging and tracking.

    Args:
        a2a_client: An initialized a2a.client.A2AClient instance
        request: SendMessageRequest from a2a.types
        **kwargs: Additional arguments passed to the client decorator

    Returns:
        LiteLLMSendMessageResponse (wraps a2a SendMessageResponse with _hidden_params)
    N)r,   r8   r'   )asyncioget_running_looprU   ro   run)r,   r8   r   loopr'   r'   r(   rR   o  s   rR   r   metadataproxy_server_requestc           
   	   C   s   t j  }d| }t|dddgdd|t| jt| jd}||_d|_||jd	< d|jd
< |r6||jd< |r<| ni }	|rD||	d< |rJ||	d< |	|_	|	|_
|	|jd< |pXi |jd< |S )z0Build logging object for streaming A2A requests.r1   userzstreaming-request)ZrolecontentFasend_message_streaming)r3   messagesstreamZ	call_type
start_timeZlitellm_call_idZfunction_idr2   r3   r4   r*   rt   ru   r:   )datetimenowr   rG   rH   r3   r4   r&   copyr:   Zoptional_params)
r8   r6   r*   r:   rt   ru   r{   r3   rm   Z_litellm_paramsr'   r'   r(   _build_streaming_logging_obj  s6   
	

	



r   c                 C  s  |pi }| d}|rM|du rtdtd|  ddlm}	 t|jdr/|jjdd	nt	|j}
|	j
t|j|
||d
2 z	3 dH W }|V  q@6 dS |du rUtd| du r~|du ratddt|ji}|rn||d< |ru|| t||dI dH } | dusJ td|j  t| ddpt| dd}|rt|ddnd}|rt|ddnd}t||||||d}d}tdD ]}| |}t||||d}zd}|2 z3 dH W }|rd}|V  q6 W  dS  ty } z |r|dkrt||| dd} |r|jnd}n W Y d}~qd}~w ty` } zD|r[|dkr[z
t||||d W   tyR } zt||| dd} |rA|jnd}W Y d}~W Y d}~qd}~w tyZ    w  d}~ww dS )a  
    Async: Send a streaming message to an A2A agent.

    If litellm_params contains custom_llm_provider, routes through the completion bridge.

    Args:
        a2a_client: An initialized a2a.client.A2AClient instance (optional if using completion bridge)
        request: SendStreamingMessageRequest from a2a.types
        api_base: API base URL (required for completion bridge)
        litellm_params: Optional dict with custom_llm_provider, model, etc. for completion bridge
        agent_id: Optional agent ID for tracking in SpendLogs
        metadata: Optional metadata dict (contains user_api_key, user_id, team_id, etc.)
        proxy_server_request: Optional proxy server request data

    Yields:
        SendStreamingMessageResponse chunks from the agent

    Example (completion bridge with LangGraph):
        ```python
        from litellm.a2a_protocol import asend_message_streaming
        from a2a.types import SendStreamingMessageRequest, MessageSendParams
        from uuid import uuid4

        request = SendStreamingMessageRequest(
            id=str(uuid4()),
            params=MessageSendParams(
                message={"role": "user", "parts": [{"kind": "text", "text": "Hello!"}], "messageId": uuid4().hex}
            )
        )
        async for chunk in asend_message_streaming(
            request=request,
            api_base="http://localhost:2024",
            litellm_params={"custom_llm_provider": "langgraph", "model": "agent"},
        ):
            print(chunk)
        ```
    r4   Nr]   z0A2A streaming using completion bridge: provider=r   r;   r=   r>   r?   rA   r^   r_   r`   ra   rb   z&A2A send_message_streaming request_id=r.   r/   rS   r0   r-   )r8   r6   r*   r:   rt   ru   TrM   )rz   r8   rm   r6   FrN   rP   )r#   rf   r	   rC   rD   r<   rE   rB   r=   rF   Zhandle_streamingrG   rH   ri   rj   r5   r   rQ   Zsend_message_streamingr   r   r   rS   rT   r   )r,   r8   r9   r:   r*   rt   ru   r\   r4   r<   rB   chunkZstreaming_extra_headersr/   rL   r6   rm   Zfirst_chunkattemptrz   iteratorrX   rY   r'   r'   r(   rx     s   /




rx         N@rc   timeoutrd   c           	         s   t stdtd|   d|i}|rtt| |d< ttj	|d}|j
}|r=|j| tdt|   t|| d}| I dH }td	t|d
rU|jnd  t||d}||_td|   |S )az  
    Create an A2A client for the given agent URL.

    This resolves the agent card and returns a ready-to-use A2A client.
    The client can be reused for multiple requests.

    Args:
        base_url: The base URL of the A2A agent (e.g., "http://localhost:10001")
        timeout: Request timeout in seconds (default: 60.0)
        extra_headers: Optional additional headers to include in requests

    Returns:
        An initialized a2a.client.A2AClient instance

    Example:
        ```python
        from litellm.a2a_protocol import create_a2a_client, asend_message

        # Create client once
        client = await create_a2a_client(base_url="http://localhost:10001")

        # Reuse for multiple requests
        response1 = await asend_message(a2a_client=client, request=request1)
        response2 = await asend_message(a2a_client=client, request=request2)
        ```
    \The 'a2a' package is required for A2A agent invocation. Install it with: pip install a2a-sdkzCreating A2A client for r   Zdisable_aiohttp_transportZllm_providerrB   z&A2A client created with extra_headers=httpx_clientrc   NzResolved agent card: r0   r-   )r   r/   zA2A client created for )A2A_SDK_AVAILABLEImportErrorr	   rC   rG   sorteditemsr   r   ZA2AProviderr   headersri   r
   debuglistkeysr   get_agent_cardrE   r0   r   r.   )	rc   r   rd   Z_client_paramsZ_async_handlerr   resolverr/   r,   r'   r'   r(   rj   h  sH   

rj   r   c                    st   t stdtd|   ttjd|id}|j}t|| d}|	 I dH }tdt
|dr3|jnd	  |S )
aF  
    Fetch the agent card from an A2A agent.

    Args:
        base_url: The base URL of the A2A agent (e.g., "http://localhost:10001")
        timeout: Request timeout in seconds (default: 60.0)
        extra_headers: Optional additional headers to include in requests

    Returns:
        AgentCard from the A2A agent
    r   zFetching agent card from r   r   r   NzFetched agent card: r0   r-   )r   r   r	   rC   r   r   ZA2Ar   r   r   rE   r0   )rc   r   rd   Zhttp_handlerr   r   r/   r'   r'   r(   aget_agent_card  s(   r   )NNNNNN)NNNNNNNN)r   N)@__doc__rp   r|   rg   typingr   r   r   r   r   r   r   r$   Zlitellm._loggingr	   r
   Z'litellm.a2a_protocol.streaming_iteratorr   Zlitellm.a2a_protocol.utilsr   Zlitellm.constantsr   Z*litellm.litellm_core_utils.litellm_loggingr   Z&litellm.llms.custom_httpx.http_handlerr   r   Zlitellm.types.agentsr   Zlitellm.utilsr   Z
a2a.clientr   r[   Z	a2a.typesr   r   r   r   r   __annotations__r   r   Z"litellm.a2a_protocol.card_resolverr   Z,litellm.a2a_protocol.exception_mapping_utilsr   r   Zlitellm.a2a_protocol.exceptionsr   rG   intr)   r+   r7   rK   rZ   ro   rR   r   rx   floatrj   r   r'   r'   r'   r(   <module>   sZ   $



"

#
+ 
+	
 2
\