o
    z­j=0  ã                   @   s:  d Z ddlZddlmZmZmZmZmZmZ ddl	Z	ddl
mZ ddlmZ ddlZe	je	jd� e	 e¡ZG dd„ deƒZeG d	d
„ d
ƒƒZG dd„ dƒZddlmZ ddlmZ G dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ dƒZG dd„ dƒZ eƒ Z!e ƒ Z"e! #ee!ƒ¡ e! #ee!ƒ¡ e! #ee!ƒ¡ dS )zÖ
Multi-Agent System for CropPilot
This module implements a multi-agent system architecture that coordinates specialized agents
for crop disease detection, yield prediction, market analysis, and voice interactions.
é    N)ÚDictÚListÚAnyÚOptionalÚCallableÚUnion)ÚEnum)Ú	dataclass)Úlevelc                   @   s8   e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdZdS )Ú	AgentTypez)Types of specialized agents in the systemÚcoordinatorÚdisease_detectorÚyield_predictorÚmarket_analyzerÚvoice_assistantÚ
translatorÚchat_assistantÚmarket_expertÚweather_advisorÚcrop_doctorN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚCOORDINATORÚDISEASE_DETECTORÚYIELD_PREDICTORÚMARKET_ANALYZERÚVOICE_ASSISTANTÚ
TRANSLATORÚCHAT_ASSISTANTÚMARKET_EXPERTÚWEATHER_ADVISORÚCROP_DOCTOR© r$   r$   ú7/var/www/html/CropPilot/backend/app/core/multi_agent.pyr      s    r   c                   @   sz   e Zd ZU dZeed< eed< eed< eed< dZe	eef ed< de	eef fd	d
„Z
ede	eef dd fdd„ƒZdS )ÚMessagez,Message object for inter-agent communicationÚsenderÚreceiverÚcontentÚmessage_typeNÚcontextÚreturnc                 C   s"   | j j| jj| j| j| jpi dœS )zConvert message to dictionary©r'   r(   r)   r*   r+   )r'   Úvaluer(   r)   r*   r+   ©Úselfr$   r$   r%   Úto_dict'   s   ûzMessage.to_dictÚdatac              	   C   s2   | t |d ƒt |d ƒ|d |d | di ¡d�S )zCreate message from dictionaryr'   r(   r)   r*   r+   r-   )r   Úget)Úclsr2   r$   r$   r%   Ú	from_dict1   s   


ûzMessage.from_dict)r   r   r   r   r   Ú__annotations__r   Ústrr+   r   r1   Úclassmethodr5   r$   r$   r$   r%   r&      s   
 
 r&   c                   @   sL   e Zd ZdZddeddfdd„Zded	efd
d„Zde	de
e	 fdd„ZdS )ÚAgentz*Base agent class with common functionalityNÚ
agent_typer   ÚAgentCoordinatorc                 C   s   || _ || _i | _d S ©N)r:   r   Úmessage_handlers)r0   r:   r   r$   r$   r%   Ú__init__?   s   
zAgent.__init__r*   Úhandlerc                 C   ó   || j |< dS )z.Register a handler for a specific message typeN)r=   )r0   r*   r?   r$   r$   r%   Úregister_handlerD   ó   zAgent.register_handlerÚmessager,   c                 Ã   sD   �|j | jv r| j|j  |ƒI dH S t d| jj› d|j › �¡ dS )z9Process incoming message and optionally return a responseNúAgent z! has no handler for message type )r*   r=   ÚloggerÚwarningr:   r.   )r0   rC   r$   r$   r%   Úhandle_messageH   s
   €zAgent.handle_messager<   )r   r   r   r   r   r>   r7   r   rA   r&   r   rG   r$   r$   r$   r%   r9   <   s
    r9   )Úget_settingsc                       ó*   e Zd ZdZd‡ fdd„	Zdd„ Z‡  ZS )ÚMarketExpertAgentz,Specialized agent for market-related queriesNc                    óT   t ƒ  tj|¡ |  d| j¡ tƒ }|jr!|jdkr!tj	|jd� t 
