
    PmjeG                       d Z ddlmZ ddlZddlZddlZddlmZ ddlm	Z	m
Z
mZmZ ddlmZmZ  edd           G d	 d
                      Z edd           G d d                      Zh dZh dZh dez  ez  Zeez  h dz  Zh dZ ej        d          ZdQdZdRdZdSdZdTdZdUd!ZdVd$Zd%d&dWd)ZdTd*Z dXd,Z!dYd.Z"dZd/Z#d[d3Z$d\d4Z%d]d:Z&d^d?Z'd@dAd_dDZ(d`dEZ)d`dFZ*dadKZ+dbdMZ, G dN dOej-                  Z.g dPZ/dS )caW  Gateway health and diagnostics signal producer.

This module keeps the plane narrow: service health monitoring plus
redacted operational diagnostics. It reuses the existing gateway runtime-status
contract and emits content-free metrics/events. No prompts, messages, tool args,
session history, audit records, or product analytics belong here.
    )annotationsN)	dataclass)AnyDictListOptional)GatewayDiagnosticEventGatewayHealthEventT)frozenslotsc                  .    e Zd ZU ded<   ded<   ded<   dS )GatewayMetricstrnameint | floatvalueDict[str, str]
attributesN__name__
__module____qualname____annotations__     E/home/thesage/.hermes/hermes-agent/agent/monitoring/gateway_health.pyr   r      s3         IIIr   r   c                  $    e Zd ZU ded<   ded<   dS )GatewayHealthSnapshotzList[GatewayMetric]metricsz1List[GatewayHealthEvent | GatewayDiagnosticEvent]eventsNr   r   r   r   r   r      s*             ======r   r   >   okreadyrunning	connected>   errorfatalfaileddegraded>   stoppedunknowndrainingstartingstoppingstartup_failed>   pausedr*   disabledretrying
connectingdisconnected>   s6manuallaunchdsystemdr*   	containerz&^gateway(?:\.[A-Za-z_][A-Za-z0-9_]*)*$r   r   returnboolc                8    | dk    p|                      d          S )Ngatewayzgateway.)
startswith)r   s    r   _allowed_loggerr>   -   s    9;
 ; ;;r   r   Optional[str]c                    t          | pd          }t          |          dk    rt                              |          r|ndS )zFReturn a bounded source-controlled gateway logger name for OTLP scope.    N)r   len_SOURCE_LOGGER_RE	fullmatch)r   r   s     r   source_logger_for_exportrF   1   s@    
OOEJJ#%%*;*E*Ee*L*L%55RVVr   messagec                    	 ddl m}  |t          | pd                    pd}n# t          $ r d}Y nw xY w|dd         S )zRedact gateway diagnostic free text for operator-owned export.

    Single scrub path: everything goes through
    ``agent.monitoring.redaction.redact_for_export`` (unconditional
    secrets + PII), then is length-bounded.
    r   redact_for_exportrA   z[redaction-unavailable]Ni  agent.monitoring.redactionrJ   r   	Exception)rG   rJ   redacteds      r   redact_gateway_messagerO   7   sn    -@@@@@@$$SB%7%788>B - - -,-DSD>s   "% 44rawc                <   t          | pd                                          t          fddD                       rdS dv rdv rdS dv sd	v rdS t          fd
dD                       rdS t          fddD                       rdS dv rdS dv rdS dS )NrA   c              3      K   | ]}|v V  	d S Nr   .0kss     r   	<genexpr>z)classify_gateway_error.<locals>.<genexpr>H   s'      
X
Xa16
X
X
X
X
X
Xr   )authtokenunauthorized	forbidden401403auth_failedratelimitrate_limitedtimeoutz	timed outc              3      K   | ]}|v V  	d S rS   r   rT   s     r   rX   z)classify_gateway_error.<locals>.<genexpr>N   s;         	
Q     r   )	network
connectiondnssocketzconnect call failedzfailed to connectzcannot connectunreachablezname resolutionnetwork_errorc              3      K   | ]}|v V  	d S rS   r   rT   s     r   rX   z)classify_gateway_error.<locals>.<genexpr>]   s'      
<
<a16
<
<
<
<
<
<r   )configmissinginvalidinvalid_configstartupr.   r&   platform_fatalr*   )r   lowerany)rP   rW   s    @r   classify_gateway_errorrt   F   s   CI2A

X
X
X
XW
X
X
XXX }{{w!||~A~~))y
    

      

