
    PL
jP                        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 daddZ G d	 d
          Z G d d          ZddZddZddZ e            Zg dZdS )u  Process-level bootstrap helpers for ``run_agent``.

Three concerns, all tied to ``AIAgent`` boot-time / runtime IO setup:

1. **Lazy OpenAI SDK import** — ``_load_openai_cls`` + ``_OpenAIProxy``
   defer the 240ms-ish ``from openai import OpenAI`` cost until first use,
   while preserving ``isinstance(client, OpenAI)`` checks and
   ``patch("run_agent.OpenAI", ...)`` test patterns.

2. **Crash-resistant stdio** — ``_SafeWriter`` wraps stdout/stderr so
   ``OSError: Input/output error`` from broken pipes (systemd, Docker,
   thread teardown races) cannot crash the agent.  ``_install_safe_stdio``
   applies the wrapper.

3. **HTTP proxy resolution** — ``_get_proxy_from_env`` reads
   ``HTTPS_PROXY`` / ``HTTP_PROXY`` / ``ALL_PROXY``;
   ``_get_proxy_for_base_url`` respects ``NO_PROXY`` for the given base URL.

``run_agent`` re-exports every name so existing
``from run_agent import _get_proxy_from_env`` imports keep working
unchanged.
    )annotationsN)Optional)base_url_hostnamenormalize_proxy_urlreturntypec                 .    t           ddlm}  | a t           S )z#Import and cache ``openai.OpenAI``.Nr   )OpenAI)_OPENAI_CLS_CACHEopenair
   )_clss    ;/home/kuhnn/.hermes/hermes-agent/agent/process_bootstrap.py_load_openai_clsr   '   s(      ))))))     c                  (    e Zd ZdZdZd Zd Zd ZdS )_OpenAIProxyzHModule-level proxy that looks like ``openai.OpenAI`` but imports lazily. c                *     t                      |i |S N)r   )selfargskwargss      r   __call__z_OpenAIProxy.__call__5   s    !!!426222r   c                :    t          |t                                S r   )
isinstancer   )r   objs     r   __instancecheck__z_OpenAIProxy.__instancecheck__8   s    #/11222r   c                    dS )Nz<lazy openai.OpenAI proxy>r   r   s    r   __repr__z_OpenAIProxy.__repr__;   s    ++r   N)__name__
__module____qualname____doc__	__slots__r   r   r    r   r   r   r   r   0   sL        RRI3 3 33 3 3, , , , ,r   r   c                  :    e Zd ZdZdZd Zd Zd Zd Zd Z	d Z
d	S )
_SafeWriterup  Transparent stdio wrapper that catches OSError/ValueError from broken pipes.

    When hermes-agent runs as a systemd service, Docker container, or headless
    daemon, the stdout/stderr pipe can become unavailable (idle timeout, buffer
    exhaustion, socket reset). Any print() call then raises
    ``OSError: [Errno 5] Input/output error``, which can crash agent setup or
    run_conversation() — especially via double-fault when an except handler
    also tries to print.

    Additionally, when subagents run in ThreadPoolExecutor threads, the shared
    stdout handle can close between thread teardown and cleanup, raising
    ``ValueError: I/O operation on closed file`` instead of OSError.

    This wrapper delegates all writes to the underlying stream and silently
    catches both OSError and ValueError. It is transparent when the wrapped
    stream is healthy.
    )_innerc                >    t                               | d|           d S )Nr(   )object__setattr__)r   inners     r   __init__z_SafeWriter.__init__T   s     4511111r   c                    	 | j                             |          S # t          t          f$ r) t	          |t
                    rt          |          ndcY S w xY w)Nr   )r(   writeOSError
ValueErrorr   strlen)r   datas     r   r/   z_SafeWriter.writeW   sb    	=;$$T***$ 	= 	= 	= *4 5 5<3t9991<<<	=s    7AAc                j    	 | j                                          d S # t          t          f$ r Y d S w xY wr   )r(   flushr0   r1   r   s    r   r6   z_SafeWriter.flush]   sH    	K$ 	 	 	DD	s    22c                4    | j                                         S r   )r(   filenor   s    r   r8   z_SafeWriter.filenoc   s    {!!###r   c                f    	 | j                                         S # t          t          f$ r Y dS w xY w)NF)r(   isattyr0   r1   r   s    r   r:   z_SafeWriter.isattyf   sB    	;%%'''$ 	 	 	55	s    00c                ,    t          | j        |          S r   )getattrr(   )r   names     r   __getattr__z_SafeWriter.__getattr__l   s    t{D)))r   N)r!   r"   r#   r$   r%   r-   r/   r6   r8   r:   r>   r   r   r   r'   r'   ?   s         $ I2 2 2= = =  $ $ $  * * * * *r   r'   Optional[str]c                     dD ]G} t           j                            | d                                          }|rt	          |          c S HdS )zRead proxy URL from environment variables.

    Checks HTTPS_PROXY, HTTP_PROXY, ALL_PROXY (and lowercase variants) in order.
    Returns the first valid proxy URL found, or None if no proxy is configured.
    )HTTPS_PROXY
HTTP_PROXY	ALL_PROXYhttps_proxy
http_proxy	all_proxy N)osenvirongetstripr   )keyvalues     r   _get_proxy_from_envrN   p   sZ    : . .
sB''--// 	.&u-----	.4r   base_urlc                    t                      }|r| s|S t          |           }|s|S 	 t          j                            |          rdS n# t
          $ r Y nw xY w|S )zFReturn an env-configured proxy unless NO_PROXY excludes this base URL.N)rN   r   urllibrequestproxy_bypass_environment	Exception)rO   proxyhosts      r   _get_proxy_for_base_urlrW   ~   s    !!E  X&&D >22488 	4	    Ls   A 
AANonec                     dD ]R} t          t          | d          }|8t          |t                    s#t	          t          | t          |                     SdS )zHWrap stdout/stderr so best-effort console output cannot crash the agent.)stdoutstderrN)r<   sysr   r'   setattr)stream_namestreams     r   _install_safe_stdior`      s\    + ; ;k400j&E&ECk&&9&9:::; ;r   )r
   r   r   r'   r`   rN   rW   )r   r   )r   r?   )rO   r?   r   r?   )r   rX   )r$   
__future__r   rH   r\   urllib.requestrQ   typingr   utilsr   r   r   r   r   r'   rN   rW   r`   r
   __all__r   r   r   <module>rf      s6   . # " " " " " 				 



           8 8 8 8 8 8 8 8
     , , , , , , , ,.* .* .* .* .* .* .* .*b      &; ; ; ; 
  r   