
    b
if                       d dl mZ d dlZd dlZd dlZd dlmZ d dlmZm	Z	m
Z
mZ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 d d
lmZmZmZ erd dlmZ  edede	f                   Z ej         e!          Z"d7dZ#d8dZ$d9dZ%d:dZ&d;dZ'd<dZ(d=d!Z)d>d$Z*	 	 d?d@d.Z+ G d/ d0ed%1          Z,edd2d3dAd6            Z-dS )B    )annotationsN)Mapping)TYPE_CHECKINGAnyCallableOptionalTypeVarUnion)	TypedDict)client)run_helpers)	warn_beta)dumps)InputTokenDetailsOutputTokenDetailsUsageMetadata)genaiCzgenai.Client)boundddictreturnc                >    d |                                  D             S )z%Remove `None` values from dictionary.c                    i | ]
\  }}|||S N .0kvs      C:\Users\Dell Inspiron 16\Desktop\tws\AgrotaPowerBi\back-agrota-powerbi\mcp-client-agrota\venv\Lib\site-packages\langsmith/wrappers/_gemini.py
<dictcomp>z_strip_none.<locals>.<dictcomp>!   s    888TQ!-Aq---    )items)r   s    r!   _strip_noner%      s    88QWWYY8888r#   kwargsNonec                |    d| v r5t          | d         t                    st          | d                   | d<   dS dS dS )zFConvert `GenerateContentConfig` to `dict` for LangSmith compatibility.configN)
isinstancer   vars)r&   s    r!   _convert_config_for_tracingr,   $   sL    6*VH-=t"D"Dx 011x r#   objr   c                    t          | t          t          f          r| S t          | d          r|                                 S t          | d          r|                                 S | S )zISerialize a Pydantic/model object to dict (or return as-is for dict/str).
model_dumpto_dict)r*   r   strhasattrr/   r0   )r-   s    r!   _to_dictr3   *   sd    #c{## 
sL!!  ~~sI {{}}Jr#   inputsc                R   |                      d          }|s| S t          |t                    r:d|dg|                      d          dd |                                 D             S t          |t                    rt          d |D                       r@d |D             |                      d          dd	 |                                 D             S g }|D ]}t          |          }t          |t                    s(|                     d
d          }|                     dg           }g }g }|D ]h}t          |          }t          |t                    r.|                    |           |                    d|d           Ut          |t                    skd|v rB|d         r:|                    |d                    |                    d|d         d           d|v rt          |d                   }	t          |	t                    s|	                     dd          }
|	                     dd          }t          |t                    r(t          j        |                              d          }n|}|                    dd|
 d| ddd           nd|v rL|d         }|                    d|                     d          |                     di           dd           d |v sd!|v rt          |                     d           p|                     d!                    }t          |t                    rV|                    d |                     d"          |                     d          |                     d#i           d$d%           j|r/t          d& |D                       rd'                    |          }n|r|nd(}|                    ||d           ||                      d          dd) |                                 D             S | S )*u  Process Gemini inputs to normalize them for LangSmith tracing.

    Example:
        ```txt
        {"contents": "Hello", "model": "gemini-pro"}
        → {"messages": [{"role": "user", "content": "Hello"}], "model": "gemini-pro"}
        {"contents": [{"role": "user", "parts": [{"text": "What is AI?"}]}], "model": "gemini-pro"}
        → {"messages": [{"role": "user", "content": "What is AI?"}], "model": "gemini-pro"}
        ```
    contentsuserrolecontentmodel)messagesr;   c                "    i | ]\  }}|d v	||S )r6   r;   r   r   s      r!   r"   z*_process_gemini_inputs.<locals>.<dictcomp>J   )    RRRA1<Q3Q3Q13Q3Q3Qr#   c              3  @   K   | ]}t          |t                    V  d S r   )r*   r1   r   items     r!   	<genexpr>z)_process_gemini_inputs.<locals>.<genexpr>P   s,      ::z$$$::::::r#   c                    g | ]}d |dS )r7   r8   r   rA   s     r!   
