
    yj'                     ~   U d Z ddlZddlmZ ddl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 dd	l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mZ ddl m!Z!  ed          Z"ej#        Z# ed          Z$ ed          Z%e	dee$e%f         dee$e%f         fd            Z&e	de'deee$e%f         gee$e%f         f         fd            Z&	 d7dddee$e%f         dz  de'dz  dee$e%f         eee$e%f         gee$e%f         f         z  fdZ&dZ( e            Z)ee'e*e+e'e'e,z  e-z  e'f                  f         e.d<   de!de'd e'd!ej        de'f
d"Z/de!ddfd#Z0d$e'd%e'd&e'e,z  e-z  d'e'ddf
d(Z1d$e'd)e,d*e,d+e,d,e,ddfd-Z2	 	 d8d/e'd$e'd0e*e+e'e'e,z  e-z  e'f                  dz  d1e'ddf
d2Z3d3e'de'fd4Z4d5ede'fd6Z5dS )9z
Custom utility logging functions for Langfuse integration.
This module provides specialized formatters for all @observe decorated functions
and a conditional observe decorator that only applies when Langfuse is configured.
    N)OrderedDict)Callable)	ParamSpecTypeVaroverload)Request)observe)box)ConsoleGroupRenderableType)Panel)Table)Text)Tree)settings)append_metrics_to_file)RepresentationT)markupPRfuncreturnc                     d S N )r   s    =/DATA/AppData/hermes/projects/honcho/src/telemetry/logging.pyconditional_observer   $   s	     S    namec                     d S r   r   r    s    r   r   r   *   s	     25r   r"   c                    dt           t          t          f         dt           t          t          f         ffd}|  ||           S |S )a  
    Conditionally apply the @observe decorator only when LANGFUSE_PUBLIC_KEY is present.

    Can be used in two ways:
    1. As a decorator: @conditional_observe
    2. As a decorator factory: @conditional_observe(name="...")

    Args:
        func: The function to potentially decorate (when used as @conditional_observe)
        name: Optional name for the observation (when used as @conditional_observe(name="..."))

    Returns:
        The decorated function if Langfuse is configured, otherwise the original function
    fr   c                 h    t           j        r$n| j        } t          |          |           S | S )Nr"   )r   LANGFUSE_PUBLIC_KEY__name__r	   )r$   observe_namer    s     r   	decoratorz&conditional_observe.<locals>.decoratorE   s>    ' 	#'#344L-7---a000Hr   )r   r   r   )r   r    r)   s    ` r   r   r   1   s]    (Xad^ A       y r   i  accumulated_metricsrepresentationhistorynew_turnmessage_created_atc                    g }|                     d           |                     d|                    d                      |                     d           |                     d           |                     |                                            |rQ|                     d           |                     |                                           |                     d           |rQ|                     d           |                     |                                           |                     d           d                    |          S )	a!  
    Format reasoning inputs as markdown for logging.
    Args:
        representation: Current/working representation
        history: Conversation history
        new_turn: New user message
        message_created_at: Message timestamp
    Returns:
        Formatted markdown string
    z## Reasoning Inputs
z**Current Time**: z%Y-%m-%d %H:%M:%S z### Current Representation
z### Conversation History
z### New Turn

)appendstrftimeformat_as_markdownstripjoin)r+   r,   r-   r.   partss        r   #format_reasoning_inputs_as_markdownr8   `   s:     E	LL()))	LLO/889LMMOO   
LL 
LL/000	LL2244555  1222W]]__%%%R  %&&&X^^%%&&&R99Ur   c                    t          d          }|                    dt          | j                   d          }t	          | j        d          D ] \  }}|                    d| d|            !|                    dt          | j                   d          }t	          | j        d          D ] \  }}|                    d| d|            !t                              |           t                                           dS )	zi
    Log representation in a tree structure.
    Args:
        representation: Representation to log
    u   📊 REPRESENTATIONz[bold cyan]EXPLICIT[/] ()   z[dim]z.[/] z[bold cyan]DEDUCTIVE[/] (N)r   addlenexplicit	enumerate	deductiveconsoleprint)r+   treetype_branchiobss        r   log_representationrG      s    %&&D((Uc.:Q6R6RUUUVVKN3Q77 / /3-----....((Ws>;S7T7TWWWXXKN4a88 / /3-----....MM$MMOOOOOr   	task_namelabelvalueunitc                 6   t          t                    t          k    rJ| t          vrAt                              d           t          t                    t          k    r	| t          vAt                              | g                               |||f           dS )a  
    Accumulate a metric value to be printed the next time log_performance_metrics is called.

    This function uses a bounded OrderedDict to prevent memory leaks. If the number of
    tracked tasks exceeds MAX_ACCUMULATED_TASKS, the oldest entries are evicted (FIFO).

    Args:
        task_name: Task identifier
        label: Metric label
        value: Metric value
        unit: Metric unit
    F)lastN)r=   r*   MAX_ACCUMULATED_TASKSpopitem
setdefaultr2   )rH   rI   rJ   rK   s       r   accumulate_metricrQ      s    * 	  $999000 	###///	 	  $999000
 ""9b1188%9MNNNNNr   input_tokensoutput_tokenscache_read_input_tokenscache_creation_input_tokensc                     t          | d|d           t          | d|d           t          | d|d           ||z
  |z   }t          | d|d           t          | d|d           dS )a  
    Log cache-aware token usage metrics.

    Args:
        task_name: The task name for metric accumulation
        input_tokens: Total input tokens (cached + uncached)
        output_tokens: Output tokens generated
        cache_read_input_tokens: Tokens read from cache (90% cheaper)
        cache_creation_input_tokens: Tokens written to cache (25% more expensive)

    Returns:
        None
    rR   tokensrT   rU   uncached_input_tokensrS   N)rQ   )rH   rR   rS   rT   rU   rX   s         r   log_token_usage_metricsrY      s    ( ixHHH!	   %#	   	..1LL  *,A8   i-JJJJJr      ⚡ PERFORMANCE	task_slugmetricstitlec           	      @   |  d| }t                               |          s|sdS |g }t                               |g           |z   }t          rt	          | ||           g }g }|D ]%}|d         dk    r|n|                    |           &t          dddd          }|                    d	d
d           |                    dddd           |                    ddd           |D ]h\  }}}	|	dk    r|d}
n|	dk    r|d}
nt          |          }
|	                    |
                    dd                                          |
