o
    iY                     @  s  U d dl mZ d dlZd dlZd dlZd dlmZmZmZm	Z	 d dl
mZmZ d dlmZmZ d dl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 d d
lmZ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* ddl+m,Z, ddl-m.Z. ddl/m0Z0m1Z1m2Z2m3Z3 ddl4m5Z5 ddl+m6Z6m7Z7m8Z8m9Z9 ddl:m;Z; dZ<dZ=de>d< e(e eZ?dZ@d-d!d"ZAed#d$G d%d& d&ZBd'ZCd(ZDed#d$G d)d* d*e;ZEG d+d, d,eFZGdS ).    )annotationsN)AsyncIteratorCallableIteratorMapping)asynccontextmanagercontextmanager)	dataclassfield)AnyLiteralcast)urlparse)PriceCalculation)EventEventLoggerEventLoggerProviderget_event_logger_provider)MeterProviderget_meter_provider)SpanTracerTracerProviderget_tracer_provider)AttributeValue)TypeAdapter)DEFAULT_INSTRUMENTATION_VERSION   )_otel_messages)
RunContext)ModelMessageModelRequestModelResponseSystemPromptPart)ModelSettings   )KnownModelNameModelModelRequestParametersStreamedResponse)WrapperModel)instrument_modelInstrumentationSettingsInstrumentedModel)
max_tokenstop_pseedtemperaturepresence_penaltyfrequency_penaltyzjtuple[Literal['max_tokens', 'top_p', 'seed', 'temperature', 'presence_penalty', 'frequency_penalty'], ...]MODEL_SETTING_ATTRIBUTES)r%         @      i   i   i @  i   i   i   i  @ i   i   modelr'   
instrumentInstrumentationSettings | boolreturnc                 C  s*   |rt | ts|du rt }t| |} | S )z.Instrument a model with OpenTelemetry/logfire.T)
isinstancer-   r,   )r9   r:    r>   e/var/www/html/karishye-ai-python/venv/lib/python3.10/site-packages/pydantic_ai/models/instrumented.pyr+   B   s
   
r+   F)initc                   @  s   e Zd ZU dZeddZded< eddZded< dZd	ed
< dZ	ded< dZ
ded< eZded< ddddedddd=ddZ	d>d?d!d"Zd@d$d%Z	d>dAd-d.ZdBd2d3ZdCd6d7ZdDd;d<ZdS )Er,   ah  Options for instrumenting models and agents with OpenTelemetry.

    Used in:

    - `Agent(instrument=...)`
    - [`Agent.instrument_all()`][pydantic_ai.agent.Agent.instrument_all]
    - [`InstrumentedModel`][pydantic_ai.models.instrumented.InstrumentedModel]

    See the [Debugging and Monitoring guide](https://ai.pydantic.dev/logfire/) for more info.
    F)reprr   tracerr   event_logger
attributesLiteral['attributes', 'logs']
event_modeTboolinclude_binary_contentinclude_contentLiteral[1, 2, 3]versionN)tracer_providermeter_providerrH   rI   rK   rF   event_logger_providerrL   TracerProvider | NonerM   MeterProvider | NonerN   EventLoggerProvider | Nonec                C  s   ddl m} |p
t }|pt }|pt }d}	||	|| _||	|| _|	|	|| _
|| _|| _|| _|dkrF|dkrFtjddd d}|| _td	d
dd}
z| jjdi |
dti| _W n tys   | jjdi |
| _Y nw | jjdddd| _dS )aF  Create instrumentation options.

        Args:
            tracer_provider: The OpenTelemetry tracer provider to use.
                If not provided, the global tracer provider is used.
                Calling `logfire.configure()` sets the global tracer provider, so most users don't need this.
            meter_provider: The OpenTelemetry meter provider to use.
                If not provided, the global meter provider is used.
                Calling `logfire.configure()` sets the global meter provider, so most users don't need this.
            include_binary_content: Whether to include binary content in the instrumentation events.
            include_content: Whether to include prompts, completions, and tool call arguments and responses
                in the instrumentation events.
            version: Version of the data format. This is unrelated to the Pydantic AI package version.
                Version 1 is based on the legacy event-based OpenTelemetry GenAI spec
                    and will be removed in a future release.
                    The parameters `event_mode` and `event_logger_provider` are only relevant for version 1.
                Version 2 uses the newer OpenTelemetry GenAI spec and stores messages in the following attributes:
                    - `gen_ai.system_instructions` for instructions passed to the agent.
                    - `gen_ai.input.messages` and `gen_ai.output.messages` on model request spans.
                    - `pydantic_ai.all_messages` on agent run spans.
            event_mode: The mode for emitting events in version 1.
                If `'attributes'`, events are attached to the span as attributes.
                If `'logs'`, events are emitted as OpenTelemetry log-based events.
            event_logger_provider: The OpenTelemetry event logger provider to use.
                If not provided, the global event logger provider is used.
                Calling `logfire.configure()` sets the global event logger provider, so most users don't need this.
                This is only used if `event_mode='logs'` and `version=1`.
        r   )__version__zpydantic-ailogsr%   zfevent_mode is only relevant for version=1 which is deprecated and will be removed in a future release.r   )
