Ë
    fåÚhî*  ã                   ó¤   — 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	m
Z
mZ ddlZddlmZ ddlmZ  G d„ d	ee«      Z G d
„ d«      Z G d„ d«      Zy)zN
Agent Factory for creating PydanticAI agents with different model providers.
é    N)ÚEnum)ÚPath)ÚAnyÚDictÚListÚOptionalÚType)Ú	BaseModel)ÚAgentc                   ó0   — e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zy
)ÚModelProviderzSupported model providers.Ú	anthropicÚopenaiÚgroqÚgeminiÚvertexaiÚbedrockÚmistralÚollamaN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú	ANTHROPICÚOPENAIÚGROQÚGEMINIÚVERTEXAIÚBEDROCKÚMISTRALÚOLLAMA© ó    ú2/home/mande/repo/quber/src/quber/agents/factory.pyr   r      s-   „ Ù$à€IØ€FØ€DØ€FØ€HØ€GØ€GØ�Fr#   r   c                   ó¾  — e Zd ZdZej
                  dej                  dej                  dej                  dej                  dej                  dej                  dej                  diZej
                  d	ej                  d
ej                  dej                  dej                  dej                  dej                  dej                  diZedeeee   f   fd„«       Zy)ÚModelConfigzModel configuration mappings.zclaude-3-5-haiku-latestzgpt-4o-minizllama-3.1-8b-instantzgemini-1.5-flashz(anthropic.claude-3-5-haiku-20241022-v1:0zmistral-small-latestzllama3.2ÚANTHROPIC_API_KEYÚOPENAI_API_KEYÚGROQ_API_KEYÚGEMINI_API_KEYÚGOOGLE_APPLICATION_CREDENTIALSÚAWS_ACCESS_KEY_IDÚMISTRAL_API_KEYNÚreturnc                 óð  — 	 t        t        «      j                  j                  j                  j                  dz  }|j                  «       si S |j	                  «       }ddl}i }d}|j                  ||«      }|D ]A  }d|v sŒ|j                  dd«      \  }}	||vrg ||<   |	||   vsŒ.||   j                  |	«       ŒC |S # t        $ r,}
ddl
}d|j                  v rt        d|
› �«       i cY d}
~
S d}
~
ww xY w)	z�
        Load known models from known_models.py file.

        Returns:
            Dictionary mapping provider to list of model names
        zknown_models.pyr   Nz"([^"]+:[^"]+)"Ú:é   z--debugzError loading known_models: )r   Ú__file__ÚparentÚexistsÚ	read_textÚreÚfindallÚsplitÚappendÚ	ExceptionÚsysÚargvÚprint)ÚclsÚknown_models_pathÚcontentr6   Úmodels_by_providerÚpatternÚmatchesÚmatchÚproviderÚmodelÚer;   s               r$   Úget_known_modelszModelConfig.get_known_models7   s  € ð!	ä $¤X£× 5Ñ 5× <Ñ <× CÑ C× JÑ JÐM^Ñ ^ÐØ$×+Ñ+Ô-Ø�	ð (×1Ñ1Ó3ˆGó à!#Ðð )ˆGØ—j‘j ¨'Ó2ˆGã �Ø˜%’<Ø&+§k¡k°#°qÓ&9‘O�H˜eØÐ'9Ñ9Ø79Ð*¨8Ñ4ØÐ$6°xÑ$@Ò@Ø*¨8Ñ4×;Ñ;¸EÕBð !ð &Ð%øÜò 	ãà˜CŸH™HÑ$ÜÐ4°Q°CÐ8Ô9Ø�Iûð	ús0   ‚AC  Á3C  Â%C  Â(C  Ã 	C5Ã	!C0Ã*C5Ã0C5)r   r   r   r   r   r   r   r   r   r   r   r    r!   ÚDEFAULT_MODELSÚAPI_KEY_VARSÚclassmethodr   Ústrr   rH   r"   r#   r$   r&   r&      sû   „ Ù'ð 	×ÑÐ!:Ø×Ñ˜mØ×ÑÐ2Ø×ÑÐ0Ø×ÑÐ 2Ø×ÑÐIØ×ÑÐ5Ø×Ñ˜jð	€Nð 	×ÑÐ!4Ø×ÑÐ.Ø×Ñ˜NØ×ÑÐ.Ø×ÑÐ @Ø×ÑÐ2Ø×ÑÐ0Ø×Ñ˜dð	€Lð ð(  c¨4°©9 nÑ!5ò (ó ñ(r#   r&   c                   ó¶   — e Zd ZdZddefd„Z	 	 	 ddee   dede	e
   de	e   d	ed
edefd„Zde	e
   fd„Zde
dedefd„Zdde	e
   deeef   fd„Zdee   fd„Zy)ÚAgentFactorya  
    Factory for creating PydanticAI agents with different model providers.

    This factory provides a unified interface for creating agents that can work
    with various LLM providers, automatically handling API key configuration
    and model selection.
    Úenable_logfirec                 ób  — || _         |rŸt        j                  d«      rŠt        t        d«      srt	        j
                  dt        j                  d«      d¬«       t	        j                  «        t	        j                  «        t	        j                  «        dt        _	        d| _
        yd| _
        y)z~
        Initialize the Agent Factory.

        Args:
            enable_logfire: Whether to enable logfire telemetry
        ÚPYDANTIC_LOGFIRE_TOKENÚ_configuredÚquberF)Úservice_nameÚtokenÚconsoleTN)rO   ÚosÚgetenvÚhasattrÚlogfireÚ	configureÚinstrument_anthropicÚinstrument_openaiÚinstrument_pydantic_airR   Úlogfire_configured)ÚselfrO   s     r$   Ú__init__zAgentFactory.__init__l   s„   € ð -ˆÔÙœbŸi™iÐ(@ÔAäœ7 MÔ2Ü×!Ñ!Ø!(ÜŸ)™)Ð$<Ó=Ø!õô ×,Ñ,Ô.Ü×)Ñ)Ô+Ü×.Ñ.Ô0Ø&*”Ô#Ø&*ˆDÕ#à&+ˆDÕ#r#   NÚoutput_typeÚsystem_promptrE   rF   Ústrict_validationÚagent_kwargsr.   c           	      ó
  — |rGd|v rC|j                  dd«      \  }}t        D ]%  }	|	j                  |j                  «       k(  sŒ!|	}|} n |€\| j	                  «       }|€Jt        ddj                  t        j                  j                  «       D �
