o
    ưi	0                     @  s$  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 d dl	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mZ d d
lmZmZ d dlmZ d dlmZmZ d dl m!Z! erhd dl	m"Z" dZ#dZ$G dd deZ%d'ddZ&d(ddZ'd)d!d"Z(d'd#d$Z)G d%d& d&eZ*dS )*    )annotationsN)TYPE_CHECKINGAnyOptional)Status
StatusCode)override)verbose_logger)SpanAttributes)_utils)OpenTelemetryOpenTelemetryConfig)BaseLLMObsOTELAttributessafe_set_attribute)
safe_dumps)WeaveOtelConfigWeaveSpanAttributes)StandardCallbackDynamicParams)Spanzhttps://trace.wandb.aiz/otel/v1/tracesc                   @  s"   e Zd ZdZeed	ddZdS )
WeaveLLMObsOTELAttributesz
    Weave-specific LLM observability OTEL attributes.

    Weave automatically maps attributes from multiple frameworks including
    GenAI, OpenInference, Langfuse, and others.
    span'Span'kwargsdict[str, Any]c                 C  sp   | dpg }| dpi }d|i}| d}| d}|dur$||d< |dur,||d< t| tjt| dS )zFSet input messages as span attributes using OpenInference conventions.messagesoptional_params	functionstoolsN)getr   OpenInferenceSpanAttributesZINPUT_VALUEjsondumps)r   r   r   r   promptr   r    r#   \/home/app/Keep/.python/lib/python3.10/site-packages/litellm/integrations/weave/weave_otel.pyset_messages*   s   

z&WeaveLLMObsOTELAttributes.set_messagesN)r   r   r   r   )__name__
__module____qualname____doc__staticmethodr   r%   r#   r#   r#   r$   r   "   s
    r   r   r   r   r   response_objr   c           
      C  s  | dpi }| dpi }| dpd}| dpd}| d}|s1|r1|r/| d| }n|}|rA|dd}t| tjj| | d	 }d
uret|ttfrUt	|}t| tj
j| t| tjjd |rd
}	t|drs| }	nt|drz|}	|	rt| tjt	|	 d
S d
S d
S )z
    Sets Weave-specific metadata attributes onto the OTEL span.

    Based on Weave's OTEL attribute mappings from:
    https://github.com/wandb/weave/blob/master/weave/trace_server/opentelemetry/constants.py
    litellm_paramsmetadatamodel custom_llm_providerdisplay_name/__
session_idNT
model_dumpr   )r   replacer   r   ZDISPLAY_NAMEvalue
isinstancelistdictr   Z	THREAD_IDZIS_TURNhasattrr5   r   ZOUTPUT_VALUE)
r   r   r+   r,   r-   r.   r0   r1   r4   Zoutput_dictr#   r#   r$   _set_weave_specific_attributes<   s6   	



r<   api_keystrreturnc                 C  s&   d|  }t |  }d| S )z{
    Get the authorization header for Weave OpenTelemetry.

    Weave uses Basic auth with format: api:<WANDB_API_KEY>
    zapi:zBasic )base64	b64encodeencodedecode)r=   Zauth_stringauth_headerr#   r#   r$   _get_weave_authorization_headerj   s   

rE   r   c                  C  s   t d} t d}t d}| std|std|r6|ds&d| }|dt }td	|  ntt }td
|  t	| d}d| d| }|t j
d< |t j
d< t|||ddS )a  
    Retrieves the Weave OpenTelemetry configuration based on environment variables.

    Environment Variables:
        WANDB_API_KEY: Required. W&B API key for authentication.
        WANDB_PROJECT_ID: Required. Project ID in format <entity>/<project_name>.
        WANDB_HOST: Optional. Custom Weave host URL. Defaults to cloud endpoint.

    Returns:
        WeaveOtelConfig: A Pydantic model containing Weave OTEL configuration.

    Raises:
        ValueError: If required environment variables are missing.
    ZWANDB_API_KEYZWANDB_PROJECT_IDZ
WANDB_HOSTz>WANDB_API_KEY must be set for Weave OpenTelemetry integration.zaWANDB_PROJECT_ID must be set for Weave OpenTelemetry integration. Format: <entity>/<project_name>httpzhttps://r2   z%Using Weave OTEL endpoint from host: zUsing Weave cloud endpoint: r=   zAuthorization=z,project_id=ZOTEL_EXPORTER_OTLP_ENDPOINTZOTEL_EXPORTER_OTLP_HEADERSZ	otlp_http)otlp_auth_headersendpoint
project_idprotocol)osgetenv
ValueError
startswithrstripWEAVE_OTEL_ENDPOINTr	   debugWEAVE_BASE_URLrE   environr   )r=   rJ   hostrI   rD   rH   r#   r#   r$   get_weave_otel_configu   s4   






rV   c                 C  s"   t | ||t t| ||d dS )z
    Sets OpenTelemetry span attributes for Weave observability.
    Uses the same attribute setting logic as other OTEL integrations for consistency.
    r   r   r+   N)r   set_attributesr   r<   rW   r#   r#   r$   set_weave_otel_attributes   s   rY   c                      sN   e Zd ZdZ		dd fdd	Zd
