
    6Qj!                     "   U 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e
dz  d	efd
Zdde
dz  d	efdZdde
dz  d	efdZdde
dz  d	efdZeeeedZee
ef   ed<   de
ded	efdZde
d	efdZd	ee   fdZdde
de
dz  d	efdZd	efdZy)   )settings   )AnthropicProvider)LLMProvider)FallbackProvider)OpenAICompatibleProviderNmodelreturnc                 \    t        t        j                  | xs t        j                        S N)api_keyr	   )r   r   openai_api_keyopenai_modelr	   s    ;/var/www/html/meridian/meridian-ai/app/providers/factory.py_build_openair      s&    #'',x,,     c                 \    t        t        j                  | xs t        j                        S r   )r   r   anthropic_api_keyanthropic_modelr   s    r   _build_anthropicr      s&    **/x// r   c                 |    t        t        j                  | xs t        j                  t        j                  d      S )NF)r   r	   base_urluse_json_mode)r   r   ollama_api_keyollama_modelollama_base_urlr   s    r   _build_ollamar      s2    #'',x,,))	 r   c                 ^    t        t        j                  | xs t        j                  d      S )Nz8https://generativelanguage.googleapis.com/v1beta/openai/)r   r	   r   )r   r   gemini_api_keygemini_modelr   s    r   _build_geminir"      s)    #'',x,,K r   )openai	anthropicollamagemini	_BUILDERSname
is_primaryc                     | dk(  rt        t        j                        S | dk(  rt        t        j                        S | dk(  rt        t        j                        S | dk(  r|S y)Nr#   r$   r&   r%   F)boolr   r   r   r    )r(   r)   s     r   _has_credentialsr,   /   s`    xH++,,{H..//xH++,,x r   c                     | t         vr$t        d|  ddj                  t                      t        | d      st        d|  d      t        |           S )zReturn a single provider by name (no fallback chain).
    Raises ValueError if the name is unknown or credentials are missing.
    Unknown provider '   ' — expected one of: , Tr)   z
Provider 'z' has no credentials configured)r'   
ValueErrorjoinr,   )r(   s    r   get_single_providerr4   >   s]     9-dV3J499U^K_J`abbDT2:dV+JKLLT?r   c                  h   dt         j                  ddt         j                  ddt         j                  ddt         j                  dd} g }| j                         D ]Q  \  }}t        ||t         j                  k(        s%|j                  ||d   |d	   |t         j                  k(  d
       S |S )z<Return metadata for all configured (credentialed) providers.zGemini 2.5 Flash Lite)r(   r	   zGPT-4o MinizClaude HaikuzOllama (local)r&   r#   r$   r%   r1   r(   r	   )idr(   r	   
is_default)	r   r!   r   r   r   itemsr,   llm_providerappend)metaresultprovider_idbuilder_metas       r   list_providersr@   I   s     6@U@UV+@U@UV,@X@XY.AVAVW	D F%)ZZ\ !\K[HDYDY5Y[MM!$V,%g.)X-B-BB	  Mr   primarymodel_overridec                 :   | t         vr$t        d|  ddj                  t                      g d}| g|D cg c]
  }|| k7  s	| c}z   }g }|D ];  }t        ||| k(        s|| k(  r|nd}|j	                  |t        |   |      f       = t        |      S c c}w )uG  Like get_provider() but promotes `primary` to the front of the fallback chain.

    `model_override` applies to the primary provider only — if the user picked
    "Gemini 2.0 Flash" we honour that exact model; fallback providers use their
    own configured defaults so they work without the caller knowing their models.
    r.   r/   r0   r6   r1   N)r'   r2   r3   r,   r;   r   )rA   rB   fallback_orderpordered	providersr(   r	   s           r   get_provider_starting_withrH   ]   s     i-gY6MdiiXaNbMcdee@NinEW1EEG/1I =Ddgo?&*goN4EdIdOE$:;<=
 I&& Fs   
BBc                     t         j                  } | t        vrt        d|  d      g d}| g|D cg c]
  }|| k7  s	| c}z   }g }|D ]1  }t	        ||| k(        s|j                  |t        |          f       3 t        |      S c c}w )ua  Build a FallbackProvider that tries LLM_PROVIDER first, then any other
    provider that has credentials configured, in a fixed fallback order.

    Order: primary (LLM_PROVIDER) → gemini → openai → anthropic → ollama
    (primary is moved to front; duplicates skipped; Gemini leads the fallback
    chain because it is free-tier friendly).
    zUnknown LLM_PROVIDER 'u;   ' — expected 'openai', 'anthropic', 'gemini', or 'ollama'r6   r1   )r   r:   r'   r2   r,   r;   r   )rA   rD   rE   rF   rG   r(   s         r   get_providerrJ   s   s     ##Gi$WI-hi
 	
 ANinEW1EEG/1I 8Ddgo?dIdO$5678 I&& Fs
   
B	B	)N)configr   anthropic_providerr   baser   fallback_providerr   openai_providerr   strr   r   r   r"   r'   dictobject__annotations__r+   r,   r4   listr@   rH   rJ    r   r   <module>rV      s     1  / 5t { C$J + t { t {  !	 	4V 3 D T c k T
 (' 'S4Z 'Sc ','& 'r   