<listcomp>z*_process_gemini_inputs.<locals>.<listcomp>S   s     TTT4f>>TTTr#   c                "    i | ]\  }}|d v	||S r>   r   r   s      r!   r"   z*_process_gemini_inputs.<locals>.<dictcomp>U   s)    VVVTQq@U7U7UAq7U7U7Ur#   r9   partstexttyperH   inline_data	mime_type
image/jpegdatar#   utf-8	image_urldata:;base64,highurldetailrJ   rP   functionResponsefunction_responsenameresponse)rZ   r[   )rJ   rY   function_callfunctionCallidargsr^   rZ   	argumentsrJ   r\   c              3  H   K   | ]}|                     d           dk    V  dS )rJ   rH   Ngetr   ps     r!   rC   z)_process_gemini_inputs.<locals>.<genexpr>   s1      $T$TQUU6]]f%<$T$T$T$T$T$Tr#   
 c                "    i | ]\  }}|d v	||S r>   r   r   s      r!   r"   z*_process_gemini_inputs.<locals>.<dictcomp>   r?   r#   )re   r*   r1   r$   listallr3   r   appendbytesbase64	b64encodedecodejoin)r4   r6   r<   r:   r9   	raw_parts
text_partscontent_partspartrK   rL   rN   data_b64rY   fcmessage_contents                   r!   _process_gemini_inputsrz   5   s    zz*%%H  (C   
"(X>>?ZZ((
 
 SRRRR
 	
 (D!! \
::::::: 	 UT8TTTG,,  WVV\\^^VVV   K	H K	HGw''Ggt,, ;;vv..DGR00I$&J24M! 7 7~~dC(( %%d+++!((&$)G)GHHH!$-- T>>d6l>%%d6l333!((&$v,)O)OPPPP"d**"*4+>"?"?K%k488 !  +\ J JI&??6377D!$.. (#)#3D#9#9#@#@#I#I#'!(($/'Ly'L'L('L'L*0* *     (4//(,-?(@%!(($7(9(=(=f(E(E,=,A,A*b,Q,Q2 2     %,,$0F0F!$((?";";"Wtxx?W?WXXB!"d++ 
%,,(7*,&&,,,.FF6NN131C1C2" 2" 	 	 	  I$T$Tm$T$T$T!T!T IDHIIE E 4A"H--bOOToFFGGGG !ZZ((
 
 SRRRR
 	
 Mr#   prepopulated_invocation_paramsc                x   t          |          }|                    di           }t          |d          r*|j        }t	          |dd          }t	          |dd          }n?|                    d          }|                    d          }|                    d          }dd|                    d          |||| d	S )
z*Extract invocation parameters for tracing.r)   temperaturemax_output_tokensNstop_sequencesgooglechatr;   )ls_providerls_model_typels_model_namels_temperaturels_max_tokensls_stopls_invocation_params)r%   re   r2   r}   getattr)r{   r&   strippedr)   r}   
max_tokensstops          r!   _infer_invocation_paramsr      s     6""H\\(B''F v}%% ,(V%8$??
v/66jj//ZZ 344
zz*++  !g..%# >  r#   gemini_usage_metadatar   c                Z   |                      d          pd}|                      d          pd}|                      d          pd}|                      d          pd}|                      d          p||z   }i }|r1||d<   t          d|dz
            |d	<   t          d|dz
            |d
<   i }|r||d<   |rt          d|dz
            |d
<   t          |||t          di d |                                D             t          di d |                                D                       S )z2Convert Gemini usage metadata to LangSmith format.prompt_token_countr   candidates_token_countcached_content_token_countthoughts_token_counttotal_token_count
cache_readi@ cache_read_over_200k	over_200k	reasoningc                    i | ]
\  }}|||S r   r   r   s      r!   r"   z*_create_usage_metadata.<locals>.<dictcomp>   s    MMM1q}q!}}}r#   c                    i | ]
\  }}|||S r   r   r   s      r!   r"   z*_create_usage_metadata.<locals>.<dictcomp>   s    NNN1q!r#   )input_tokensoutput_tokenstotal_tokensinput_token_detailsoutput_token_detailsr   )re   maxr   r   r$   r   )r   r   r   r   r   r   r   r   s           r!   _create_usage_metadatar      s   .223GHHMA2667OPPUTU!!">??D1  1445KLLQPQ!!"566 	7 66 
 !#! O,FL)69)F27
 7