stacklevelzgen_ai.client.token.usagez{token}z/Measures number of input and output tokens used)nameunitdescription#explicit_bucket_boundaries_advisoryoperation.costz{USD}zMonetary cost)rV   rW   Nr>   )pydantic_airR   r   r   r   
get_tracerrB   	get_metermeterget_event_loggerrC   rF   rH   rI   warningswarnrK   dictcreate_histogramTOKEN_HISTOGRAM_BOUNDARIEStokens_histogram	TypeErrorcost_histogram)selfrL   rM   rH   rI   rK   rF   rN   rR   
scope_nametokens_histogram_kwargsr>   r>   r?   __init__a   sN   '




z InstrumentationSettings.__init__messageslist[ModelMessage]
parametersModelRequestParameters | Noner<   list[Event]c           
      C  s   g }t ||}|dur"|tdi | jrd|ini ddid t|D ]=\}}g }t|trE|jD ]}t	|drC||
|  q4n
t|trO|| }|D ]}	d|i|	jpZi |	_qQ|| q&|D ]	}	t |	j|	_qf|S )	zConvert a list of model messages to OpenTelemetry events.

        Args:
            messages: The messages to convert.
            parameters: The model request parameters.

        Returns:
            A list of OpenTelemetry events.
        Nzgen_ai.system.messagecontentrolesystembody
otel_eventzgen_ai.message.index)r-   _get_instructionsappendr   rI   	enumerater=   r!   partshasattrru   r"   otel_eventsrD   extendserialize_anyrt   )
rg   rk   rm   eventsinstructionsmessage_indexmessagemessage_eventsparteventr>   r>   r?   messages_to_otel_events   s8   




z/InstrumentationSettings.messages_to_otel_events list[_otel_messages.ChatMessage]c           	      C  s   g }|D ]W}t |tr=tj|jdd dD ]&\}}g }|D ]}t|dr,|||  q|t	j
|r5dnd|d qqt |tr[t	jd|| d}|jd urV|j|d	< || q|S )
Nc                 S  s
   t | tS N)r=   r#   )pr>   r>   r?   <lambda>   s   
 zCInstrumentationSettings.messages_to_otel_messages.<locals>.<lambda>)keyotel_message_partsrr   user)rq   ry   	assistantfinish_reason)r=   r!   	itertoolsgroupbyry   rz   r|   r   rw   r   ChatMessager"   OutputMessager   )	rg   rk   resultr   	is_systemgroupmessage_partsr   otel_messager>   r>   r?   messages_to_otel_messages   s(   





z1InstrumentationSettings.messages_to_otel_messagesinput_messagesresponser"   rr   strspanr   c              	   C  s  | j dkr9| ||}| |g|D ]}|tdd|jdd q|D ]}t|i|jp-i |_q$| || d S | |g}t	|dksGJ |d }	t
||}
| |
}t| |t|	gd|dtdd	d
id	d
id|rzdd	d
iini dd	diidi}|| d S )Nr%   zgen_ai.choicer   )indexr   rs   )zgen_ai.input.messageszgen_ai.output.messageslogfire.json_schemaobjecttypearraygen_ai.system_instructionsmodel_request_parametersr   
properties)rK   r   rw   r   rt   GEN_AI_SYSTEM_ATTRIBUTErD   _emit_eventsr   lenr-   rv   system_instructions_attributesjsondumpsset_attributes)rg   r   r   rr   r   rm   r~   r   output_messagesoutput_messager   r   rD   r>   r>   r?   handle_messages   sT   
	