<
<
<
<;
<
<
<<<  A~~!||9r   staterestart_requestedc               P   |rdS t          |pd                                          }| |dk    rdS t          |           }|dk    r
|dk    r|ndS t          | pd                                          dv sdv sdv rdS |d	k    rt          fd
dD                       rdS |S )z>Reduce free-form shutdown text to a bounded operational class.rv   rA   Nr.   r*   signalsigtermsigintr)   c              3      K   | ]}|v V  	d S rS   r   )rU   wordtexts     r   rX   z'classify_exit_reason.<locals>.<genexpr>u   s'      &U&Utt|&U&U&U&U&U&Ur   )shutdownstopplanned_stop)r   rr   rt   rs   )rP   ru   rv   
state_name
classifiedr}   s        @r   classify_exit_reasonr   f   s      #""U[b!!''))J
{z%555t',,J%%%'944zz:JJsyb>>!!D49,,D0@0@xY3&U&U&U&U@T&U&U&U#U#U~r   allowedset[str]c               X    t          | pd                                          }||v r|ndS )Nr*   )r   rr   )rP   r   ru   s      r   _bounded_stater   z   s4     y!!''))EW$$55)3r   rB   ra   ra   intc                   	 ddl m}  |t          | pd                    pd}n# t          $ r Y dS w xY w|d |         S )Nr   rI   rA   r*   rK   )rP   ra   rJ   r   s       r   _safe_metric_valuer      sj    @@@@@@!!#ciR..11>Y   yy%=s   "% 
33c                    t          | pd                              dd          }dt          j        |                                          dd          S )zDReturn a stable opaque instance key without exporting the source ID.r*   zutf-8replace)errorszsha256:N   )r   encodehashlibsha256	hexdigest)rP   r   s     r   _safe_instance_idr      sT     y!!(((CCE=W^E**4466ss;===r   logger_namec                <   | dk    s|                      d          rdS |                      d          r;|                     d          }t          |          dk    r|d         rd|d          S |                      d	          rd
S |                      d          rdS dS )Nzgateway.relayzgateway.relay.zplatform.relayzgateway.platforms..      	platform.zgateway.platformsplatformr<   )r=   splitrC   )r   partss     r   subsystem_for_loggerr      s    o%%)?)?@P)Q)Q%233 *!!#&&u::??uQx?)uQx)))122 zi(( y9r   	subsystemc                l    |                      d          r|                     dd          d         pd S d S )Nr   r      )r=   r   )r   s    r   platform_for_subsystemr      s;    K(( 2sA&&q)1T14r   c                    	 ddl m}  ||           S # t          $ r: 	 t          dt	          |                     cY S # t
          t          f$ r Y Y dS w xY ww xY w)Nr   )parse_active_agents)gateway.statusr   rM   maxr   	TypeError