23 ,/q2Dv2M+N+NK(!# A,@[) T,/3IF3R,S,S[)',&- 
 
MM 3 9 9 ; ;MMM
 
 0 
 
NN 4 : : < <NNN
 

 
 
 
r#   r[   c           
     B   	 t          | d          r|                                 }nEt          | d          r|                                 }n dt          | dt	          |                     i}d}g }d}d|v r|d         r|d         d         }d|v r|d         }d	|v r|d	         r|d	         D ]}d|v r2|d         r*||d         z  }|                    d|d         d
           9d|v r|d         |d         }|                    dd          }	|                    dd          }
t          |
t                    r(t          j
        |
                              d          }n|
}|                    dd|	 d| ddd           d|v sd|v rt          |                    d          p|                    d                    }t          |t                    rV|                    d|                    d          |                    d          |                    di           dd           d|v r|d         r|d         }n$d|v r |d         }|                    d|d
           d |D             }|r!|pdd |d! t          |          D             d"}n4t          |          d#k    s|r|d         d$         dk    r|d |d%}n|d |d%}|                    d&          }t!          ddd'          }|rt#          |          }|                    d(          r|d         d ||d(         |d)S t          |d         t                    r|d         d ||d*S |d         d ||d*S # t$          $ r+}t&                              d+|            d,| icY d}~S d}~ww xY w)-z$Process Gemini response for tracing.r0   r/   rH   ri   N
candidatesr   r:   rG   rI   rK   rL   rM   rN   r#   rO   rP   rQ   rR   rS   rT   rW   r\   r]   r^   rZ   r_   r`   rb   finish_reasonc                D    g | ]}|                     d           dk    |S rb   rd   rf   s     r!   rE   z6_process_generate_content_response.<locals>.<listcomp>9  s,    SSSA!%%--?2R2Ra2R2R2Rr#   	assistantc           
         g | ]d\  }}|d                               d          pd| d||d          d         t          |d          d                                                   ddeS )r\   r^   call_functionrZ   ra   )rZ   ra   )r^   rJ   indexr   )re   _dumpsrq   )r   itcs      r!   rE   z6_process_generate_content_response.<locals>.<listcomp>@  s        2 !155d;;J{q{{ *!"$&$7$?)/ "? 3K @* *$fhh	% %	
 
  r#   )r:   r9   r   
tool_calls   rJ   )r:   r9   r   usage_metadatar   r   r   r   )r:   r9   r   r   r   )r:   r9   r   r   z"Error processing Gemini response: output)r2   r0   r/   r   r1   rm   re   r*   rn   ro   rp   rq   r3   r   	enumeratelenr   r   	Exceptionloggerdebug)r[   rdictcontent_resultru   r   	candidater:   rv   rK   rL   rN   rw   rx   r   resultr   
usage_dictes                     r!   "_process_generate_content_responser      s   N$8Y'' 	G$$&&EEX|,, 	G''))EEWXvs8}}EEFE '+5  U<%8 l+A.II%%#I.g%%''*:% ' 0 (" ("!T>>d6l>*d6l:N)00&$v,1W1WXXXX*d22tM7J7V*.}*=K(3\(R(RI#.??63#?#?D  *$66 0+1+;D+A+A+H+H+Q+Q+/)00,7/Ty/T/T(/T/T282& 2&!" !"    -44$8N8N!) $ 9 9 UTXXn=U=U" "B  *"d33 
" - 4 40?24&&,,46FF6NN9;9K9K:* :*%& %&	!" 	!" 	!" #i//Io4N/$-o$>Mu__"6]N  &.!I!IJJJ TSSSS
 $	 *1T#!.  "+:!6!6  	 FF& !## $+A.v6&@@ )#!. FF *#!. F #344$1!!%
 %
 %

  	@/??J ::l## 	 "),#!.$\2",   &+S11 %i0'%2&0	    &i0'%2&0	    $ $ $=!==>>>(#######$s*   L1M) 4'M) M) )
N3 NNN
all_chunksrk   c           	     r   | sdt          ddd          dS d}d}| D ]Z}	 t          |d          r|j        r
||j        z  }|}'# t          $ r'}t                              d|            Y d}~Sd}~ww xY wt          ddd          }|r&	 t          |d          r|j        rt          |j        d	          r|j                                        }nt          |j        d
          r|j                                        }nlt          |j        dd          t          |j        dd          t          |j        dd          t          |j        dd          t          |j        dd          d}t          |          }n4# t          $ r'}t                              d|            Y d}~nd}~ww xY w||dS )z/Reduce streaming chunks into a single response.ri   r   r   )r:   r   NrH   zError processing chunk: r   r0   r/   r   r   r   r   r   )r   r   r   r   r   z+Error extracting metadata from last chunk: )r   r2   rH   r   r   r   r   r0   r/   r   r   )r   	full_text