z'InstrumentationSettings.handle_messagesr   
str | Nonedict[str, str]c                 C  s(   |r| j rdttjd|dgiS i S )Nr   text)r   rp   )rI   r   r   r   TextPart)rg   r   r>   r>   r?   r   '  s   
z6InstrumentationSettings.system_instructions_attributesr~   Nonec                 C  sj   | j dkr|D ]}| j| qd S d}||tdd |D dtd|ddid	ddiid
i d S )NrS   r~   c                 S  s   g | ]}t |qS r>   )r-   event_to_dict).0r   r>   r>   r?   
<listcomp>6  s    z8InstrumentationSettings._emit_events.<locals>.<listcomp>r   r   r   r   r   r   )rF   rC   emitr   r   r   )rg   r   r~   r   	attr_namer>   r>   r?   r   .  s    
z$InstrumentationSettings._emit_eventsprice_calculationPriceCalculation | Nonedict[str, AttributeValue]c                 C  sl   dD ]1}t |j| dd }sqi |d|i}| j|| |r3tt || d}| j|| qd S )N)inputoutput_tokensr   zgen_ai.token.type_price)getattrusagerd   recordfloatrf   )rg   r   r   rD   typtokenstoken_attributescostr>   r>   r?   record_metricsC  s   z&InstrumentationSettings.record_metrics)rL   rO   rM   rP   rH   rG   rI   rG   rK   rJ   rF   rE   rN   rQ   r   )rk   rl   rm   rn   r<   ro   )rk   rl   r<   r   )
r   rl   r   r"   rr   r   r   r   rm   rn   )r   r   r<   r   )r   r   r~   ro   r<   r   )r   r"   r   r   rD   r   )__name__
__module____qualname____doc__r
   rB   __annotations__rC   rF   rH   rI   r   rK   rj   r   r   r   r   r   r   r>   r>   r>   r?   r,   M   s0   
 U
)
6
r,   zgen_ai.systemgen_ai.request.modelc                      s   e Zd ZU dZded< 	 	d/d0 fddZd1ddZe	d/d2ddZe	d3ddZ
ed4d!d"Zed5d#d$Zed6d(d)Zed7d-d.Z  ZS )8r-   zModel which wraps another model so that requests are instrumented with OpenTelemetry.

    See the [Debugging and Monitoring guide](https://ai.pydantic.dev/logfire/) for more info.
    r,   instrumentation_settingsNwrappedModel | KnownModelNameoptionsInstrumentationSettings | Noner<   r   c                   s   t  | |p
t | _d S r   )superrj   r,   r   )rg   r   r   	__class__r>   r?   rj   a  s   zInstrumentedModel.__init__rk   rl   model_settingsModelSettings | Noner   r(   r"   c                   sj   | j ||\}}| |||}| j |||I d H }||| |W  d    S 1 s.w   Y  d S r   )r   prepare_request_instrumentrequest)rg   rk   r   r   prepared_settingsprepared_parametersfinishr   r>   r>   r?   r   i  s   
$zInstrumentedModel.requestrun_contextRunContext[Any] | NoneAsyncIterator[StreamedResponse]c           	   
   C s   | j ||\}}| |||H}d }z1| j ||||4 I d H }|V  W d   I d H  n1 I d H s6w   Y  W |rE|| | n|rP|| | w w W d    d S 1 s\w   Y  d S r   )r   r   r   request_streamget)	rg   rk   r   r   r   r   r   r   response_streamr>   r>   r?   r   x  s.   ("z InstrumentedModel.request_streamAIterator[Callable[[ModelResponse, ModelRequestParameters], None]]c                 #  s    d dj  }dij|dtddddiidi |rBtD ]}t|| }t	t
B rA| d	| < q,d z2jjj| d
d fdd}|V  W d    n1 shw   Y  W ru  d S d S r}  w w )Nchat gen_ai.operation.namer   r   r   r   r   zgen_ai.request.)rD   r   r"   rm   r(   c              
     sB   t
