o
    Zh!}                     @   s  d Z ddl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 ddlZddl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 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# 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) 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. zddl/m0Z0 ddl/m1Z1 W n e2y   ddl3m0Z0 ddl3m1Z1 Y nw e4dZ5dZ6G d d! d!Z7G d"d# d#ej8Z9dS )$z-Live client. The live module is experimental.    N)AnyAsyncIteratorDictOptionalSequenceUnionget_args)ConnectionClosed   )_api_module)_common)_transformers)client)errors)types)BaseApiClient)experimental_warning)get_value_by_path)set_value_by_path)_Content_from_mldev)_Content_from_vertex)_Content_to_mldev)_Content_to_vertex)_GenerateContentConfig_to_mldev) _GenerateContentConfig_to_vertex)_SafetySetting_to_mldev)_SafetySetting_to_vertex)_SpeechConfig_to_mldev)_SpeechConfig_to_vertex)_Tool_to_mldev)_Tool_to_vertex)ClientConnection)connectzgoogle_genai.liveznFunctionResponse request must have an `id` field from the response of a ToolCall.FunctionalCalls in Google AI.c                   @   s  e Zd ZdZdejdefddZdddd	ee	e
je
je
je
je
je
jee
j f  d
ee fddZdee
j fddZdee dedee
j fddZde
jfddZdee dedejfddZde	eef de ee!f fddZ"de	eef de ee!f fddZ#de	eef de ee!f fdd Z$de	eef de ee!f fd!d"Z%de	eef de ee!f fd#d$Z&de	eef de ee!f fd%d&Z'		d+d	ee	e
je
je
je
je
je
jee
j f  d
ee de
j(fd'd(Z)d)d* Z*dS ),AsyncSessionz.AsyncSession. The live module is experimental.
api_client	websocketc                 C   s   || _ || _d S N)_api_client_ws)selfr$   r%    r*   H/var/www/html/lang_env/lib/python3.10/site-packages/google/genai/live.py__init__G   s   
zAsyncSession.__init__NF)inputend_of_turnr-   r.   c                   s*   |  ||}| jt|I dH  dS )a  Send input to the model.

    The method will send the input request to the server.

    Args:
      input: The input request to the model.
      end_of_turn: Whether the input is the last message in a turn.

    Example usage:

    .. code-block:: python

      client = genai.Client(api_key=API_KEY)

      async with client.aio.live.connect(model='...') as session:
        await session.send(input='Hello world!', end_of_turn=True)
        async for message in session.receive():
          print(message)
    N)_parse_client_messager(   sendjsondumps)r)   r-   r.   client_messager*   r*   r+   r0   M   s   #zAsyncSession.sendreturnc                 C  sL   |   I dH  }r$|jr|jjr|V  dS |V  |   I dH  }s
dS dS )a  Receive model responses from the server.

    The method will yield the model responses from the server. The returned
    responses will represent a complete model turn. When the returned message
    is function call, user must call `send` with the function response to
    continue the turn.

    The live module is experimental.

    Yields:
      The model responses from the server.

    Example usage:

    .. code-block:: python

      client = genai.Client(api_key=API_KEY)

      async with client.aio.live.connect(model='...') as session:
        await session.send(input='Hello world!', end_of_turn=True)
        async for message in session.receive():
          print(message)
    N)_receiveserver_contentturn_complete)r)   resultr*   r*   r+   receives   s   zAsyncSession.receivestream	mime_typec                C  s   t  }t | ||| d}| sOz,t |  }t j|t | gt jdI dH  | r@|	 V  t 
dI dH  W n	 tyJ   Y nw | r|duro| sq|  z|I dH  W dS  t jyn   Y dS w dS dS )a  start a live session from a data stream.

    The interaction terminates when the input stream is complete.
    This method will start two async tasks. One task will be used to send the
    input stream to the model and the other task will be used to receive the
    responses from the model.

    The live module is experimental.

    Args:
      stream: An iterator that yields the model response.
      mime_type: The MIME type of the data in the stream.

    Yields:
      The audio bytes received from the model and server response messages.

    Example usage:

    .. code-block:: python

      client = genai.Client(api_key=API_KEY)
      config = {'response_modalities': ['AUDIO']}
      async def audio_stream():
        stream = read_audio()
        for data in stream:
          yield data
      async with client.aio.live.connect(model='...', config=config) as session:
        for audio in session.start_stream(stream = audio_stream(),
        mime_type = 'audio/pcm'):
          play_audio_chunk(audio.data)
    N)return_when-q=)asyncioEventcreate_task