last_chunkchunkr   r   r   s          r!   _reduce_generate_content_chunksr     ss    
+aa  
 
 	
 IJ 9 9	9uf%% (%* (UZ'	JJ 	9 	9 	9LL7A7788888888	9 %2aa% % %N  L	Lz#344 D9R D:4i@@ !+!:!B!B!D!DJJZ6EE !+!:!E!E!G!GJJ /6&57KQ/ / 3:&57OQR3 3 7>&57SUV7 7 18&57Mq1 1 .5&57JA. ." "J$ "8
!C!C 	L 	L 	LLLJqJJKKKKKKKK	L
 (  s0   #A
A6A11A6C0F   
F1
F,,F1Foriginal_generater   rZ   r1   tracing_extraOptional[TracingExtra]is_streamingboolc                     |pi t          j                    fd            }t          j                    fd            }t          j                   r|n|S )z9Create a wrapper for Gemini's `generate_content` methods.c                     t          |           t          j        ddrt          nd t          st
          nd t          j        t                    d}  |          | i |S Nllm)rZ   run_type	reduce_fnprocess_inputsprocess_outputs_invocation_params_fnr   	r,   r   	traceabler   rz   r   	functoolspartialr   r_   r&   	decoratorr   rZ   r   r{   textras      r!   generatez_get_wrapper.<locals>.generate  s     	$F+++) 
9EO5541:FP22D"+"3(*H# #
 
 
 
	 ,yy*++T<V<<<r#   c                    K   t          |           t          j        ddrt          nd t          st
          nd t          j        t                    d}  |          | i | d {V S r   r   r   s      r!   	ageneratez_get_wrapper.<locals>.agenerate  s       	$F+++) 