cg c]  }
|
sŒ|
‘Œ	 c}
«      z   «      ‚t        j                  j                  |«      }|r#t        j                  |«      st        d|› �«      ‚|€t        j                  |   }n†|r„t        j                  «       }|j                  |j                  g «      }|rR||vrN|dd }dj                  |«      }t        |«      dkD  rdt        |«      dz
  › d	�nd
}t        d|› d|› d|› |› �«      ‚| j!                  ||«      }| j"                  r<t%        j&                  d|j                  |¬«      5  t)        |f||dœ|¤Ž}ddd«       |S t)        |f||dœ|¤Ž}|S c c}
w # 1 sw Y   S xY w)a¬  
        Create a PydanticAI agent with the specified configuration.

        Args:
            output_type: The Pydantic model for structured output
            system_prompt: System prompt for the agent
            provider: Model provider to use (auto-detected if not specified)
            model: Specific model to use (uses default if not specified)
            strict_validation: If False, allows any model string without validation
            **agent_kwargs: Additional kwargs to pass to Agent constructor

        Returns:
            Configured PydanticAI Agent instance

        Raises:
            ValueError: If no valid API key is found or invalid configuration
        r0   r1   Nz%No API key found. Please set one of: z, zAPI key not found: é   z (and z more)Ú zModel 'z' not recognized for z. Examples: Úcreate_agent)rE   rF   )rb   rc   )r8   r   ÚvalueÚlowerÚ_detect_providerÚ
ValueErrorÚjoinr&   rJ   ÚvaluesÚgetrW   rX   rI   rH   ÚlenÚ_format_model_stringr_   rZ   Úspanr   )r`   rb   rc   rE   rF   rd   re   Úprovider_strÚ
model_nameÚpÚvÚapi_key_varÚknown_modelsÚprovider_modelsÚexample_modelsÚexamplesÚmoreÚ	model_strÚagents                      r$   ri   zAgentFactory.create_agent…   s&  € ñ6 �S˜E‘\Ø',§{¡{°3¸Ó':Ñ$ˆL˜*ç"�Ø—7‘7˜l×0Ñ0Ó2Ó2Ø �HØ&�EÙð	 #ð ÐØ×,Ñ,Ó.ˆHØÐÜ Ø;Ø—i‘i¬K×,DÑ,D×,KÑ,KÔ,MÓ SÑ,M qÒQR¢Ð,MÑ SÓTñUóð ô "×.Ñ.×2Ñ2°8Ó<ˆÙœrŸy™y¨Ô5ÜÐ2°;°-Ð@ÓAÐAð ˆ=Ü×.Ñ.¨xÑ8‰EÙä&×7Ñ7Ó9ˆLØ*×.Ñ.¨x¯~©~¸rÓBˆOÙ 5°Ñ#?à!0°°!Ð!4�ØŸ9™9 ^Ó4�ÜDGÈÓDXÐ[\ÒD\˜¤ OÓ 4°qÑ 8Ð9¸Ñ@Ðbd�Ü  7¨5¨'Ð1FÀxÀjÐP\Ð]eÐ\fÐgkÐflÐ!mÓnÐnð ×-Ñ-¨h¸Ó>ˆ	ð ×"Ò"Ü—‘˜n°x·~±~ÈUÖSÜ˜iÐn°[ÐP]ÑnÐamÑn�÷ Tð
 ˆô ˜)Ðj°ÈMÑjÐ]iÑjˆEàˆùòA !T÷6 Tð
 ˆús   ÂG3ÂG3ÇG8Ç8Hc                 óâ   — t         j                  t         j                  t         j                  t         j                  g}|D ],  }t        j                  t        j                  |   «      sŒ*|c S  y)z¤
        Auto-detect available provider based on environment variables.

        Returns:
            First available provider or None if no API keys found
        N)	r   r   r   r   r   rW   rX   r&   rJ   )r`   ÚpriorityrE   s      r$   rl   zAgentFactory._detect_providerÑ   s\   € ô ×#Ñ#Ü× Ñ Ü×ÑÜ× Ñ ð	