|j¡| _d S ©NÚchatÚYOUR_GEMINI_API_KEY_NOT_SET)Úapi_key)Úsuperr>   r   r!   rA   Úhandle_chatrH   ÚGEMINI_API_KEYÚgenaiÚ	configureÚGenerativeModelÚGEMINI_MODELÚgemini_model©r0   r   Ús©Ú	__class__r$   r%   r>   V   ó   zMarketExpertAgent.__init__c              
   Ã   ó¦   �|j  dd¡}d}|› d|› �}z| j |¡}t|dƒr |jnt|ƒ}W n# tyH } zt 	| j
j› d|› �¡ d|› �}W Y d }~nd }~ww t| j
|j|dd	�S )
NrC   Ú zòYou are MarketExpert, an AI specialized in Indian agricultural markets. Provide accurate, up-to-date advice on prices, trends, and market strategies. Use real data if available. If the user asks about a specific crop or location, be specific.ú
User: Útextú Gemini error: z:Sorry, MarketExpert AI is temporarily unavailable. Error: Úchat_response©r'   r(   r)   r*   ©r)   r3   rW   Úgenerate_contentÚhasattrr`   r7   Ú	ExceptionrE   Úerrorr:   r.   r&   r'   ©r0   rC   Úuser_messageÚsystem_promptÚpromptÚgemini_responseÚresponse_textÚer$   r$   r%   rQ   ^   ó&   €ÿ€þüzMarketExpertAgent.handle_chatr<   ©r   r   r   r   r>   rQ   Ú__classcell__r$   r$   rZ   r%   rJ   T   ó    rJ   c                       rI   )ÚWeatherAdvisorAgentz-Specialized agent for weather-related queriesNc                    rK   rL   )rP   r>   r   r"   rA   rQ   rH   rR   rS   rT   rU   rV   rW   rX   rZ   r$   r%   r>   w   r\   zWeatherAdvisorAgent.__init__c              
   Ã   r]   )
NrC   r^   zÃYou are WeatherAdvisor, an AI expert in Indian agricultural weather. Provide accurate weather forecasts, climate advice, and explain how weather impacts farming. Reference real data if available.r_   r`   ra   z<Sorry, WeatherAdvisor AI is temporarily unavailable. Error: rb   rc   rd   ri   r$   r$   r%   rQ      rp   zWeatherAdvisorAgent.handle_chatr<   rq   r$   r$   rZ   r%   rt   u   rs   rt   c                       sV   e Zd ZdZd‡ fdd„	Zdd„ Zddeded	ed
e	eef de
e f
dd„Z‡  ZS )ÚCropDoctorAgentz6Specialized agent for crop and disease-related queriesNc                    rK   rL   )rP   r>   r   r#   rA   rQ   rH   rR   rS   rT   rU   rV   rW   rX   rZ   r$   r%   r>   ˜   r\   zCropDoctorAgent.__init__c              
   Ã   r]   )
NrC   r^   zèYou are CropDoctor, an AI expert in Indian crop health, soil, and disease management. Give actionable, specific advice for crop issues, pest management, and soil health. Reference real data and best practices for Indian agriculture.r_   r`   ra   z8Sorry, CropDoctor AI is temporarily unavailable. Error: rb   rc   rd   ri   r$   r$   r%   rQ       rp   zCropDoctorAgent.handle_chatr(   r)   r*   r+   r,   c                 Ã   sH   �| j rt| j||||d�}| j  |¡I dH S t d| jj› d�¡ dS )z-Send message to another agent via coordinatorr-   NrD   z$ has no coordinator to send messages)r   r&   r:   Úroute_messagerE   rh   r.   )r0   r(   r)   r*   r+   rC   r$   r$   r%   Úsend_message·   s   €ûzCropDoctorAgent.send_messager<   )r   r   r   r   r>   rQ   r   r   r7   r   r   r&   rw   rr   r$   r$   rZ   r%   ru   –   s
    4ru   c                   @   sx   e Zd ZdZdd„ Zdefdd„Zdedee fd	d
„Z	dde
dededeeef dee f
dd„Zdd„ Zdd„ ZdS )r;   z4Central coordinator for managing agent communicationc                 C   s   i | _ t ¡ | _d| _d S )NF)ÚagentsÚasyncioÚQueueÚmessage_queueÚrunningr/   r$   r$   r%   r>   É   s   