di  t ttt jpd   	fdd}|
 s/d S 	j	
| i j
 di}z  W n) tyS   Y n( tys } ztdt|j d| t W Y d }~nd }~ww t j|d< jd urj|d< jd urjg|d	< 
| 
 d
  d S )NrD   c                    s(   t d ddi} j|  d S )Nr   r   gen_ai.response.model)r   r   r   )metric_attributes)	operationr   request_modelr   response_modelrg   rr   r>   r?   _record_metrics  s   zFInstrumentedModel._instrument.<locals>.finish.<locals>._record_metricsr   z"Failed to get cost from response: z: rY   zgen_ai.response.idzgen_ai.response.finish_reasonsr   )updater   GEN_AI_REQUEST_MODEL_ATTRIBUTEr   r   r   
model_nameis_recordingr   r   r   opentelemetry_attributesr   LookupError	Exceptionr_   r`   r   r   CostCalculationFailedWarningr   total_priceprovider_response_idr   r   update_name)r   rm   r   attributes_to_seterD   rk   r   r   rg   r   )r   r   r   r   rr   r?   r     s@   





z-InstrumentedModel._instrument.<locals>.finish)r   r"   rm   r(   )r   model_attributesr   #model_request_parameters_attributesr   r   r4   r=   r   r   intr   rB   start_as_current_span)rg   rk   r   r   	span_namer   valuer   r>   r   r?   r     s@   

15
zInstrumentedModel._instrumentr9   r'   r   c                 C  s`   t | jt| ji}| j }r.zt|}W n
 ty   Y |S w |jr&|j|d< |jr.|j|d< |S )Nzserver.addresszserver.port)	r   rr   r   r   base_urlr   r   hostnameport)r9   rD   r  parsedr>   r>   r?   r     s   


z"InstrumentedModel.model_attributesc                 C  s   dt t| iS )Nr   )r   r   r-   r}   )r   r>   r>   r?   r     s   z5InstrumentedModel.model_request_parameters_attributesr   r   dict[str, Any]c                 C  s<   | j si }nt| j tr| j }nd| j i}i || jpi S )Nrt   )rt   r=   r   rD   )r   rt   r>   r>   r?   r     s   
zInstrumentedModel.event_to_dictr  r   r   c                 C  sb   zt j| ddW S  ty0   zt| W  Y S  ty/ } zd| W  Y d }~ Y S d }~ww w )Nr   )modezUnable to serialize: )ANY_ADAPTERdump_pythonr   r   )r  r   r>   r>   r?   r}     s   zInstrumentedModel.serialize_anyr   )r   r   r   r   r<   r   )rk   rl   r   r   r   r(   r<   r"   )
rk   rl   r   r   r   r(   r   r   r<   r   )rk   rl   r   r   r   r(   r<   r   )r9   r'   r<   r   )r   r(   r<   r   )r   r   r<   r  )r  r   r<   r   )r   r   r   r   r   rj   r   r   r   r   r   staticmethodr   r   r   r}   __classcell__r>   r>   r   r?   r-   W  s(   
 
X	r-   c                   @  s   e Zd ZdZdS )r   z+Warning raised when cost calculation fails.N)r   r   r   r   r>   r>   r>   r?   r     s    r   )r9   r'   r:   r;   r<   r'   )H
__future__r   r   r   r_   collections.abcr   r   r   r   
contextlibr   r   dataclassesr	   r
   typingr   r   r   urllib.parser   genai_prices.typesr   opentelemetry._eventsr   r   r   r   opentelemetry.metricsr   r   opentelemetry.tracer   r   r   r   opentelemetry.util.typesr   pydanticr   pydantic_ai._instrumentationr    r   _run_contextr   rk   r    r!   r"   r#   settingsr$   r&   r'   r(   r)   wrapperr*   __all__r4   r   r
  rc   r+   r,   r   r   r-   Warningr   r>   r>   r>   r?   <module>   sL    

   ?