
    gT                    t    d dl mZ d dlmZ d dlmZ ddlmZ dZe G d d             Z	e G d	 d
             Z
y)    )annotations)copy)	dataclass   )UsageLimitExceeded)UsageUsageLimitsc                  x    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Z	d
ed<   	 ddddZ
ddZy)r   a  LLM usage associated with a request or run.

    Responsibility for calculating usage is on the model; PydanticAI simply sums the usage information across requests.

    You'll need to look up the documentation of the model you're using to convert usage to monetary costs.
    r   intrequestsN
int | Nonerequest_tokensresponse_tokenstotal_tokenszdict[str, int] | Nonedetails)r   c                  | xj                   |z  c_         dD ]7  }t        | |      }t        ||      }|| t        | ||xs d|xs dz          9 |j                  rd| j                  xs i | _        |j                  j	                         D ]1  \  }}| j                  j                  |d      |z   | j                  |<   3 yy)zIncrement the usage in place.

        Args:
            incr_usage: The usage to increment by.
            requests: The number of requests to increment by in addition to `incr_usage.requests`.
        )r   r   r   r   Nr   )r   getattrsetattrr   itemsget)self
incr_usager   f
self_valueother_valuekeyvalues           F/var/www/openai/venv/lib/python3.12/site-packages/pydantic_ai/usage.pyincrz
Usage.incr   s     	!PA q)J!*a0K%)@a*/k6FQ!GH	 Q <<-2DL(00668
U$(LL$4$4S!$<u$DS! 9     c                >    t        |       }|j                  |       |S )zAdd two Usages together.

        This is provided so it's trivial to sum usage information from multiple requests and runs.
        )r   r   )r   other	new_usages      r   __add__zUsage.__add__2   s    
 J	ur    )r   r   r   r   returnNone)r"   r   r%   r   )__name__
__module____qualname____doc__r   __annotations__r   r   r   r   r   r$    r    r   r   r      sY     Hc1!%NJ%-"&OZ&.#L*#n%)G")29: E&r    r   c                  j    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	Z	dd
Z
ddZy)r	   aE  Limits on model usage.

    The request count is tracked by pydantic_ai, and the request limit is checked before each request to the model.
    Token counts are provided in responses from the model, and the token limits are checked after each response.

    Each of the limits can be set to `None` to disable that limit.
    2   r   request_limitNrequest_tokens_limitresponse_tokens_limittotal_tokens_limitc                h    t        d | j                  | j                  | j                  fD              S )ax  Returns `True` if this instance places any limits on token counts.

        If this returns `False`, the `check_tokens` method will never raise an error.

        This is useful because if we have token limits, we need to check them after receiving each streamed message.
        If there are no limits, we can skip that processing in the streaming response iterator.
        c              3  $   K   | ]  }|d u 
 y w)Nr,   ).0limits     r   	<genexpr>z/UsageLimits.has_token_limits.<locals>.<genexpr>W   s      
i is   )anyr0   r1   r2   )r   s    r   has_token_limitszUsageLimits.has_token_limitsO   s8      
33T5O5OQUQhQhi
 
 	
r    c                \    | j                   }||j                  |k\  rt        d|       yy)z[Raises a `UsageLimitExceeded` exception if the next request would exceed the request_limit.Nz3The next request would exceed the request_limit of )r/   r   r   )r   usager/   s      r   check_before_requestz UsageLimits.check_before_request\   s<    **$=)H$'Z[hZi%jkk *I$r    c                   |j                   xs d}| j                  +|| j                  kD  rt        d| j                   d|d      |j                  xs d}| j                  +|| j                  kD  rt        d| j                   d|d      |j
                  xs d}| j                  ,|| j                  kD  rt        d| j                   d	|d      yy)
zURaises a `UsageLimitExceeded` exception if the usage exceeds any of the token limits.r   Nz%Exceeded the request_tokens_limit of z (request_tokens=)z&Exceeded the response_tokens_limit of z (response_tokens=z#Exceeded the total_tokens_limit of z (total_tokens=)r   r0   r   r   r1   r   r2   )r   r;   r   r   r   s        r   check_tokenszUsageLimits.check_tokensb   s   --2$$0^dF_F_5_$78Q8Q7RRdUcTeefg   //41%%1oHbHb6b$89S9S8TTgWfVhhij  )).Q"".<$BYBY3Y$'J4KbKbJccsfrettu%vww 4Z.r    )r%   bool)r;   r   r%   r&   )r'   r(   r)   r*   r/   r+   r0   r1   r2   r9   r<   r?   r,   r    r   r	   r	   <   sQ     !#M:">'+*+H(,:,K%)
)R
lxr    r	   N)
__future__r   _annotationsr   dataclassesr   
exceptionsr   __all__r   r	   r,   r    r   <module>rF      sL    2  ! *
  - - -` 5x 5x 5xr    