ValueError)rP   r   s     r   _parse_active_agentsr      s    666666""3'''   	q#c((#####:& 	 	 	111	s)    
A=AAAAAgateway_runninggateway_stateactive_agentsc                    	 ddl m}  || ||          S # t          $ r+ t          | o|dk    ot	          |          dk              cY S w xY w)Nr   )derive_gateway_busy)r   r   r   r#   )r   r   rM   r:   r   )r   r   r   r   s       r   _derive_busyr      s    p666666""+''
 
 
 	

  p p pOn(BnG[\iGjGjmnGnooooops    2A
Ac                t    	 ddl m}  || |          S # t          $ r t          | o|dk              cY S w xY w)Nr   )derive_gateway_drainable)r   r   r#   )r   r   rM   r:   )r   r   r   s      r   _derive_drainabler      sn    D;;;;;;''Wdeeee D D DOB(BCCCCCDs    77profile
install_idversionsupervision_moder   c                    t          |pd                                          }t          |          t          |d          |t          v r|nddS )Nr*   @   r   )zservice.instance.idzservice.versionzhermes.supervision_mode)r   rr   r   r   _SUPERVISION_MODES)r   r   r   r   modes        r   _base_attrsr      s]    ,9--3355D0<<-gR@@@+/3E+E+E449  r   r   r   attrsextrac                    t          |          }|                                D ]\  }}|t          |          ||<   t          | ||          S )N)r   r   r   )dictitemsr   r   )r   r   r   r   outkeyvals          r   _metricr      sT    
u++CKKMM / /S?)#..CHd%C@@@@r   r*   )r   runtimeOptional[dict[str, Any]]c                  | pi } t          |                     d          t                    }t          |                     dd                    }t	          |||          }t          ||          }	t          |                     d          t                    r|                     d          ni }
t          ||||          }t          d|rdnd|          t          d	||          t          d
|rdnd|          t          d|	rdnd|          t          d|                     d          rdnd|          g}|r1|
                    t          dd|fi dt          |          i           d}g }|
                                D ]m\  }}t          |t                    r|ni }t          |                    d          t                    }|                    d          p|                    d          }t          |          }|t          v }|t           v }|r|dz  }|
                    t          d|rdnd|fi t          |          |d           |
                    t          d|rdnd|fi t          |          ||d           |rd|
                    t#          dd| t          |          |t          |p|                    d                    |||dk    rdnd                     o|                    dt'          d|t          |          nd|||	t)          |
          |||||t+          |                     d                                         t-          ||           S )!zDConvert gateway_state.json-compatible runtime state into P0 signals.r   r   r   r   	platforms)r   r   r   r   zhermes.gateway.upr   zhermes.gateway.active_agentszhermes.gateway.busyzhermes.gateway.drainablez hermes.gateway.restart_requestedrv   zhermes.gateway.stateru   
error_codeerror_messagezhermes.platform.up)hermes.platformhermes.platform.statezhermes.platform.degraded)r   r   zhermes.error_codeplatform.fatalr   r&   r%   warningr   r   r   r   error_classr   r   severityzgateway.health_snapshotNpid)r   r   r   gateway_busygateway_drainableplatform_countfatal_platform_countr   r   r   r   r   )r   r    )r   get_KNOWN_GATEWAY_STATESr   r   r   
isinstancer   r   r   appendr   r   _KNOWN_PLATFORM_STATESrt   _RUNNING_PLATFORM_STATES_FATAL_PLATFORM_STATESr	   insertr
   rC   _coerce_pidr   )r   r   r   r   r   r   r   r   busy	drainabler   baser   fatal_countr    r   pdataru   	raw_errorr   is_upis_degradeds                         r   build_gateway_health_snapshotr      s    mG"O$$.C  M )_a)H)HIIMFFD!/=AAI,6w{{;7O7OQU,V,V^K(((\^Iw:waqrrrD 	#/%@QQq$GG.tDD%D'7qqa>>*,AAA4HH2EX9Y9Y4`AA_`bfgg$G  qw5q$ooCY[^_l[m[mBnoopppK@BF$??,, ! !%#E4008bIIg(>
 
 
 IIl++Iuyy/I/I	+I66
1155 	1Kw AAA
 
 #&h--%PP	
 
 	 	 	 	w&#AA!
 
 #&h--%fpqq	
 
 	 	 	  
	MM0%0h00X%2:3[?A[A[\\$)W$4$4)	 	 	 	 	 	 MM!'&,9,Ec-(((4##9~~()E**++      !@@@@r   c                 d    	 ddl m}  t           |             pd          S # t          $ r Y dS w xY w)Nr   get_active_profile_namedefault)hermes_cli.profilesr   r   rM   r   s    r   _safe_profiler   &  sX    ??????**,,9	:::   yys   ! 
//c                 P    	 ddl m}  t          |           S # t          $ r Y dS w xY w)Nr   __version__r*   )
hermes_clir   r   rM   r   s    r   _safe_versionr   .  sI    ******;   yys    
%%previouscurrentdict[str, Any]Nonec                
   	 ddl m} g }t                      }t                      }| pi                     d          +t          | pi                     d          t                    nd}|                    d          )t          |                    d          t                    nd}||k    r|r|                    t          d|||t          |                    d          |t          |                    d                    	          t          |                    d                    t          |                    d
d                    ||t          |                    d                    
  
                   |dk    rm|                    t          ddt          |                    d          pd          t          |                    d          pd          ||d                     |dk    r|                    t          d|||t          |                    d          |t          |                    d                    	          t          |                    d                    t          |                    d
d                    ||t          |                    d                    
  
                   | pi                     d          }|                    d          }	t          |t                     r|ni }
t          |	t                     r|	ni }|                                D ]\  }}t          |t                     r|ni }|
                    |i           }t          |t                     r|ni }|                    d          )t          |                    d          t$                    nd}|                    d          )t          |                    d          t$                    nd}||k    s|st          |                    d          p|                    d                    }|                                dv rdnd}|                    t          dd| t)          |          |||||||
  
                   |                                t*          v r:|                    t          dd| t)          |          |||||                     |D ]}|                    |           dS # t.          $ r2 t1          j        t4                                        dd !           Y dS w xY w)"zEmit immediate content-free gateway events for runtime status changes.

    Called by gateway.status.write_runtime_status after persisting the new status.
    Fully fail-open: failures never affect gateway status writes.
    r   emitterr   Nr   zgateway.lifecycleexit_reasonrv   )ru   rv   r   r   )
r   r   	old_state	new_stater   rv   r   r   r   r   r.   zgateway.startup_failedr<   r%   )r   r   r   r   r   r   r   r)   zgateway.exitr   ru   r   r   >   r%   r&   r'   r   zplatform.state_changer   )
r   r   r   r   r   r   r   r   r   r   r   r   z-gateway runtime status transition emit failedTexc_info)agent.monitoringr   r   r   r   r   r   r   r
   r   r:   r   r   r	   rt   r   r   r   r   rr   r   r   emitrM   logging	getLoggerr   debug)r   r   r   r   r   r   old_gateway_statenew_gateway_stateold_platforms_rawnew_platforms_rawold_platformsnew_platformsr   r   prev_rawprevr   r   r   r   evs                        r   emit_runtime_status_transitionr  6  s   dj,,,,,,AC//// n"!!/22> +^  11;P
 
 
 
DH 	
 [[))5 +KK((2G
 
 
 
;? 	  1116G1JJ)(/++0KK..+&*7;;7J+K+K&L&L  
 #'w{{3F'G'G"H"H27;;PQ3R3RSSE 2 233       !$444

11' 6w{{=7Q7Q7eUe f f5gkk-6P6P6dTdee##$      !I--

-'"3// 4M22/*.w{{;N/O/O*P*P! ! !
 '+7;;7J+K+K&L&L"6w{{?TU7V7V"W"W###GKK$6$677     " &^00==#KK44-78I4-P-PX))VX-78I4-P-PX))VX,2244 $	 $	OHe't44<EE"E$((266H)(D99A88rD '"". '!!+A   48 
 7##/ '		'"",B   59  I%%Y%/		,0G0G0e599UdKeKeffJ"+//"3"37S"S"SwwYbHJJ-,0h00X##%&!        $:::

1)4(44 ]]) *##%	 	 	 	 	 	  	 	BLL	 	 j j j(##))*Ydh)iiiiiijs   TT 8UUOptional[int]c                h    	 t          |           }n# t          t          f$ r Y d S w xY w|dk    r|nd S )Nr   )r   r   r   )rP   r   s     r   r   r     sM    #hhz"   tt''33t#s    ''c                  4     e Zd ZdZdddd fd
ZddZ xZS )GatewayDiagnosticLogHandlerz?Allowlisted warning/error bridge for gateway-owned diagnostics.r   r*   )r   r   r   r   r   r9   r   c               |    t                                          t          j                   || _        || _        d S )N)level)super__init__r  WARNINGr   r   )selfr   r   	__class__s      r   r  z$GatewayDiagnosticLogHandler.__init__  s2    w///r   recordlogging.LogRecordc                   	 |j         t          j        k     rd S t          |j                  sd S t          |j                  }|                                }t          |          }t          d|j	        
                                 |t          |j                  t          |          ||| j        | j        |j	        
                                	  	        }ddlm} |                                                    |           d S # t&          $ r2 t          j        t*                                        dd           Y d S w xY w)Nzgateway.log.)	r   r   source_loggerr   r   r   r   r   r   r   r   zgateway diagnostic emit failedTr   )levelnor  r  r>   r   r   
getMessagert   r	   	levelnamerr   rF   r   r   r   r  r   get_emitterr  rM   r  r   r  )r  r  r   rG   r   eventr   s          r   r  z GatewayDiagnosticLogHandler.emit  sS   	_~//"6;// ,V[99I''))G099K*>F$4$:$:$<$<>>#6v{CC/	::'&)//11
 
 
E 100000!!&&u----- 	_ 	_ 	_h''--.NY]-^^^^^^	_s   D D CD 8EE)r   r   r   r   r9   r   )r  r  r9   r   )r   r   r   __doc__r  r  __classcell__)r  s   @r   r  r    sn        II)29        
_ _ _ _ _ _ _ _r   r  )r   r   r  r   rt   rF   rO   )r   r   r9   r:   )r   r   r9   r?   )rG   r   r9   r   )rP   r   r9   r   )rP   r   ru   r   rv   r:   r9   r?   )rP   r   r   r   r9   r   )rP   r   ra   r   r9   r   )r   r   r9   r   )r   r   r9   r?   )rP   r   r9   r   )r   r:   r   r   r   r   r9   r:   )r   r:   r   r   r9   r:   )
r   r   r   r   r   r   r   r   r9   r   )
r   r   r   r   r   r   r   r   r9   r   )r   r   r   r:   r   r   r   r   r   r   r   r   r9   r   )r9   r   )r   r   r   r   r9   r   )rP   r   r9   r  )0r$  
__future__r   r   r  redataclassesr   typingr   r   r   r   agent.monitoring.eventsr	   r
   r   r   r   r   r   r   r   compilerD   r>   rF   rO   rt   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r   Handlerr  __all__r   r   r   <module>r.     s    # " " " " "   				 ! ! ! ! ! ! , , , , , , , , , , , , N N N N N N N N $d###       $# $d###> > > > > > > $#>
 CBB AAA   56  24JJ N N N   TSS BJHII < < < <W W W W      @   (4 4 4 4
 25      > > > >         	p 	p 	p 	pD D D D   A A A A &QA QA QA QA QA QAh      jj jj jj jjZ$ $ $ $_ _ _ _ _'/ _ _ _D  r   