9EO5541:FP22D"+"3(*H# #
 
 
 
	 2YY0114B6BBBBBBBBBr#   )r   wrapsr   is_async)r   rZ   r{   r   r   r   r   r   s   ``` `  @r!   _get_wrapperr     s      bF_&''= = = = = = = = ('=( _&''C C C C C C C C ('C( $,->??M99XMr#   c                  .    e Zd ZU ded<   ded<   ded<   dS )TracingExtrazOptional[Mapping[str, Any]]metadatazOptional[list[str]]tagszOptional[ls_client.Client]r   N)__name__
__module____qualname____annotations__r   r#   r!   r   r     s6         ))))&&&&&&r#   r   )totalChatGoogleGenerativeAI)r   	chat_namer   r   c               `   |pi }t          |                    d          pi           }|                    di           }d |                                D             }|r||d<   t	          | d          r>t	          | j        d          r)t	          | j        j        d          rt          d          t	          | d          r=t	          | j        d          r(t          | j        j        |||d	          | j        _        t	          | d          r=t	          | j        d
          r(t          | j        j	        |||d	          | j        _	        t	          | d          rat	          | j
        d          rLt	          | j
        j        d          r2t          | j
        j        j        |||d	          | j
        j        _        t	          | d          rat	          | j
        d          rLt	          | j
        j        d
          r2t          | j
        j        j	        |||d	          | j
        j        _	        | S )a  Patch the Google Gen AI client to make it traceable.

    !!! warning

        **BETA**: This wrapper is in beta.

    Supports:
        - `generate_content` and `generate_content_stream` methods
        - Sync and async clients
        - Streaming and non-streaming responses
        - Tool/function calling with proper UI rendering
        - Multimodal inputs (text + images)
        - Image generation with `inline_data` support
        - Token usage tracking including reasoning tokens

    Args:
        client: The Google Gen AI client to patch.
        tracing_extra: Extra tracing information.
        chat_name: The run name for the chat endpoint.

    Returns:
        The patched client.

    Example:
        ```python
        from google import genai
        from google.genai import types
        from langsmith import wrappers

        # Use Google Gen AI client same as you normally would.
        client = wrappers.wrap_gemini(genai.Client(api_key="your-api-key"))

        # Basic text generation:
        response = client.models.generate_content(
            model="gemini-2.5-flash",
            contents="Why is the sky blue?",
        )
        print(response.text)

        # Streaming:
        for chunk in client.models.generate_content_stream(
            model="gemini-2.5-flash",
            contents="Tell me a story",
        ):
            print(chunk.text, end="")

        # Tool/Function calling:
        schedule_meeting_function = {
            "name": "schedule_meeting",
            "description": "Schedules a meeting with specified attendees.",
            "parameters": {
                "type": "object",
                "properties": {
                    "attendees": {"type": "array", "items": {"type": "string"}},
                    "date": {"type": "string"},
                    "time": {"type": "string"},
                    "topic": {"type": "string"},
                },
                "required": ["attendees", "date", "time", "topic"],
            },
        }

        tools = types.Tool(function_declarations=[schedule_meeting_function])
        config = types.GenerateContentConfig(tools=[tools])

        response = client.models.generate_content(
            model="gemini-2.5-flash",
            contents="Schedule a meeting with Bob and Alice tomorrow at 2 PM.",
            config=config,
        )

        # Image generation:
        response = client.models.generate_content(
            model="gemini-2.5-flash-image",
            contents=["Create a picture of a futuristic city"],
        )

        # Save generated image
        from io import BytesIO
        from PIL import Image

        for part in response.candidates[0].content.parts:
            if part.inline_data is not None:
                image = Image.open(BytesIO(part.inline_data.data))
                image.save("generated_image.png")
        ```

    !!! version-added "Added in `langsmith` 0.4.33"

        Initial beta release of Google Gemini wrapper.

    r   r   c                &    i | ]\  }}|d k    ||S )r   r   r   s      r!   r"   zwrap_gemini.<locals>.<dictcomp>o  s*     ( ( (A!z//1///r#   modelsgenerate_content__wrapped__zfThis Google Gen AI client has already been wrapped. Wrapping a client multiple times is not supported.F)r   r   generate_content_streamTaio)r   re   popr$   r2   r   r   
ValueErrorr   r   r   )r   r   r   r   r{   tracing_extra_rests         r!   wrap_geminir     s   F "'RM M%%j117R88H%-\\2H"%M%M"( (&,,..( ( (  2)1:& 	!!
FM#566
 FM2MBB

 A
 
 	
 vx   
WV]<N%O%O 
)5M**,*
 *
 *
& vx   
WV]<U%V%V 
0<M1*,1
 1
 1
- 	
FJ))
 FJ%'9::

 .:J.*,.
 .
 .

* 	
FJ))
 FJ%'@AA

 5AJ5*,5
 5
 5

1 Mr#   )r   r   r   r   )r&   r   r   r'   )r-   r   r   r   )r4   r   r   r   )r{   r   r&   r   r   r   )r   r   r   r   )r[   r   r   r   )r   rk   r   r   )NF)r   r   rZ   r1   r{   r   r   r   r   r   r   r   )r   r   r   r   r   r1   r   r   ).
__future__r   ro   r   loggingcollections.abcr   typingr   r   r   r   r	   r
   typing_extensionsr   	langsmithr   	ls_clientr   #langsmith._internal._beta_decoratorr   langsmith._internal._orjsonr   r   langsmith.schemasr   r   r   r   r   r   	getLoggerr   r   r%   r,   r3   rz   r   r   r   r   r   r   r   r   r#   r!   <module>r     s   " " " " " "       # # # # # #                ( ' ' ' ' ' ) ) ) ) ) ) ! ! ! ! ! ! 9 9 9 9 9 9 7 7 7 7 7 7 R R R R R R R R R R GCu^S01222		8	$	$9 9 9 9
2 2 2 2   x x x xv   8& & & &RP$ P$ P$ P$f= = = =H -14N 4N 4N 4N 4Nn' ' ' ' '9E ' ' ' '  -1-	h h h h h h h hr#   