zAgentCoordinator.__init__Úagentc                 C   s*   | |_ || j|j< t d|jj› �¡ dS )z&Register an agent with the coordinatorzRegistered agent: N)r   rx   r:   rE   Úinfor.   )r0   r}   r$   r$   r%   Úregister_agentÎ   s   zAgentCoordinator.register_agentrC   r,   c              
   Ã   s    �|j | jvrt d|j j› �¡ dS z!t d|jj› d|j j› d|j› d�¡ | j|j   |¡I dH W S  t	yO } zt d|› �¡ W Y d}~dS d}~ww )z(Route a message to the appropriate agentzNo agent registered for type: NzRouting message: z -> z (ú)zError routing message: )
r(   rx   rE   rh   r.   Údebugr'   r*   rG   rg   )r0   rC   ro   r$   r$   r%   rv   Ô   s   €(€þzAgentCoordinator.route_messageNr'   r)   r*   r+   c           
      Ã   sV   �g }| j  ¡ D ] \}}||kr(t|||||d�}| |¡I dH }	|	r(| |	¡ q|S )z.Send a message to all agents except the senderr-   N)rx   Úitemsr&   rG   Úappend)
r0   r'   r)   r*   r+   Ú	responsesr:   r}   rC   Úresponser$   r$   r%   Úbroadcast_messageá   s    €û
€z"AgentCoordinator.broadcast_messagec                 Ã   ó   �d| _ t d¡ dS )z(Start processing messages from the queueTzAgent coordinator startedN©r|   rE   r~   r/   r$   r$   r%   Ústartò   ó   €zAgentCoordinator.startc                 Ã   r‡   )zStop the coordinatorFzAgent coordinator stoppedNrˆ   r/   r$   r$   r%   Ústop÷   rŠ   zAgentCoordinator.stopr<   )r   r   r   r   r>   r9   r   r&   r   rv   r   r   r7   r   r   r†   r‰   r‹   r$   r$   r$   r%   r;   Æ   s    ,r;   c                   @   sh   e Zd ZdZdd„ Zdedefdd„Zdedee fd	d
„Z	dede
eef fdd„Zdefdd„ZdS )ÚModelContextProtocolz˜
    Protocol for maintaining context between agent interactions.
    This allows agents to share a common understanding of the conversation state.
    c                 C   s
   i | _ d S r<   ©Úcontextsr/   r$   r$   r%   r>     s   
zModelContextProtocol.__init__Ú
context_idr2   c                 C   r@   )z"Set context data for a specific IDNr�   ©r0   r�   r2   r$   r$   r%   Úset_context  rB   z ModelContextProtocol.set_contextr,   c                 C   s   | j  |¡S )z"Get context data for a specific ID)rŽ   r3   ©r0   r�   r$   r$   r%   Úget_context	  s   z ModelContextProtocol.get_contextc                 C   sR   || j v r!t| j | tƒr| j |  |¡ dS t d|› �¡ dS |  ||¡ dS )z%Update existing context with new dataz Cannot update non-dict context: N)rŽ   Ú
isinstanceÚdictÚupdaterE   rF   r‘   r�   r$   r$   r%   Úupdate_context  s
   
z#ModelContextProtocol.update_contextc                 C   s   || j v r| j |= dS dS )zClear context for a specific IDNr�   r’   r$   r$   r%   Úclear_context  s   
ÿz"ModelContextProtocol.clear_contextN)r   r   r   r   r>   r7   r   r‘   r   r“   r   r—   r˜   r$   r$   r$   r%   rŒ   ü   s    
rŒ   )$r   ry   Útypingr   r   r   r   r   r   ÚloggingÚenumr   Údataclassesr	   ÚjsonÚbasicConfigÚINFOÚ	getLoggerr   rE   r   r&   r9   Úgoogle.generativeaiÚgenerativeairS   Úapp.core.configrH   rJ   rt   ru   r;   rŒ   r   Úcontext_protocolr   r$   r$   r$   r%   Ú<module>   s4     
!!06!