|	           i|g}|rg|D ]d\  }}}|                    t          j        dd| ddfd                     |                    t          t          |                               et          t          | d| d | d!t           j        d"d#$          }t$                              |           t$                                           dS )%aH  
    Log performance metrics in a clean table and optionally send to global collector.

    Args:
        task_slug: Slug of the task that generated these metrics
        task_name: Name of the task that generated these metrics
        metrics: Dictionary of metric names and (value, unit) tuples
        title: Table title
    _N   blobTz
bold green)r   r;   )show_headerheader_styler
   paddingMetriccyan   )stylewidthValuerightyellow   )justifyrh   ri   Unitdim   msz.0fsz.3f z    r1   :boldz     z[bold green]z - z[/])r;   r`   P   )r]   r
   rd   ri   )r*   getpopCOLLECT_METRICS_LOCALr   r2   r   
add_columnstradd_rowreplacer]   r   assembler   r   r
   ROUNDEDrA   rB   )r[   rH   r\   r]   blob_metricsnon_blob_metricsmetrictablerJ   rK   formatted_valuecontent_items_unitpanels                 r   log_performance_metricsr      s    **y**I ""9-- g !%%i44w>G >y)W=== >@LAC S Sf,,2BJJ6RRRR!	  E 
XV2666	WgXRHHH	V5222/ O Ot4<<!&nnOOS[[!&nnOO!%jjOfnnS#..4466NNNN ,1'M 3$0 	3 	3 FE5  f~F~~~v&>HH     c%jj!1!12222}5U55y555K  E MM%MMOOOOOr   pathc                 f    | dk    r*|                      d          r|                     d          S | S )N/)endswithrstrip)r   s    r   normalize_template_pathr   7  s2    s{{t}}S)){{{3Kr   requestc                     | j                             d          }|r%t          |dd           rt          |j                  S dS )Nrouter   unknown)scoperx   getattrr   r   )r   r   s     r   get_route_templater   =  sG    Mg&&E 3-- 3&uz2229r   r   )NrZ   )6__doc__datetimecollectionsr   collections.abcr   typingr   r   r   fastapir   langfuser	   richr
   rich.consoler   r   r   
rich.panelr   
rich.tabler   	rich.textr   	rich.treer   
src.configr   src.telemetry.metrics_collectorr   src.utils.representationr   rA   rz   r   r   r   r|   rN   r*   listtupleintfloat__annotations__r8   rG   rQ   rY   r   r   r   r   r   r   <module>r      s      # # # # # # $ $ $ $ $ $ / / / / / / / / / /                   7 7 7 7 7 7 7 7 7 7                               B B B B B B     
 '


 6 IcNNGCLL 

1a4.ad^   

 
5
5 x1~A./5 5 5 
5 #'       
1a4.4
  *  ad^hA/!Q$?@@	       N   KMM [d5cCi%6G1L+M&N!NO   
("(( ( !)	(
 	( ( ( (V"	   ,OOO 9uO 	O
 
O O O O<)K)K)K )K !	)K
 "%)K 
)K )K )K )K^ @D"	I III %S3Y.345<I 	I
 
I I I IX# #     C      r   