o
    i
                 
   @  s  U d dl mZ d dlZd dlZd dlmZmZ d dlm	Z	 d dl
mZmZmZmZ d dlmZ d dlm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mZ d d
l m!Z! d dl"m#Z# ddl$m%Z%m&Z& ddl&m'Z(m)Z* ddl+m,Z, ddl-m.Z. erddl/m0Z0 ed Z1de2d< ed Z3de2d< ed Z4de2d< ed Z5de2d< ed Z6de2d< ed Z7de2d< ed Z8de2d < ed! Z9de2d"< ed# Z:de2d$< 	 ed%d&G d'd( d(Z;dd-d.Z<ed%d%d/G d0d1 d1eZ=ed%d%d/G d2d3 d3e=Z>ed%d%d/G d4d5 d5e=Z?ed%d%d/G d6d7 d7e=Z@ed%d%d/G d8d9 d9e=ZAed%d%d/G d:d; d;ZBG d<d= d=eBZCeG d>d? d?ZDe@e?B eAB e>B eBB ZEeFeEB eDB ZGde2d@< ed%d&G dAdB dBZHdCdDdEdFdGdHdIdJdKd	ZIdLe2dM< dNdOdPdQdRdSdTZJdUe2dV< dWdXdYdZdZKd[e2d\< d]d^d_d`dadbdcdddZLdee2df< ed%d&G dgdh dhZMejNeejOdidjdjdkdlZPdme2dn< ed%d&G dodp dpZQed%d&G dqdr dreQZRed%d&G dsdt dteQZSejNeTejU ejOdidudlZVed%d&G dvdw dwZWee;eMB eRB eWB eXdxf ZY	 ed%d&G dydz dzZZed%d&G d{d| d|Z[ed%d&G d}d~ d~Z\ed%d&G dd dZ]ed%d&G dd dZ^ed%d&G dd de^Z_ed%d&G dd de^Z`ee[e_B e`B eSB e\B e]B eXdxf Za	 ed%d&G dd dZbeeZebB eXdf Zc	 ejNeTec ejOdidjdjdkdlZd	 ed%d&G dd dZeed%didG dd dZfed%didG dd dZgeeeefB egB eXdf Zh	 ed%didG dd dZied%didG dd dZjed%didG dd dZked%didG dd dZleeiejB ekB elB eXdf Zm	 ed%d&G dd dZned%d&G dd dZoe#ded%d&G dd dZpe#ded%d&G dd dZqeeneoB epB eqB eXdf Zr	 eemerB eXdf ZsdS )    )annotationsN)ABCabstractmethod)Sequence)KW_ONLY	dataclassfieldreplace)datetime)
guess_type)TYPE_CHECKING	AnnotatedAnyLiteral	TypeAliascastoverload)
calc_pricetypes)Event)
deprecated   )_otel_messages_utils)generate_tool_call_idnow_utc)UnexpectedModelBehavior)RequestUsage)InstrumentationSettings)	audio/wav
audio/mpeg	audio/ogg
audio/flac
audio/aiff	audio/aacr   AudioMediaType)
image/jpeg	image/png	image/gif
image/webpImageMediaType)	application/pdf
text/plainztext/csvGapplication/vnd.openxmlformats-officedocument.wordprocessingml.documentAapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheetz	text/htmltext/markdownapplication/mswordapplication/vnd.ms-excelDocumentMediaType)video/x-matroskavideo/quicktime	video/mp4
video/webmvideo/x-flv
video/mpegvideo/x-ms-wmv
video/3gppVideoMediaType)wavmp3ogaflacaiffaacAudioFormat)jpegpnggifwebpImageFormat)	csvdocdocxhtmlmdpdftxtxlsxlsxDocumentFormat)	mkvmovmp4webmflvmpegmpgwmvthree_gpVideoFormat)stoplengthcontent_filter	tool_callerrorFinishReasonF)reprc                   @  sn   e Zd ZU dZded< 	 ded< eedZded< 	 d	Zd
ed< 	 dZ	ded< 	 dddZ
dddZejZd	S )SystemPromptPartzA system prompt, generally written by the application developer.

    This gives the model context and guidance on how to respond.
    strcontentr   _default_factoryr
   	timestampN
