
    yjW                       U d 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 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!m"Z"m#Z#m$Z$ ddlm%Z%  ed          d;d            Z& ed          d<d            Z' ed          d=d            Z( ed          d>d            Z) ed          d?d             Z* ed          d@d!            Z+i Z,d"e-d#<   ej.        j/        r% eej.        j/        ej.        j0        d$%          e,d&<   ej.        j1        r$ eej.        j1        ej.        j2        '          e,d(<   ej.        j3        rHej.        j4        r ej5        ej.        j4        )          nd*Z6 e
j7        ej.        j3        e6+          e,d,<   dAd2Z8dBd5Z9dCd7Z:dDd9Z;g d:Z<d*S )EaZ  Single owner of provider runtime objects: clients, backends, history adapters.

Consolidates wiring that previously lived in both `src/llm/__init__.py` and
`src/utils/clients.py`. Everything that touches provider SDKs at runtime
(default client construction, override client caching, backend selection,
history adapter selection) lives here now.
    )annotations)	lru_cache)assert_neverAsyncAnthropic)genai)typesAsyncOpenAI)ModelConfigModelTransportsettings)ValidationException   )ProviderBackend)AnthropicBackend)GeminiBackend)OpenAIBackend)default_transport_api_key)AnthropicHistoryAdapterGeminiHistoryAdapterHistoryAdapterOpenAIHistoryAdapter)ProviderClient)maxsizereturnr   c                 b    t          t          j        j        t          j        j        d          S )zCDefault Anthropic client built from settings.LLM.ANTHROPIC_API_KEY.     @api_keybase_urltimeout)r   r   LLMANTHROPIC_API_KEYANTHROPIC_BASE_URL     8/DATA/AppData/hermes/projects/honcho/src/llm/registry.pyget_anthropic_clientr)   $   s.     .0   r'   r   c                 `    t          t          j        j        t          j        j                  S )z=Default OpenAI client built from settings.LLM.OPENAI_API_KEY.r    r!   )r   r   r#   OPENAI_API_KEYOPENAI_BASE_URLr&   r'   r(   get_openai_clientr.   .   s+     +-   r'   genai.Clientc                     t           j        j        r$t          j        t           j        j                  nd} t          j        t           j        j        |           S )z=Default Gemini client built from settings.LLM.GEMINI_API_KEY.r!   Nr    http_options)r   r#   GEMINI_BASE_URLgenai_typesHttpOptionsr   ClientGEMINI_API_KEY)r3   s    r(   get_gemini_clientr9   7   sM    
 <'	)EFFFF 
 < ;,WWWWr'      r!   
str | Noner    c                $    t          ||           S )zEOpenAI client for a specific (base_url, api_key) pair. Cached by key.r+   r
   r!   r    s     r(   get_openai_override_clientr>   D   s    
 w::::r'   c                &    t          || d          S )zHAnthropic client for a specific (base_url, api_key) pair. Cached by key.r   r   r   r=   s     r(   get_anthropic_override_clientr@   L   s     'HeLLLLr'   c                `    | rt          j        |           nd}t          j        ||          S )zEGemini client for a specific (base_url, api_key) pair. Cached by key.r1   Nr2   )r5   r6   r   r7   )r!   r    r3   s      r(   get_gemini_override_clientrB   U   s8    
 BJS;*H====tL<lCCCCr'   z$dict[ModelTransport, ProviderClient]CLIENTSr   r   	anthropicr+   openair1   Nr2   geminiproviderr   model_configr   r   c                d   |j         %|j        t                              |           }||S |j         pt	          |           }|j        }|st          d|  d          | dk    rt          ||          S | dk    rt          ||          S | dk    rt          ||          S t          |            dS )u   Resolve the provider client for a ModelConfig.

    Fast path: no overrides → reuse the module-level default client from
    CLIENTS (the test-mockable seam). Otherwise route through the cached
    override factories.
    NzMissing API key for z model configrD   rE   rF   )
r    r!   rC   getr   r   r@   r>   rB   r   )rG   rH   existing_clientr    r!   s        r(   client_for_model_configrL   {   s     #(=(E!++h//&"""I&?&I&IG$H R!"P"P"P"PQQQ;,Xw???8)(G<<<8)(G<<<r'   clientr   c                    | dk    rt          |          S | dk    rt          |          S | dk    rt          |          S t          |            dS )zGWrap a raw provider SDK client in the matching ProviderBackend adapter.rD   rE   rF   N)r   r   r   r   )rG   rM   s     r(   backend_for_providerrO      sc    
 ;'''8V$$$8V$$$r'   r   c                n    | dk    rt                      S | dk    rt                      S t                      S )zJProvider-appropriate HistoryAdapter for assistant/tool message formatting.rD   rF   )r   r   r   )rG   s    r(   history_adapter_for_providerrQ      s<    ;&(((8#%%%!!!r'   configc                V    t          | j        |           }t          | j        |          S )u  High-level one-shot backend factory: ModelConfig → ProviderBackend.

    Delegates client resolution to ``client_for_model_config``, which owns
    the CLIENTS fast-path and the missing-API-key validation. Both the
    production path (via ``honcho_llm_call_inner``) and the live-test path
    (via this function) now construct clients through the same helper, so
    validation behavior stays consistent.
    )rL   	transportrO   )rR   rM   s     r(   get_backendrU      s)     %V%5v>>F 0&999r'   )rC   rO   rL   r)   r@   rU   r9   rB   r.   r>   rQ   )r   r   )r   r   )r   r/   )r!   r;   r    r;   r   r   )r!   r;   r    r;   r   r   )r!   r;   r    r;   r   r/   )rG   r   rH   r   r   r   )rG   r   rM   r   r   r   )rG   r   r   r   )rR   r   r   r   )=__doc__
__future__r   	functoolsr   typingr   rD   r   googler   google.genair	   r5   rE   r   
src.configr   r   r   src.exceptionsr   backendr   backends.anthropicr   backends.geminir   backends.openair   credentialsr   history_adaptersr   r   r   r   r   r)   r.   r9   r>   r@   rB   rC   __annotations__r#   r$   r%   r,   r-   r8   r4   r6   r3   r7   rL   rO   rQ   rU   __all__r&   r'   r(   <module>rf      s     # " " " " "             $ $ $ $ $ $       - - - - - -       < < < < < < < < < < . . . . . . $ $ $ $ $ $ 0 0 0 0 0 0 * * * * * * * * * * * * 2 2 2 2 2 2            " ! ! ! ! ! 1    1    1X X X X 3; ; ; ; 3M M M M 3D D D D 13 2 2 2 2<! )>.0  GK < #+-  GH
 < 	 <'	)EFFFF 
 %+!  GH   :   " " " "
: 
: 
: 
:  r'   