ˆó !ˆHÜ�y‰yœ×1Ñ1°(Ñ;Õ<Ø’ð !ð r#   c                 ót   — |t         j                  k(  r|j                  d«      r|S |S |j                  › d|› �S )zå
        Format model string for PydanticAI based on provider.

        Args:
            provider: The model provider
            model: The model name

        Returns:
            Formatted model string for PydanticAI
        z
anthropic:r0   )r   r   Ú
startswithrj   )r`   rE   rF   s      r$   rr   z!AgentFactory._format_model_stringæ   sB   € ð ”}×.Ñ.Ò.à×Ñ Ô-Ø�àˆLð —.‘.Ð!  5 'Ð*Ð*r#   c                 ób  — t         j                  «       }|rE|j                  }|j                  |g «      }|s!t         j                  j                  |d«      g}||iS i }t
        D ]H  }|j                  }|j                  |g «      }|s!t         j                  j                  |d«      g}|||<   ŒJ |S )zÙ
        List available models for each provider.

        Args:
            provider: Specific provider to list models for (all if None)

        Returns:
            Dictionary of provider -> list of models
        zNo models found)r&   rH   rj   rp   rI   r   )r`   rE   ry   Úprovider_nameÚmodelsÚresultrv   s          r$   Úlist_available_modelsz"AgentFactory.list_available_modelsý   s¶   € ô #×3Ñ3Ó5ˆáØ$ŸN™NˆMØ!×%Ñ% m°RÓ8ˆFáÜ%×4Ñ4×8Ñ8¸ÐCTÓUÐV�Ø! 6Ð*Ð*ð ˆßˆAØŸG™GˆMØ!×%Ñ% m°RÓ8ˆFáÜ%×4Ñ4×8Ñ8¸Ð<MÓNÐO�Ø$*ˆF�=Ò!ð ð ˆr#   c                 ó$  — g }t         D ]„  }t        j                  j                  |«      }|€0|t         j                  k(  sŒ8|j                  |j                  «       ŒTt        j                  |«      sŒj|j                  |j                  «       Œ† |S )z€
        Get list of providers with configured API keys.

        Returns:
            List of available provider names
        )	r   r&   rJ   rp   r!   r9   rj   rW   rX   )r`   Ú	availablerE   rx   s       r$   Úget_available_providersz$AgentFactory.get_available_providers  su   € ð ˆ	ß%ˆHÜ%×2Ñ2×6Ñ6°xÓ@ˆKàÐ"àœ}×3Ñ3Ó3Ø×$Ñ$ X§^¡^Õ4Ü—‘˜;Õ'Ø× Ñ  §¡Õ0ð &ð Ðr#   )T)NNF)N)r   r   r   r   Úboolra   r	   r
   rL   r   r   r   r   ri   rl   rr   r   Úlistrˆ   r‹   r"   r#   r$   rN   rN   c   sÞ   „ ññ, tó ,ð: -1Ø#Ø"'ñJà˜)‘_ðJð ðJð ˜=Ñ)ð	Jð
 ˜‰}ðJð  ðJð ðJð 
óJðX (¨=Ñ"9ó ð*+¨]ð +À3ð +È3ó +ñ.¨h°}Ñ.Eð ÐQUÐVYÐ[_ÐV_ÑQ`ó ðB¨¨c©ô r#   rN   )r   rW   Úenumr   Úpathlibr   Útypingr   r   r   r   r	   rZ   Úpydanticr
   Úpydantic_air   rL   r   r&   rN   r"   r#   r$   Ú<module>r“      sK   ðñó 
Ý Ý ß 2Õ 2ã Ý Ý ô
�C˜ô 
÷Dñ D÷NLò Lr#   