_send_loopis_setr5   waitFIRST_COMPLETEDdoner8   sleepr	   cancelCancelledError)r)   r:   r;   
stop_eventZ	recv_taskr*   r*   r+   start_stream   s:   "
zAsyncSession.start_streamc                    s   t  }| jjddI d H }|r)zt|}W n tjjy(   td|w i }| j	j
r5| |}n| |}t jj|| dS )NFdecodezFailed to parse response: )responsekwargs)r   LiveServerMessager(   recvr1   loadsdecoderJSONDecodeError
ValueErrorr'   vertexai_LiveServerMessage_from_vertex_LiveServerMessage_from_mldevZ_from_response
model_dump)r)   parameter_modelZraw_responserM   Zresponse_dictr*   r*   r+   r5      s    
zAsyncSession._receivedata_streamrI   c                    s\   |2 z#3 d H W }t jt j||dgd}| j|dI d H  tdI d H  q6 |  d S )Ndatar;   media_chunks)r-   r=   )r   LiveClientRealtimeInputBlobr0   r>   rF   set)r)   rZ   r;   rI   r\   Zmodel_inputr*   r*   r+   rA      s   zAsyncSession._send_loopfrom_objectc                 C      i }t |dgd urt|dgt| jt |dg t |dgd ur,t|dgt |dg t |dgd ur?t|dgt |dg |S NZ	modelTurnZ
model_turnZturnCompleter7   Zinterrupted)getvsetvr   r'   r)   rb   	to_objectr*   r*   r+   _LiveServerContent_from_mldev      
z*AsyncSession._LiveServerContent_from_mldevc                 C   .   i }t |dgd urt|dgt |dg |S NZfunctionCallsZfunction_callsre   rf   rg   r*   r*   r+   _LiveToolCall_from_mldev     
z%AsyncSession._LiveToolCall_from_mldevc                 C   rk   rl   rm   rg   r*   r*   r+   _LiveToolCall_from_vertex  ro   z&AsyncSession._LiveToolCall_from_vertexc                 C      i }t |dgd urt|dg| t |dg t |dgd ur.t|dg| t |dg t |dgd urAt|dgt |dg |S NZserverContentr6   ZtoolCallZ	tool_callZtoolCallCancellationZtool_call_cancellation)re   rf   ri   rn   rg   r*   r*   r+   rW   !  s,   

z*AsyncSession._LiveServerMessage_from_mldevc                 C   rc   rd   )re   rf   r   r'   rg   r*   r*   r+   _LiveServerContent_from_vertex<  rj   z+AsyncSession._LiveServerContent_from_vertexc                 C   rq   rr   )re   rf   rs   rp   rg   r*   r*   r+   rV   P  s,   

z+AsyncSession._LiveServerMessage_from_vertexc              
      s  |}|st d dddiiS t|tr|g}ndt|trVd|v rVz