str | Nonedynamic_refzsystem-promptzLiteral['system-prompt']	part_kindsettingsr   returnr   c                 C  s*   t dddi|jrd| jidS i dS )Nzgen_ai.system.messagerolesystemre   body)r   include_contentre   selfrm    rv   Z/var/www/html/karishye-ai-python/venv/lib/python3.10/site-packages/pydantic_ai/messages.py
otel_eventZ   s   zSystemPromptPart.otel_event list[_otel_messages.MessagePart]c                 C  s,   t jdddi|jrd| jigS i gS )Ntypetextre   rv   )r   TextPartrs   re   rt   rv   rv   rw   otel_message_parts`   s   ,z#SystemPromptPart.otel_message_partsrm   r   rn   r   rm   r   rn   ry   )__name__
__module____qualname____doc____annotations__r   _now_utcri   rk   rl   rx   r}   r   dataclasses_no_defaults_repr__repr__rv   rv   rv   rw   rc   B   s   
 


rc   
identifierstr | bytesrn   rd   c                 C  s*   t | tr
| d} t|  dd S )zqGenerate stable identifier for multi-modal content to help LLM in finding a specific file in tool call responses.zutf-8N   )
isinstancerd   encodehashlibsha1	hexdigest)r   rv   rv   rw   _multi_modal_content_identifierf   s   

r   )initrb   c                   @  s   e Zd ZU dZded< 	 ded< dZded< 	 d	Zd
ed< 	 edd	dZded< edd	dZ	ded< d	d	dd	dd!ddZ
ejed"ddZejed"ddZed"ddZeed"dd ZejZd	S )#FileUrlz+Abstract base class for any URL-based file.rd   urlr   rf   Fboolforce_downloadNdict[str, Any] | Nonevendor_metadatacomparedefaultzUAnnotated[str | None, pydantic.Field(alias='media_type', default=None, exclude=True)]_media_typeUAnnotated[str | None, pydantic.Field(alias='identifier', default=None, exclude=True)]_identifier)
media_typer   r   r   r   rj   r   rn   Nonec                C  s"   || _ || _|| _|| _|| _d S N)r   r   r   r   r   )ru   r   r   r   r   r   rv   rv   rw   __init__   s
   	
zFileUrl.__init__c                 C  s   | j p|  S )zQReturn the media type of the file, based on the URL or the provided `media_type`.)r   _infer_media_typeru   rv   rv   rw   r      s   zFileUrl.media_typec                 C     | j pt| jS )a  The identifier of the file, such as a unique ID.

        This identifier can be provided to the model in a message to allow it to refer to this file in a tool call argument,
        and the tool can look up the file in question by iterating over the message history and finding the matching `FileUrl`.

        This identifier is only automatically passed to the model when the `FileUrl` is returned by a tool.
        If you're passing the `FileUrl` as a user message, it's up to you to include a separate text part with the identifier,
        e.g. "This is file <identifier>:" preceding the `FileUrl`.

        It's also included in inline-text delimiters for providers that require inlining text documents, so the model can
        distinguish multiple files.
        )r   r   r   r   rv   rv   rw   r         zFileUrl.identifierc                 C     t )z2Infer the media type of the file based on the URL.NotImplementedErrorr   rv   rv   rw   r         zFileUrl._infer_media_typec                 C  r   )zThe file format.r   r   rv   rv   rw   format   s   zFileUrl.format)r   rd   r   rj   r   rj   r   r   r   r   rn   r   rn   rd   )r   r   r   r   r   r   r   r   r   r   r   pydanticcomputed_fieldpropertyr   r   r   r   r   r   r   r   rv   rv   rv   rw   r   m   s@   
 
r   c                      s|   e Zd ZU dZded< 	 ded< dZded< 	 d	d	d
d	dd	d	dd! fddZd"ddZed#ddZ	ed$dd Z
  ZS )%VideoUrlzA URL to a video.rd   r   r   rf   z	video-urlLiteral['video-url']kindNFr   r   r   r   r   r   r   r   rj   r   r   r   r   r   r   r   rn   r   c          	        (   t  j||||p	||p|d || _d S N)r   r   r   r   r   superr   r   	ru   r   r   r   r   r   r   r   r   	__class__rv   rw   r         
zVideoUrl.__init__r;   c                 C  s   | j drdS | j drdS | j drdS | j dr dS | j d	r(d
S | j dr0dS | j dr8dS | j dr@dS | jrEdS td| j  d)z5Return the media type of the video, based on the url.z.mkvr3   z.movr4   z.mp4r5   z.webmr6   z.flvr7   )z.mpegz.mpgr8   z.wmvr9   z	.three_gpr:   z+Could not infer media type from video URL: ,. Explicitly provide a `media_type` instead.)r   endswith
is_youtube
ValueErrorr   rv   rv   rw   r      s*   zVideoUrl._infer_media_typec                 C     | j dS )z%True if the URL has a YouTube domain.)zhttps://youtu.be/zhttps://youtube.com/zhttps://www.youtube.com/)r   
startswithr   rv   rv   rw   r         zVideoUrl.is_youtuber[   c                 C  
   t | j S )zThe file format of the video.

        The choice of supported formats were based on the Bedrock Converse API. Other APIs don't require to use a format.
        )_video_format_lookupr   r   rv   rv   rw   r        
zVideoUrl.format)r   rd   r   rj   r   rj   r   r   r   r   r   r   r   rj   r   rj   rn   r   )rn   r;   rn   r   )rn   r[   )r   r   r   r   r   r   r   r   r   r   r   __classcell__rv   rv   r   rw   r      s(   
 
r   c                      n   e Zd ZU dZded< 	 ded< dZded< 	 d	d	d
d	dd	d	dd fddZd ddZed!ddZ	  Z
S )"AudioUrlzA URL to an audio file.rd   r   r   rf   z	audio-urlLiteral['audio-url']r   NFr   r   rj   r   r   r   r   r   r   r   rn   r   c          	        r   r   r   r   r   rv   rw   r     r   zAudioUrl.__init__r%   c                 C  sr   | j drdS | j drdS | j drdS | j dr dS | j d	r(d
S | j dr0dS td| j  d)zReturn the media type of the audio file, based on the url.

        References:
        - Gemini: https://ai.google.dev/gemini-api/docs/audio#supported-formats
        z.mp3r    z.wavr   z.flacr"   z.ogar!   z.aiffr#   z.aacr$   z+Could not infer media type from audio URL: r   r   r   r   r   rv   rv   rw   r   /  s   zAudioUrl._infer_media_typerB   c                 C  r   )z"The file format of the audio file.)_audio_format_lookupr   r   rv   rv   rw   r   F     
zAudioUrl.format)r   rd   r   rj   r   rj   r   r   r   r   r   r   r   rj   r   rj   rn   r   )rn   r%   )rn   rB   r   r   r   r   r   r   r   r   r   r   r   rv   rv   r   rw   r     s$   
 
r   c                      r   )"ImageUrlzA URL to an image.rd   r   r   rf   z	image-urlLiteral['image-url']r   NFr   r   rj   r   r   r   r   r   r   r   rn   r   c          	        r   r   r   r   r   rv   rw   r   X  r   zImageUrl.__init__r*   c                 C  sR   | j drdS | j drdS | j drdS | j dr dS td	| j  d
)z5Return the media type of the image, based on the url.)z.jpgz.jpegr&   z.pngr'   z.gifr(   z.webpr)   z+Could not infer media type from image URL: r   r   r   rv   rv   rw   r   n  s   zImageUrl._infer_media_typerG   c                 C  r   )zThe file format of the image.

        The choice of supported formats were based on the Bedrock Converse API. Other APIs don't require to use a format.
        )_image_format_lookupr   r   rv   rv   rw   r   }  r   zImageUrl.format)r   rd   r   rj   r   rj   r   r   r   r   r   r   r   rj   r   rj   rn   r   )rn   r*   )rn   rG   r   rv   rv   r   rw   r   L  s$   
 
r   c                      sn   e Zd ZU dZded< 	 ded< dZded< 	 d	d	d
d	dd	d	dd fddZdddZed ddZ	  Z
S )!DocumentUrlzThe URL of the document.rd   r   r   rf   zdocument-urlLiteral['document-url']r   NFr   r   rj   r   r   r   r   r   r   r   rn   r   c          	        r   r   r   r   r   rv   rw   r     r   zDocumentUrl.__init__c                 C  s   | j drdS | j drdS | j drdS | j dr dS | j d	r(d
S | j dr0dS | j dr8dS | j dr@dS | j drHdS t| j \}}|du r\td| j  d|S )z8Return the media type of the document, based on the url.)z.mdz.mdxz	.markdownr/   z	.asciidocztext/x-asciidocz.txtr,   z.pdfr+   z.rtfzapplication/rtfz.docr0   z.docxr-   z.xlsr1   z.xlsxr.   Nz.Could not infer media type from document URL: r   )r   r   r   r   )ru   type_rf   rv   rv   rw   r     s0   zDocumentUrl._infer_media_typerQ   c              
   C  s:   | j }zt| W S  ty } ztd| |d}~ww )zThe file format of the document.

        The choice of supported formats were based on the Bedrock Converse API. Other APIs don't require to use a format.
        zUnknown document media type: N)r   _document_format_lookupKeyErrorr   )ru   r   erv   rv   rw   r     s   
zDocumentUrl.format)r   rd   r   rj   r   rj   r   r   r   r   r   r   r   rj   r   rj   rn   r   r   )rn   rQ   r   rv   rv   r   rw   r     s$   
 
r   c                   @  s   e Zd ZU dZded< 	 ded< ded< 	 dZd	ed
< 	 edddZded< dZded< 	 dddddd0ddZ	e
d1ddZed2dd Zejed3d!d"Zed3d#d$Zed4d&d'Zed4d(d)Zed4d*d+Zed4d,d-Zed3d.d/ZejZdS )5BinaryContentz,Binary content, e.g. an audio or image file.bytesdatar   rf   9AudioMediaType | ImageMediaType | DocumentMediaType | strr   Nr   r   Fr   r   r   binaryLiteral['binary']r   r   r   r   r   r   rj   rn   r   c                C  s&   || _ || _|p	|| _|| _|| _d S r   )r   r   r   r   r   ru   r   r   r   r   r   r   rv   rv   rw   r     s
   

zBinaryContent.__init__bcBinaryContent | BinaryImagec                 C  s"   | j rt| j| j| j| jdS | S )zINarrow the type of the `BinaryContent` to `BinaryImage` if it's an image.r   r   r   r   )is_imageBinaryImager   r   r   r   )r   rv   rv   rw   narrow_type  s   zBinaryContent.narrow_typedata_urird   c                 C  sJ   d}| |std|t|d dd\}}| | t||dS )z)Create a `BinaryContent` from a data URI.data:z Data URI must start with "data:"N;base64,r   )r   r   )r   r   lensplitr   base64	b64decode)clsr   prefixr   r   rv   rv   rw   from_data_uri  s
   
zBinaryContent.from_data_uric                 C  r   )a$  Identifier for the binary content, such as a unique ID.

        This identifier can be provided to the model in a message to allow it to refer to this file in a tool call argument,
        and the tool can look up the file in question by iterating over the message history and finding the matching `BinaryContent`.

        This identifier is only automatically passed to the model when the `BinaryContent` is returned by a tool.
        If you're passing the `BinaryContent` as a user message, it's up to you to include a separate text part with the identifier,
        e.g. "This is file <identifier>:" preceding the `BinaryContent`.

        It's also included in inline-text delimiters for providers that require inlining text documents, so the model can
        distinguish multiple files.
        )r   r   r   r   rv   rv   rw   r     r   zBinaryContent.identifierc                 C  s   d| j  dt| j  S )z*Convert the `BinaryContent` to a data URI.r   r   )r   r   	b64encoder   decoder   rv   rv   rw   r   &  s   zBinaryContent.data_urir   c                 C  r   )z1Return `True` if the media type is an audio type.zaudio/r   r   r   rv   rv   rw   is_audio+  r   zBinaryContent.is_audioc                 C  r   )z1Return `True` if the media type is an image type.zimage/r   r   rv   rv   rw   r   0  r   zBinaryContent.is_imagec                 C  r   )z0Return `True` if the media type is a video type.zvideo/r   r   rv   rv   rw   is_video5  r   zBinaryContent.is_videoc                 C  s
   | j tv S )z3Return `True` if the media type is a document type.)r   r   r   rv   rv   rw   is_document:  r   zBinaryContent.is_documentc              
   C  sn   z!| j r
t| j W S | jrt| j W S | jrt| j W S t| j W S  ty6 } z	t	d| j |d}~ww )z&The file format of the binary content.zUnknown media type: N)
r   r   r   r   r   r   r   r   r   r   )ru   r   rv   rv   rw   r   ?  s   zBinaryContent.format)r   r   r   r   r   rj   r   r   r   r   r   rj   rn   r   )r   r   rn   r   )r   rd   rn   r   r   r   )r   r   r   r   r   r   r   r   r   r   staticmethodr   classmethodr   r   r   r   r   r   r   r   r   r   r   r   r   r   rv   rv   rv   rw   r     sN   
 
r   c                      s.   e Zd ZdZdddddd fddZ  ZS )r   z0Binary content that's guaranteed to be an image.Nr   r   r   r   r   rd   r   rj   r   r   r   r   r   c                  s*   t  j|||p||d | jstdd S )Nr   zA`BinaryImage` must be have a media type that starts with "image/")r   r   r   r   r   r   rv   rw   r   T  s   zBinaryImage.__init__)r   r   r   rd   r   rj   r   r   r   r   r   rj   )r   r   r   r   r   r   rv   rv   r   rw   r   Q  s    r   c                   @  s   e Zd ZU dZdZded< dS )
CachePointzA cache point marker for prompt caching.

    Can be inserted into UserPromptPart.content to mark cache boundaries.
    Models that don't support caching will filter these out.

    Supported by:

    - Anthropic
    zcache-pointzLiteral['cache-point']r   N)r   r   r   r   r   r   rv   rv   rv   rw   r   g  s   
 
r   UserContentc                   @  sR   e Zd ZU dZded< 	 ded< dZded< 	 dZded	< 	 d
Zded< ej	Z
dS )
ToolReturnar  A structured return value for tools that need to provide both a return value and custom content to the model.

    This class allows tools to return complex responses that include:
    - A return value for actual tool return
    - Custom content (including multi-modal content) to be sent to the model as a UserPromptPart
    - Optional metadata for application use
    r   return_valuer   rf   N"str | Sequence[UserContent] | Nonere   metadatatool-returnLiteral['tool-return']r   )r   r   r   r   r   re   r   r   r   r   r   rv   rv   rv   rw   r   {  s   
 
r   rM   rN   rH   rJ   rP   rK   rL   rI   rO   zdict[str, DocumentFormat]r   r=   r<   r?   r>   r@   rA   )r    r   r"   r!   r#   r$   zdict[str, AudioFormat]r   rC   rD   rE   rF   zdict[str, ImageFormat]r   rR   rS   rT   rU   rV   rW   rY   rZ   zdict[str, VideoFormat]r   c                   @  s`   e Zd ZU dZded< 	 ded< eedZded< 	 d	Zd
ed< 	 dddZ	dddZ
ejZdS )UserPromptParta)  A user prompt, generally written by the end user.

    Content comes from the `user_prompt` parameter of [`Agent.run`][pydantic_ai.agent.AbstractAgent.run],
    [`Agent.run_sync`][pydantic_ai.agent.AbstractAgent.run_sync], and [`Agent.run_stream`][pydantic_ai.agent.AbstractAgent.run_stream].
    zstr | Sequence[UserContent]re   r   rf   rg   r
   ri   zuser-promptzLiteral['user-prompt']rl   rm   r   rn   r   c                 C  s~   dd |  |D }|D ]}|d dkrd|v r|d|d< qdd |D }|ddig| jgfv r6|d	 }td