d Z	dddZdd ZdddZ  Z	S )WeaveOtelLoggera  
    Weave (W&B) OpenTelemetry Logger for LiteLLM.

    Sends LLM traces to Weave via the OpenTelemetry Protocol (OTLP).

    Environment Variables:
        WANDB_API_KEY: Required. Weights & Biases API key for authentication.
        WANDB_PROJECT_ID: Required. Project ID in format <entity>/<project_name>.
        WANDB_HOST: Optional. Custom Weave host URL. Defaults to cloud endpoint.

    Usage:
        litellm.callbacks = ["weave_otel"]

        Or manually:
        from litellm.integrations.weave.weave_otel import WeaveOtelLogger
        weave_logger = WeaveOtelLogger(callback_name="weave_otel")
        litellm.callbacks = [weave_logger]

    Reference:
        https://docs.wandb.ai/weave/guides/tracking/otel
    N
weave_otelconfigOptional[OpenTelemetryConfig]callback_nameOptional[str]c                   s>   |du rt  }t|j|j|jd}t jd||d| dS )z
        Initialize WeaveOtelLogger.

        If config is not provided, automatically configures from environment variables
        (WANDB_API_KEY, WANDB_PROJECT_ID, WANDB_HOST) via get_weave_otel_config().
        N)ZexporterrI   headers)r\   r^   r#   )rV   r   rK   rI   rH   super__init__)selfr\   r^   r   Zweave_config	__class__r#   r$   rb      s   zWeaveOtelLogger.__init__c                 C  s   dS )z
        Override to skip creating the raw_gen_ai_request child span.

        For Weave, we only want a single span per LLM call. The parent span
        already contains all the necessary attributes, so the child span
        is redundant.
        Nr#   )rc   r   r+   
start_timeend_timeparent_spanr#   r#   r$   _maybe_log_raw_request   s   z&WeaveOtelLogger._maybe_log_raw_requestc           	      C  sZ   |  |}|j| || ||d}|ttj | ||| |j	| |d |S )z
        Override to always create a child span instead of reusing the parent span.

        This ensures that wrapper spans (like "B", "C", "D", "E") remain separate
        from the LiteLLM LLM call spans, creating proper nesting in Weave.
        )namerf   context)rg   )
Zget_tracer_to_use_for_requestZ
start_spanZ_get_span_nameZ_to_nsZ
set_statusr   r   OKrX   end)	rc   r   r+   rf   rg   rk   rh   Zotel_tracerr   r#   r#   r$   _start_primary_span   s   
z#WeaveOtelLogger._start_primary_spanc           	      C  s   t d|| j | |\}}d}| ||||||}| ||||| | j||d | |||| | jjr@| 	||| dS dS )z
        Override to prevent ending externally created parent spans.

        When wrapper spans (like "B", "C", "D", "E") are provided as parent spans,
        they should be managed by the user code, not ended by LiteLLM.
        zGWeave OpenTelemetry Logger: Logging kwargs: %s, OTEL config settings=%sN)r   rk   )
r	   rR   r\   Z_get_span_contextrn   ri   Z_create_guardrail_spanZ_record_metricsZenable_eventsZ_emit_semantic_logs)	rc   r   r+   rf   rg   ctxrh   Zprimary_span_parentr   r#   r#   r$   _handle_success	  s   zWeaveOtelLogger._handle_success standard_callback_dynamic_paramsr   r?   dict | Nonec                 C  sF   i }| d}| d}|rt|d}||d< |r||d< |r!|S dS )z
        Construct dynamic Weave headers from standard callback dynamic params.

        This is used for team/key based logging.

        Returns:
            dict: A dictionary of dynamic Weave headers
        Zwandb_api_keyZweave_project_idrG   AuthorizationrJ   N)r   rE   )rc   rq   Zdynamic_headersZdynamic_wandb_api_keyZdynamic_weave_project_idrD   r#   r#   r$   construct_dynamic_otel_headers0  s   

z.WeaveOtelLogger.construct_dynamic_otel_headers)Nr[   )r\   r]   r^   r_   )N)rq   r   r?   rr   )
r&   r'   r(   r)   rb   ri   rn   rp   rt   __classcell__r#   r#   rd   r$   rZ      s    
'rZ   )r   r   r   r   r+   r   )r=   r>   r?   r>   )r?   r   )+
__future__r   r@   r    rL   typingr   r   r   Zopentelemetry.tracer   r   Ztyping_extensionsr   Zlitellm._loggingr	   Z*litellm.integrations._types.open_inferencer
   r   Zlitellm.integrations.arizer   Z"litellm.integrations.opentelemetryr   r   ZElitellm.integrations.opentelemetry_utils.base_otel_llm_obs_attributesr   r   Z*litellm.litellm_core_utils.safe_json_dumpsr   Z%litellm.types.integrations.weave_otelr   r   Zlitellm.types.utilsr   r   rS   rQ   r   r<   rE   rV   rY   rZ   r#   r#   r#   r$   <module>   s2    

.

5	