tjd(i |}W n tjy@   t	dt
| d| dw t|tjrUt|jtrU|jd	dd
g}n&t|tjr`|g}nt|tr|d|v r|d|v r| jjsyd|vryt	t|g}t|trtdd |D rg }|D ]Y}t|trz
tjd(i |}W n tjy   t	dt
| d| dw |jd u r jjst	t|jdd	d}tj|d|dd}	|dr|d|	d< ||	 qtjtj|dd}
|
S t|trtdd |D ri g }|D ]}t|ttjr|| q
 jjr1 fddt j|D }n fddt j|D }g }|D ]6}z
tjd(i |}W n tjyf   t	dt
| d| dw |tj|jdd	dd |j d qDtjtj!||dd}
|
S t|trtdd |D rntdd |D rdd |D }nt	dt
| d| dtjtj"|dd }
|
S t|trqd!|v sd"|v rd"|v r|d" }n|d! }tjtj!||ddd}
|
S d#|v r+z
tj#d(i |}W n tjy   t	dt
| d| dw tjtj"|jdd	dd# dd }
|
S d$|v rdz
tj$d(i |}W n tjyP   t	dt
| d| dw tjtj|jdd	dd$ dd}
|
S t	dt
| d| dt|tj#r|jdd	d}tjtj"|d#dd }
|
d% d ur|
d% d# d urt|
d% d# d& d trg }|
d% d# D ]M}t|trz
tjd(i |}W n tjy   t	dt
| d| dw t|tjrt|jtr|jd ur|tj%t&'|j|j(d' q||
d% d#< |
S t|tj)r)|jdd	d}tjtj!|d"|ddd}
|
S t|tj$rZ jjsF|j*d urF|j*d& jsFt	ttjtj|jdd	dd$dd}
|
S t|tjr jjsn|jsnt	t|jdd	d}tj|d|dd}	|dr|d|	d< tjtj|	gdd}
|
S t|trt|d& tjr jjs|d& jst	tg }|D ])}|jdd	d}tj|d|dd}	|dr|d|	d< ||	 qtjtj|dd}
|
S t	dt
| d| d))Nz0No input provided. Assume it is the end of turn.client_contentr7   Tr\   zUnsupported input type "z" or input content ""r1   )modeexclude_nonenamerM   idc                 s   s*    | ]}t |tod |v od|v V  qdS )rx   rM   N
isinstancedict.0cr*   r*   r+   	<genexpr>  s
    
z5AsyncSession._parse_client_message.<locals>.<genexpr>rw   rv   )rx   rM   )function_responses)Ztool_responsec                 s   s    | ]}t |tV  qd S r&   )r{   strr}   r*   r*   r+   r     s    

c                       g | ]	}t  j|qS r*   )r   r'   r~   itemr)   rh   r*   r+   
<listcomp>      z6AsyncSession._parse_client_message.<locals>.<listcomp>c                    r   r*   )r   r'   r   r   r*   r+   r     r   parts)r   role)turnsr7   )rt   c                 s   s"    | ]}t |tod |v V  qdS )r\   Nrz   r~   br*   r*   r+   r     s     c                 s   s    | ]	}t |tjV  qd S r&   )r{   r   r`   r   r*   r*   r+   r     s    c                 S   s   g | ]	}|j d ddqS )Tr1   r   )rX   r   r*   r*   r+   r     r   r]   )realtime_inputcontentr   r^   r   r   r   r[   r*   )+logginginfor{   r   r|   r   r`   pydanticZValidationErrorrT   typer\   bytesrX   r'   rU   _FUNCTION_RESPONSE_REQUIRES_IDr   anyZFunctionResponsery   ZFunctionResponseDictgetappendLiveClientMessageDictZLiveClientToolResponseDictr   Z	PartUniontZ
t_contentsZContentZContentDictr   ZLiveClientContentDictZLiveClientRealtimeInputDictr_   ZLiveClientToolResponseZBlobDictbase64	b64decoder;   ZLiveClientContentr   )r)   r-   r.   Zformatted_inputZ
blob_inputZfunction_responses_inputr   Zfunction_response_inputZfunction_response_dictZfunction_response_typeddictr3   Zcontent_input_partscontentsZcontent_dict_listZcontent_inputZcontent_turnsr   Ztool_response_inputZrealtime_input_dictZformatted_media_chunksZclient_content_dictZfunction_response_listr*   r   r+   r/   l  sX  







 ` 


	 6  $ 

  
 	 
y


	H@
2
z"AsyncSession._parse_client_messagec                    s   | j  I d H  d S r&   )r(   close)r)   r*   r*   r+   r     s   zAsyncSession.close)NF)+__name__
__module____qualname____doc__r   r   r!   r,   r   r   r   ZContentListUnionZContentListUnionDictZLiveClientContentOrDictZLiveClientRealtimeInputOrDictZLiveClientToolResponseOrDictZFunctionResponseOrDictr   boolr0   r   rO   r9   r   r   rJ   r5   r>   r?   rA   r|   objectr   r   ri   rn   rp   rW   rs   rV   r   r/   r   r*   r*   r*   r+   r#   D   s    

&
>


















(
  1r#   c                
   @   s|   e Zd ZdZ	ddedeej fddZ	ddedeej fddZ	e
d	ejdd
dedeej dee fddZdS )	AsyncLivez+AsyncLive. The live module is experimental.Nmodelconfigc                    s  i t |dgd urtdgt jt |dg t |dgd ur?t dgd ur5t |dgd d< n
dt |dgid< t |dgd urxt dgd urdt jt jt |dgd d< ndt jt jt |dgid< t |dgd urtdgt jt jt |dg t |d	gd urtd	g fd
dt	 jt |d	gD  dd|ii}|d 
 |S )Ngeneration_configgenerationConfigresponse_modalitiesresponseModalitiesspeech_configspeechConfigsystem_instructionsystemInstructiontoolsc                    $   g | ]}t  jt j|qS r*   )r   r'   r   t_toolr   r   r*   r+   r         z1AsyncLive._LiveSetup_to_mldev.<locals>.<listcomp>setupr   )re   rf   r   r'   r   r   t_speech_configr   	t_contentt_toolsupdater)   r   r   return_valuer*   r   r+   _LiveSetup_to_mldev  st   
		