|dddS )Nc                 S  s   g | ]}d | di|qS )r   rz   )pop.0partrv   rv   rw   
<listcomp>      z-UserPromptPart.otel_event.<locals>.<listcomp>r   r   re   binary_contentc                 S  s,   g | ]}|d | ddkr|d n|qS )r{   re   )r   re   )getr  rv   rv   rw   r    s     r{   r   gen_ai.user.messageuserre   ro   rq   )r}   r   re   r   )ru   rm   re   r  rv   rv   rw   rx     s   zUserPromptPart.otel_eventry   c                 C  s  g }t | jtr| jgn| j}|D ]o}t |tr-|tjdddi|jr'd|ini  qt |ttB t	B t
B rO|tjdd|ji|jrId|jini  qt |trrtjd|jd}|jrl|jrlt|j |d< || qt |trxq|d|ji q|S )Nrz   r{   re   r   r   rz   r   rv   )r   re   rd   appendr   r|   rs   r   r   r   r   MediaUrlPartr   r   r   BinaryDataPartr   include_binary_contentr   r   r   r   r   )ru   rm   partsre   r  converted_partrv   rv   rw   r}     s0   
 

z!UserPromptPart.otel_message_partsNr~   r   )r   r   r   r   r   r   r   ri   rl   rx   r}   r   r   r   rv   rv   rv   rw   r     s   
 


r   Tr   )defer_buildser_json_bytesval_json_bytes)configzpydantic.TypeAdapter[Any]tool_return_tac                   @  s   e Zd ZU dZded< 	 ded< 	 eedZded< 	 ded	< d
Zded< 	 ee	dZ
ded< 	 dddZd ddZd!ddZd"ddZd#ddZejZd
S )$BaseToolReturnPartz!Base class for tool return parts.rd   	tool_namer   re   rg   tool_call_idr   rf   Nr   r
   ri   rn   c                 C  s"   t | jtr	| jS t| j S )z<Return a string representation of the content for the model.)r   re   rd   r  	dump_jsonr   r   rv   rv   rw   model_response_str  s   z%BaseToolReturnPart.model_response_strdict[str, Any]c                 C  s&   t j| jdd}t|tr|S d|iS )zYReturn a dictionary representation of the content, wrapping non-dict types appropriately.json)moder   )r  dump_pythonre   r   dict)ru   json_contentrv   rv   rw   model_response_object  s   
z(BaseToolReturnPart.model_response_objectrm   r   r   c                 C  s0   t di |jrd| jini d| j| jddS )Ngen_ai.tool.messagere   toolro   idnamerq   )r   rs   re   r  r  rt   rv   rv   rw   rx   $  s   zBaseToolReturnPart.otel_eventry   c                 C  sF   ddl m} tjd| j| jd}|jr | jd ur || j|d< |gS )Nr   InstrumentedModeltool_call_responserz   r&  r'  result)	models.instrumentedr)  r   ToolCallResponsePartr  r  rs   re   serialize_any)ru   rm   r)  r  rv   rv   rw   r}   /  s   z%BaseToolReturnPart.otel_message_partsr   c                 C  s
   | j duS )z-Return `True` if the tool return has content.Nre   r   rv   rv   rw   has_content=     
zBaseToolReturnPart.has_contentr   rn   r  r~   r   r   )r   r   r   r   r   r   _generate_tool_call_idr  r   r   ri   r  r"  rx   r}   r1  r   r   r   rv   rv   rv   rw   r    s&   
 


	


r  c                   @  &   e Zd ZU dZded< dZded< dS )ToolReturnPartzAA tool return message, this encodes the result of running a tool.r   rf   r   r   rl   Nr   r   r   r   r   rl   rv   rv   rv   rw   r6  D  
   
 r6  c                   @  4   e Zd ZU dZded< dZded< 	 dZded	< dS )
BuiltinToolReturnPartz+A tool return message from a built-in tool.r   rf   Nrj   provider_namezbuiltin-tool-returnzLiteral['builtin-tool-return']rl   r   r   r   r   r   r;  rl   rv   rv   rv   rw   r:  N  s   
 r:  )r  c                   @  s   e Zd ZU dZded< 	 ded< dZded< 	 eed	Zd