zAsyncLive._LiveSetup_to_mldevc                    s  i t |dgd urtdgt jt |dg t |dgd ur@t dgd ur5t |dgd d< n(dt |dgid< nt dgd urSd ddgi n
dddgii t |dgd urt dgd urt jt jt |dgd d< ndt jt jt |dgid< t |dgd urtd	gt jt	 jt |dg t |d
gd urtd
g fddt
 jt |d
gD  dd|ii}|d  |S )Nr   r   r   r   ZAUDIOr   r   r   r   r   c                    r   r*   )r    r'   r   r   r   r   r*   r+   r   /  r   z2AsyncLive._LiveSetup_to_vertex.<locals>.<listcomp>r   r   )re   rf   r   r'   r   r   r   r   r   r   r   r   r*   r   r+   _LiveSetup_to_vertex  s~   
	
		zAsyncLive._LiveSetup_to_vertexz?The live API is experimental and may change in future versions.)r   r4   c             	   C  s0  | j  }t| j |}|du rt }n2t|trF|ddu r%d}n
t	| j |d}tj|d|d|d||dd}n|}| j j
rv| j j
}| j jd }| d	| d
| }	| j jd }
t| j||d}t|}nbtjjdgd\}}tjjj }|| |j}| j jd }
|
dur|
dd|i | j jd }| d| d}	| j j}| j j}|drd| d| d| }t| j||d}t|}t|	|
d4 I dH (}| |I dH  t!"|j#ddI dH  t$| j |dV  W d  I dH  dS 1 I dH sw   Y  dS )a  Connect to the live server.

    The live module is experimental.

    Usage:

    .. code-block:: python

      client = genai.Client(api_key=API_KEY)
      config = {}
      async with client.aio.live.connect(model='...', config=config) as session:
        await session.send(input='Hello world!', end_of_turn=True)
        async for message in session.receive():
          print(message)
    Nr   r   r   r   r   )r   r   r   r   r   api_versionz!/ws/google.ai.generativelanguage.z+.GenerativeService.BidiGenerateContent?key=headers)r   r   z.https://www.googleapis.com/auth/cloud-platform)ZscopesAuthorizationz	Bearer {}z/ws/google.cloud.aiplatform.z#.LlmBidiService/BidiGenerateContentzpublishers/z	projects/z/locations//)Zadditional_headersFrK   )r$   r%   )%r'   Z_websocket_base_urlr   Zt_modelr   LiveConnectConfigr{   r|   r   r   api_keyZ_http_optionsr   Zconvert_to_dictr   r1   r2   googleauthdefault	transportrequestsRequestrefreshtokenr   formatlocationproject
startswithr   r"   r0   loggerr   rP   r#   )r)   r   r   base_urlZtransformed_modelrY   r   r   versionurir   Zrequest_dictrequestcreds_Zauth_reqZbearer_tokenr   r   wsr*   r*   r+   r"   ;  sz   







0zAsyncLive.connectr&   )r   r   r   r   r   r   r   r   r   r   r   
contextlibasynccontextmanagerZLiveConnectConfigOrDictr   r#   r"   r*   r*   r*   r+   r     s4    
I
Pr   ):r   r>   r   r   r1   r   typingr   r   r   r   r   r   r   Zgoogle.authr   r   Z
websocketsr	    r   r   r   r   r   r   r   r'   r   r   r   re   r   rf   modelsr   r   r   r   r   r   r   r   r   r   r   r    Zwebsockets.asyncio.clientr!   r"   ModuleNotFoundErrorZwebsockets.client	getLoggerr   r   r#   Z
BaseModuler   r*   r*   r*   r+   <module>   s`   $
    `