ed< 	 ee	d	Z
ded< 	 dZded< 	 dddZdddZdddZejZdS )RetryPromptParta  A message back to a model asking it to try again.

    This can be sent for a number of reasons:

    * Pydantic validation of tool arguments failed, here content is derived from a Pydantic
      [`ValidationError`][pydantic_core.ValidationError]
    * a tool raised a [`ModelRetry`][pydantic_ai.exceptions.ModelRetry] exception
    * no tool was found for the tool name
    * the model returned plain text when a structured response was expected
    * Pydantic validation of a structured response failed, here content is derived from a Pydantic
      [`ValidationError`][pydantic_core.ValidationError]
    * an output validator raised a [`ModelRetry`][pydantic_ai.exceptions.ModelRetry] exception
    z&list[pydantic_core.ErrorDetails] | strre   r   rf   Nrj   r  rg   rd   r  r
   ri   zretry-promptzLiteral['retry-prompt']rl   rn   c                 C  s   t | jtr| jdu rd| j }n1| j}n-tj| jddhidd}t | jto.t| jdk}t| j d|r9d	nd
 d|  d}| dS )z>Return a string message describing why the retry is requested.NzValidation feedback:
__all__ctx   )excludeindentr   z validation errors z
:
```json
z
```z

Fix the errors and try again.)	r   re   rd   r  error_details_tar  listr   r   )ru   descriptionjson_errorspluralrv   rv   rw   model_response  s   
&
zRetryPromptPart.model_responserm   r   r   c                 C  sR   | j d u rtd|  dddS tdi |jrd|  ini d| j| j ddS )	Nr  r	  r
  rq   r#  re   r$  r%  )r  r   rJ  rs   r  rt   rv   rv   rw   rx     s   
zRetryPromptPart.otel_eventry   c                 C  sJ   | j d u rtjd|  dgS tjd| j| j d}|jr"|  |d< |gS )Nr{   )rz   re   r*  r+  r,  )r  r   r|   rJ  r.  r  rs   )ru   rm   r  rv   rv   rw   r}     s   
z"RetryPromptPart.otel_message_partsr   r~   r   )r   r   r   r   r   r  r   r4  r  r   ri   rl   rJ  rx   r}   r   r   r   rv   rv   rv   rw   r=  ^  s"   
 



r=  rl   c                   @  sh   e Zd ZU dZded< 	 ded< dZded< 	 d	Zd
ed< 	 dZded< 	 edddddZ	e
jZdS )ModelRequestzmA request generated by Pydantic AI and sent to a model, e.g. a message from the Pydantic AI app to the model.zSequence[ModelRequestPart]r  r   rf   Nrj   instructionsrequestzLiteral['request']r   run_id)rL  user_promptrd   rn   c                C  s   | t |g|dS )z:Create a `ModelRequest` with a single user prompt as text.)r  rL  )r   )r   rO  rL  rv   rv   rw   user_text_prompt  s   zModelRequest.user_text_prompt)rO  rd   rL  rj   rn   rK  )r   r   r   r   r   rL  r   rN  r   rP  r   r   r   rv   rv   rv   rw   rK    s   
 
rK  c                   @  sP   e Zd ZU dZded< 	 ded< dZded< 	 d	Zd
ed< 	 dddZej	Z
dS )r|   z#A plain text response from a model.rd   re   r   rf   Nrj   r&  r{   Literal['text']rl   rn   r   c                 C  
   t | jS )z/Return `True` if the text content is non-empty.r   re   r   rv   rv   rw   r1    r2  zTextPart.has_contentr   )r   r   r   r   r   r&  rl   r1  r   r   r   rv   rv   rv   rw   r|     s   
 

r|   c                   @  sl   e Zd ZU dZded< 	 ded< dZded< 	 dZded	< 	 dZded
< 	 dZded< 	 dddZ	e
jZdS )ThinkingPartz!A thinking response from a model.rd   re   r   rf   Nrj   r&  	signaturer;  thinkingLiteral['thinking']rl   rn   r   c                 C  rR  )z3Return `True` if the thinking content is non-empty.rS  r   rv   rv   rw   r1    r2  zThinkingPart.has_contentr   )r   r   r   r   r   r&  rU  r;  rl   r1  r   r   r   rv   rv   rv   rw   rT    s   
 


rT  c                   @  s^   e Zd ZU dZded< 	 ded< dZded< 	 dZded	< 	 d
Zded< 	 dddZe	j
ZdS )FilePartzA file response from a model.zJAnnotated[BinaryContent, pydantic.AfterValidator(BinaryImage.narrow_type)]re   r   rf   Nrj   r&  r;  filezLiteral['file']rl   rn   r   c                 C  rR  )z/Return `True` if the file content is non-empty.rS  r   rv   rv   rw   r1  %  r2  zFilePart.has_contentr   )r   r   r   r   r   r&  r;  rl   r1  r   r   r   rv   rv   rv   rw   rX    s   
 

rX  c                   @  sx   e Zd ZU dZded< 	 dZded< 	 eedZded< 	 d	ed
< dZ	ded< 	 dddZ
dddZdddZejZdS )BaseToolCallPartA tool call from a model.rd   r  Nstr | dict[str, Any] | Noneargsrg   r  r   rf   rj   r&  rn   r  c                 C  sL   | j si S t| j tr| j S t| j }t|tsJ dttttf |S )zReturn the arguments as a Python dictionary.

        This is just for convenience with models that require dicts as input.
        zargs should be a dict)r]  r   r   pydantic_core	from_jsonr   rd   r   )ru   r]  rv   rv   rw   args_as_dictF  s   zBaseToolCallPart.args_as_dictc                 C  s,   | j sdS t| j tr| j S t| j  S )zReturn the arguments as a JSON string.

        This is just for convenience with models that require JSON strings as input.
        z{})r]  r   rd   r^  to_jsonr   r   rv   rv   rw   args_as_json_strS  s
   z!BaseToolCallPart.args_as_json_strr   c                 C  s$   t | jtrt| j S t| jS )z0Return `True` if the arguments contain any data.)r   r]  r   anyvaluesr   r   rv   rv   rw   r1  ^  s   
zBaseToolCallPart.has_contentr3  r   r   )r   r   r   r   r   r]  r   r4  r  r&  r`  rb  r1  r   r   r   rv   rv   rv   rw   rZ  ,  s   
 



	rZ  c                   @  r5  )ToolCallPartr[  r   rf   z	tool-callzLiteral['tool-call']rl   Nr7  rv   rv   rv   rw   re  j  r8  re  c                   @  r9  )
BuiltinToolCallPartzA tool call to a built-in tool.r   rf   Nrj   r;  zbuiltin-tool-callzLiteral['builtin-tool-call']rl   r<  rv   rv   rv   rw   rf  t  s   
 rf  c                   @  sz  e Zd ZU dZded< 	 ded< eedZded< 	 d	Zd
ed< 	 ee	dZ
ded< 	 dZded< 	 d	Zd
ed< 	 d	Zded< 	 d	Zded< 	 d	Zded< 	 d	Zd
ed< 	 edBddZedBddZedCdd ZedDd"d#ZedEd%d&ZedFd(d)Zed*dGd,d-ZdGd.d/ZdHd3d4ZdId6d7Zeed8dJd:d;Zeed<dBd=d>Zeed?dBd@dAZe j!Z"d	S )KModelResponsezNA response from a model, e.g. a message from the model to the Pydantic AI app.zSequence[ModelResponsePart]r  r   rf   rg   r   usageNrj   
model_namer
   ri   responsezLiteral['response']r   r;  z~Annotated[dict[str, Any] | None, pydantic.Field(validation_alias=pydantic.AliasChoices('provider_details', 'vendor_details'))]provider_detailszrAnnotated[str | None, pydantic.Field(validation_alias=pydantic.AliasChoices('provider_response_id', 'vendor_id'))]provider_response_idzFinishReason | Nonefinish_reasonrN  rn   c                 C  s^   g }d}| j D ]}t|tr#t|tr|d  |j7  < n||j |}q|s*dS d|S )zGet the text in the response.N

)r  r   r|   re   r  join)ru   texts	last_partr  rv   rv   rw   r{     s   



zModelResponse.textc                 C  s"   dd | j D }|sdS d|S )z!Get the thinking in the response.c                 S     g | ]
}t |tr|jqS rv   )r   rT  re   r  rv   rv   rw   r        z*ModelResponse.thinking.<locals>.<listcomp>Nro  )r  rp  )ru   thinking_partsrv   rv   rw   rV    s   
zModelResponse.thinkinglist[BinaryContent]c                 C     dd | j D S )zGet the files in the response.c                 S  rs  rv   )r   rX  re   r  rv   rv   rw   r    rt  z'ModelResponse.files.<locals>.<listcomp>r  r   rv   rv   rw   files     zModelResponse.fileslist[BinaryImage]c                 C  rw  )zGet the images in the response.c                 S     g | ]	}t |tr|qS rv   )r   r   )r  rY  rv   rv   rw   r        z(ModelResponse.images.<locals>.<listcomp>)ry  r   rv   rv   rw   images  rz  zModelResponse.imageslist[ToolCallPart]c                 C  rw  )z#Get the tool calls in the response.c                 S  r|  rv   )r   re  r  rv   rv   rw   r    r}  z,ModelResponse.tool_calls.<locals>.<listcomp>rx  r   rv   rv   rw   
tool_calls  rz  zModelResponse.tool_calls7list[tuple[BuiltinToolCallPart, BuiltinToolReturnPart]]c                   s:   dd | j D }|sg S dd | j D   fdd|D S )z7Get the builtin tool calls and results in the response.c                 S  r|  rv   )r   rf  r  rv   rv   rw   r    r}  z4ModelResponse.builtin_tool_calls.<locals>.<listcomp>c                 S  s   i | ]}t |tr|j|qS rv   )r   r:  r  r  rv   rv   rw   
<dictcomp>  r  z4ModelResponse.builtin_tool_calls.<locals>.<dictcomp>c                   s$   g | ]}|j  v r| |j  fqS rv   r  )r  	call_partreturns_by_idrv   rw   r    s
    
rx  )ru   callsrv   r  rw   builtin_tool_calls  s   
z ModelResponse.builtin_tool_callsz)`price` is deprecated, use `cost` insteadgenai_types.PriceCalculationc                 C  s   |   S r   )costr   rv   rv   rw   price  s   zModelResponse.pricec                 C  s&   | j sJ dt| j| j | j| jdS )zsCalculate the cost of the usage.

        Uses [`genai-prices`](https://github.com/pydantic/genai-prices).
        z)Model name is required to calculate price)provider_idgenai_request_timestamp)ri  r   rh  r;  ri   r   rv   rv   rw   r    s   zModelResponse.costrm   r   list[Event]c                   s(  g   fdd}| }| j D ]i}t|tr1|dg |jdd|ji|jr*d|jini d qt|t	t
B rQ|j}|dg d	|i|jrLd
|jini  qt|trw|dg d|jjd|jrs|jrsdt|jj ini  q|d }r|d d
}|d
|dgkr||d<  S )z-Return OpenTelemetry events for the response.c                    s"   ddi} t d| d} | | S )Nro   	assistantzgen_ai.assistant.messagerq   )r   r  )new_bodyevr,  rv   rw   new_event_body  s   
z1ModelResponse.otel_events.<locals>.new_event_bodyr  functionr'  	arguments)r&  rz   r  re   r   r{   r   )r   r   r  r   )r   r{   )r  r   re  
setdefaultr  r  r  rs   r]  r|   rT  rl   re   rX  r   r  r   r   r   r   r  )ru   rm   r  rr   r  r   re   text_contentrv   r  rw   otel_events	  sJ   



zModelResponse.otel_eventsry   c                   s  g }| j D ]}t|tr"|tjdddi|jrd|jini  qt|tr=|tjdddi|jr7d|jini  qt|trbtj	d|jj
d}|jr\|jr\t|jj |d< || qt|trtjd|j|jd}t|trzd	|d
< |jr|jd urddlm  t|jtr|j|d< n fdd|j D |d< || qt|trtjd|j|jd	d}|jr|jd urddlm   |j|d< || q|S )Nrz   r{   re   rV  r   r  r_   r+  Tbuiltinr   r(  r  c                   s   i | ]
\}}|  |qS rv   )r/  )r  kvr(  rv   rw   r  Y  rt  z4ModelResponse.otel_message_parts.<locals>.<dictcomp>r*  )rz   r&  r'  r  r,  rv   )r  r   r|   r  r   rs   re   rT  rX  r  r   r  r   r   r   r   rZ  re  r  r  rf  r]  r-  r)  rd   itemsr:  r.  r/  )ru   rm   r  r  r  r  return_partrv   r(  rw   r}   9  s\   







z ModelResponse.otel_message_partsz>`vendor_details` is deprecated, use `provider_details` insteadr   c                 C     | j S r   )rk  r   rv   rv   rw   vendor_detailsk     zModelResponse.vendor_detailsz=`vendor_id` is deprecated, use `provider_response_id` insteadc                 C  r  r   rl  r   rv   rv   rw   	vendor_idp  r  zModelResponse.vendor_idzG`provider_request_id` is deprecated, use `provider_response_id` insteadc                 C  r  r   r  r   rv   rv   rw   provider_request_idu  r  z!ModelResponse.provider_request_id)rn   rj   )rn   rv  )rn   r{  )rn   r  )rn   r  )rn   r  )rm   r   rn   r  r   )rn   r   )#r   r   r   r   r   r   r   rh  ri  r   ri   r   r;  rk  rl  rm  rN  r   r{   rV  ry  r~  r  r  r   r  r  r  r}   r  r  r  r   r   r   rv   rv   rv   rw   rg    sh   
 





02
rg  r   c                   @  sB   e Zd ZU dZded< 	 ded< dZded< 	 dddZejZ	dS )TextPartDeltazEA partial update (delta) for a `TextPart` to append new text content.rd   content_deltar   rf   r{   rQ  part_delta_kindr  ModelResponsePartrn   r|   c                 C  s&   t |ts	tdt||j| j dS )a*  Apply this text delta to an existing `TextPart`.

        Args:
            part: The existing model response part, which must be a `TextPart`.

        Returns:
            A new `TextPart` with updated text content.

        Raises:
            ValueError: If `part` is not a `TextPart`.
        z,Cannot apply TextPartDeltas to non-TextPartsr0  )r   r|   r   r	   re   r  ru   r  rv   rv   rw   apply  s   
zTextPartDelta.applyN)r  r  rn   r|   )
r   r   r   r   r   r  r  r   r   r   rv   rv   rv   rw   r    s   
 

r  )rb   kw_onlyc                   @  sv   e Zd ZU dZdZded< 	 dZded< 	 dZded< 	 dZded	< 	 e	dddZ
e	dddZ
dddZ
ejZdS )ThinkingPartDeltazMA partial update (delta) for a `ThinkingPart` to append new thinking content.Nrj   r  signature_deltar;  rV  rW  r  r  r  rn   rT  c                 C     d S r   rv   r  rv   rv   rw   r       zThinkingPartDelta.apply%ModelResponsePart | ThinkingPartDelta ThinkingPart | ThinkingPartDeltac                 C  r  r   rv   r  rv   rv   rw   r    r  c                 C  s   t |tr/| jr|j| j n|j}| jdur| jn|j}| jdur$| jn|j}t||||dS t |trm| jdu rB| jdu rBt	d| jdurSt||jpMd| j d}| jdur_t|| jd}| jdurkt|| jd}|S t	d|d	| d
)aB  Apply this thinking delta to an existing `ThinkingPart`.

        Args:
            part: The existing model response part, which must be a `ThinkingPart`.

        Returns:
            A new `ThinkingPart` with updated thinking content.

        Raises:
            ValueError: If `part` is not a `ThinkingPart`.
        N)re   rU  r;  z;Cannot apply ThinkingPartDelta with no content or signaturerD  )r  )r  )r;  zUCannot apply ThinkingPartDeltas to non-ThinkingParts or non-ThinkingPartDeltas (part=, self=))
r   rT  r  re   r  rU  r;  r	   r  r   )ru   r  new_contentnew_signaturenew_provider_namerv   rv   rw   r    s$   




)r  r  rn   rT  )r  r  rn   r  )r   r   r   r   r  r   r  r;  r  r   r  r   r   r   rv   rv   rv   rw   r    s    
 

r  c                   @  s   e Zd ZU dZdZded< 	 dZded< 	 dZded< 	 dZd	ed
< 	 dddZ	e
dddZe
dddZdddZd ddZd!ddZejZdS )"ToolCallPartDeltaz^A partial update (delta) for a `ToolCallPart` to modify tool name, arguments, or tool call ID.Nrj   tool_name_deltar\  
args_deltar  r_   zLiteral['tool_call']r  rn   ToolCallPart | Nonec                 C  s&   | j du rdS t| j | j| jpt S )zConvert this delta to a fully formed `ToolCallPart` if possible, otherwise return `None`.

        Returns:
            A `ToolCallPart` if `tool_name_delta` is set, otherwise `None`.
        N)r  re  r  r  r4  r   rv   rv   rw   as_part  s   
zToolCallPartDelta.as_partr  r  "ToolCallPart | BuiltinToolCallPartc                 C  r  r   rv   r  rv   rv   rw   r    r  zToolCallPartDelta.apply%ModelResponsePart | ToolCallPartDelta6ToolCallPart | BuiltinToolCallPart | ToolCallPartDeltac                 C  r  r   rv   r  rv   rv   rw   r    r   c                 C  s:   t |ttB r| |S t |tr| |S td| )a  Apply this delta to a part or delta, returning a new part or delta with the changes applied.

        Args:
            part: The existing model response part or delta to update.

        Returns:
            Either a new `ToolCallPart` or `BuiltinToolCallPart`, or an updated `ToolCallPartDelta`.

        Raises:
            ValueError: If `part` is neither a `ToolCallPart`, `BuiltinToolCallPart`, nor a `ToolCallPartDelta`.
            UnexpectedModelBehavior: If applying JSON deltas to dict arguments or vice versa.
        zeCan only apply ToolCallPartDeltas to ToolCallParts, BuiltinToolCallParts, or ToolCallPartDeltas, not )r   re  rf  _apply_to_partr  _apply_to_deltar   r  rv   rv   rw   r    s   


deltac                 C  s   | j r|j pd| j  }t||d}t| jtr7t|jtr(td|d| d|jp,d| j }t||d}n't| jtr^t|jtrNtd|d| di |jpSi | j}t||d}| jrht|| jd}|j d	uryt|j |j|jpwt	 S |S )
z5Internal helper to apply this delta to another delta.rD  )r  z;Cannot apply JSON deltas to non-JSON tool arguments (delta=r  r  )r  z;Cannot apply dict deltas to non-dict tool arguments (delta=r  N)
r  r	   r   r  rd   r   r   r  re  r4  )ru   r  updated_tool_name_deltaupdated_args_deltarv   rv   rw   r  &  s,   
z!ToolCallPartDelta._apply_to_deltac                 C  s   | j r|j| j  }t||d}t| jtr5t|jtr&td|d| d|jp*d| j }t||d}n't| jtr\t|jtrLtd|d| di |jpQi | j}t||d}| j	rft|| j	d}|S )	zZInternal helper to apply this delta directly to a `ToolCallPart` or `BuiltinToolCallPart`.)r  z:Cannot apply JSON deltas to non-JSON tool arguments (part=r  r  rD  )r]  z:Cannot apply dict deltas to non-dict tool arguments (part=r  )
r  r  r	   r   r  rd   r]  r   r   r  )ru   r  r  updated_jsonupdated_dictrv   rv   rw   r  E  s    z ToolCallPartDelta._apply_to_part)rn   r  )r  r  rn   r  )r  r  rn   r  )r  r  rn   r  )r  r  rn   r  )r   r   r   r   r  r   r  r  r  r  r   r  r  r  r   r   r   rv   rv   rv   rw   r    s&   
 




r  r  c                   @  H   e Zd ZU dZded< 	 ded< 	 dZded< 	 d	Zd
ed< 	 ejZ	dS )PartStartEventzAn event indicating that a new part has started.

    If multiple `PartStartEvent`s are received with the same index,
    the new one should fully replace the old one.
    intindexr  r  NcLiteral['text', 'thinking', 'tool-call', 'builtin-tool-call', 'builtin-tool-return', 'file'] | Noneprevious_part_kind
part_startzLiteral['part_start']
event_kind)
r   r   r   r   r   r  r  r   r   r   rv   rv   rv   rw   r  d  s   
 

r  c                   @  s:   e Zd ZU dZded< 	 ded< 	 dZded< 	 ejZd	S )
PartDeltaEventz8An event indicating a delta update for an existing part.r  r  ModelResponsePartDeltar  
part_deltazLiteral['part_delta']r  N	r   r   r   r   r   r  r   r   r   rv   rv   rv   rw   r    s   
 
r  c                   @  r  )PartEndEventz,An event indicating that a part is complete.r  r  r  r  Nr  next_part_kindpart_endzLiteral['part_end']r  )
r   r   r   r   r   r  r  r   r   r   rv   rv   rv   rw   r    s   
 

r  c                   @  s:   e Zd ZU dZded< 	 ded< 	 dZded< 	 ejZdS )	FinalResultEventzrAn event indicating the response to the current model request matches the output schema and will produce a result.rj   r  r  final_resultzLiteral['final_result']r  Nr  rv   rv   rv   rw   r    s   
 
r  r  c                   @  s\   e Zd ZU dZded< 	 ded< dZded< 	 edddZeeddddZ	e
jZdS )FunctionToolCallEventz;An event indicating the start to a call to a function tool.re  r  r   rf   function_tool_callzLiteral['function_tool_call']r  rn   rd   c                 C     | j jS z=An ID used for matching details about the call to its result.r  r  r   rv   rv   rw   r       z"FunctionToolCallEvent.tool_call_idz4`call_id` is deprecated, use `tool_call_id` instead.c                 C  r  r  r  r   rv   rv   rw   call_id  s   zFunctionToolCallEvent.call_idNr   )r   r   r   r   r   r  r   r  r   r  r   r   r   rv   rv   rv   rw   r    s   
 
r  c                   @  sT   e Zd ZU dZded< 	 ded< dZded< 	 d	Zd
ed< 	 edddZe	j
ZdS )FunctionToolResultEventz7An event indicating the result of a function tool call.z ToolReturnPart | RetryPromptPartr,  r   rf   Nr   re   function_tool_resultzLiteral['function_tool_result']r  rn   rd   c                 C  r  )z4An ID used to match the result to its original call.)r,  r  r   rv   rv   rw   r    r  z$FunctionToolResultEvent.tool_call_idr   )r   r   r   r   r   re   r  r   r  r   r   r   rv   rv   rv   rw   r    s   
 
r  zx`BuiltinToolCallEvent` is deprecated, look for `PartStartEvent` and `PartDeltaEvent` with `BuiltinToolCallPart` instead.c                   @  0   e Zd ZU dZded< 	 ded< dZded< d	S )
BuiltinToolCallEventz;An event indicating the start to a call to a built-in tool.rf  r  r   rf   builtin_tool_callzLiteral['builtin_tool_call']r  Nr   r   r   r   r   r  rv   rv   rv   rw   r       
 r  z|`BuiltinToolResultEvent` is deprecated, look for `PartStartEvent` and `PartDeltaEvent` with `BuiltinToolReturnPart` instead.c                   @  r  )
BuiltinToolResultEventz7An event indicating the result of a built-in tool call.r:  r,  r   rf   builtin_tool_resultzLiteral['builtin_tool_result']r  Nr  rv   rv   rv   rw   r    r  r  )r   r   rn   rd   )t
__future__r   _annotationsr   r   abcr   r   collections.abcr   dataclassesr   r   r   r	   r
   	mimetypesr   typingr   r   r   r   r   r   r   r   r^  genai_pricesr   r   genai_typesopentelemetry._eventsr   typing_extensionsr   rD  r   r   r   r4  r   r   
exceptionsr   rh  r   r-  r   r%   r   r*   r2   r;   rB   rG   rQ   r[   ra   rc   r   r   r   r   r   r   r   r   r   MultiModalContentrd   r   r   r   r   r   r   r   TypeAdapter
ConfigDictr  r  r6  r:  rF  ErrorDetailsrE  r=  DiscriminatorModelRequestPartrK  r|   rT  rX  rZ  re  rf  r  rg  ModelMessageModelMessagesTypeAdapterr  r  r  r  r  r  r  r  ModelResponseStreamEventr  r  r  r  HandleResponseEventAgentStreamEventrv   rv   rv   rw   <module>   st   $
#

S
K
>
9
L}	<G	V&=	 r

=z



