a
    dg#                     @  s   d dl mZ d dlZd dlmZmZmZmZ d dlm	Z	 d dl
mZmZmZmZmZ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eZG dd deZG dd deZG dd deZG dd deZG dd deZdS )    )annotationsN)AnyListOptionalUnion)NetworkxEntityGraph)	BaseModel
ConfigDictFieldPrivateAttrfield_validatormodel_validator)Constantc                   @  sF   e Zd ZU dZded< ded< ded< eddddd	d
ddZdS )NarrativeModelz2
    Narrative input as three story elements.
    strZstory_outcome_questionZstory_hypotheticalZ
story_plot*beforemodeUnion[str, None]vreturnc                 C  s   |dkrdS |S )zEmpty strings are not allowed N clsr   r   r   p/var/www/html/cobodadashboardai.evdpl.com/venv/lib/python3.9/site-packages/langchain_experimental/cpal/models.pyempty_str_to_none   s    z NarrativeModel.empty_str_to_noneN)__name__
__module____qualname____doc____annotations__r   r   r   r   r   r   r      s   

r   c                   @  s~   e Zd ZU dZeddZded< eddZded< eddZd	ed
< eg ddZ	ded< e
ddZeddddddZdS )EntityModelzEntity in the story.zentity namedescriptionr   namezentity actionscodezentity initial valuefloatvaluezancestor entities)defaultr&   z	List[str]
depends_onT)Zvalidate_assignmentr   c                 C  s   |  }|S Nlowerr   r   r   r   lower_case_name3   s    zEntityModel.lower_case_nameN)r   r    r!   r"   r
   r'   r#   r(   r*   r,   r	   Zmodel_configr   r0   r   r   r   r   r$   $   s   
r$   c                   @  s6   e Zd ZU dZeddZded< eddZded< d	S )
CausalModelzCasual data.&name of the attribute to be calculatedr%   r   	attributezentities in the storyzList[EntityModel]entitiesN)r   r    r!   r"   r
   r3   r#   r4   r   r   r   r   r1   9   s   
r1   c                   @  s`   e Zd ZU dZeddZded< eddZded< eddZd	ed
< e	ddddddZ
dS )EntitySettingModelzEntity initial conditions.

    Initial conditions for an entity

    {"name": "bud", "attribute": "pet_count", "value": 12}
    zname of the entityr%   r   r'   r2   r3   z%entity's attribute value (calculated)r)   r*   r   c                 C  s   |  }|S r-   r.   r   r   r   r   lower_case_transformN   s    z'EntitySettingModel.lower_case_transformN)r   r    r!   r"   r
   r'   r#   r3   r*   r   r6   r   r   r   r   r5   B   s   
r5   c                   @  s"   e Zd ZU dZded< ded< dS )SystemSettingModelzSystem initial conditions.

    Initial global conditions for the system.

    {"parameter": "interest_rate", "value": .05}
    r   Z	parameterr)   r*   N)r   r    r!   r"   r#   r   r   r   r   r7   T   s   
r7   c                   @  s>   e Zd ZU dZded< dZded< edddd	d
dZdS )InterventionModela0  Intervention data of the story aka initial conditions.

    >>> intervention.dict()
    {
        entity_settings: [
            {"name": "bud", "attribute": "pet_count", "value": 12},
            {"name": "pat", "attribute": "pet_count", "value": 0},
        ],
        system_settings: None,
    }
    zList[EntitySettingModel]entity_settingsNz"Optional[List[SystemSettingModel]]system_settingsr   r   r   c                 C  s   |d urt d|S )Nz%system_setting is not implemented yet)NotImplementedErrorr   r   r   r   r0   p   s    z!InterventionModel.lower_case_name)r   r    r!   r"   r#   r:   r   r0   r   r   r   r   r8   `   s
   
r8   c                   @  sF   e Zd ZU dZeejjdZde	d< de	d< de	d< e
 Zde	d< dS )	
QueryModelziQuery data of the story.

    translate a question about the story outcome into a programmatic expressionaliasr   question
expressionllm_error_msg_result_tableNr   r    r!   r"   r
   r   Znarrative_inputr*   r?   r#   r   rB   r   r   r   r   r<   w   s   
r<   c                   @  s6   e Zd ZU dZeejjdZde	d< e
 Zde	d< dS )ResultModelzResult of the story query.r=   r   r?   rB   NrC   r   r   r   r   rD      s
   
rD   c                      s  e Zd ZU dZe Zded< e Zded< e Zded< e	ddZ
ded< e	ddZded	< dd
 fddZeddedddddZddddZddddZddddZddddZddddZdddd Zddd!d"Zddd#d$Z  ZS )%
StoryModelzStory data.r   causal_operationsinterventionqueryN)r+   _outcome_table_networkx_wrapper)kwargsc                   s   t  jf i | |   d S r-   )super__init___compute)selfrK   	__class__r   r   rM      s    zStoryModel.__init__r   r   dict)valuesr   c                 C  sN   dd |d j D }|d jD ]*}|j|vrd|j d| d}t|q|S )Nc                 S  s   g | ]
}|j qS r   r'   ).0er   r   r   
<listcomp>       z:StoryModel.check_intervention_is_valid.<locals>.<listcomp>rF   rG   z\
                    Hypothetical question has an invalid entity name.
                    `z
` not in `z`
                )r4   r9   r'   
ValueError)r   rS   Zvalid_namesZsetting	error_msgr   r   r   check_intervention_is_valid   s    

z&StoryModel.check_intervention_is_validNone)r   c                 C  s:   dd | j jD }| jjD ]}|j|v rg |_d|_qd S )Nc                 S  s   g | ]
}|j qS r   rT   )rU   entity_settingr   r   r   rW      s   z5StoryModel._block_back_door_paths.<locals>.<listcomp>pass)rG   r9   rF   r4   r'   r,   r(   )rO   Zintervention_entitiesentityr   r   r   _block_back_door_paths   s    
z!StoryModel._block_back_door_pathsc                 C  s4   | j jD ]&}| jjD ]}|j|jkr|j|_qqd S r-   )rG   r9   rF   r4   r'   r*   )rO   r]   r_   r   r   r   _set_initial_conditions   s    z"StoryModel._set_initial_conditionsc                   sX   t   _ jjD ](}|jD ]} jjj||j|jd qq fdd jjD  j_d S )N)Zrelationc                   s    g | ]}|j  j v r|qS r   )r'   rJ   get_topological_sortrU   r_   rO   r   r   rW      s   z*StoryModel._make_graph.<locals>.<listcomp>)	r   rJ   rF   r4   r,   Z_graphZadd_edger'   r(   )rO   r_   parent_namer   rd   r   _make_graph   s    



zStoryModel._make_graphc                   s&   | j   | jjj fddd d S )Nc                   s     | jS r-   )indexr'   )xZsorted_nodesr   r   <lambda>   rX   z+StoryModel._sort_entities.<locals>.<lambda>)key)rJ   rb   rF   r4   sortrd   r   ri   r   _sort_entities   s    
zStoryModel._sort_entitiesc              
   C  s   zdd l }W n. ty: } ztd|W Y d }~n
d }~0 0 dd | jjD }| jjD ]"}|jdkrhqVqVt|jt | qVdd | D }||| _	d S )Nr   zBUnable to import pandas, please install with `pip install pandas`.c                 S  s   i | ]}|j |qS r   rT   rc   r   r   r   
<dictcomp>   s   z1StoryModel._forward_propagate.<locals>.<dictcomp>r^   c                 S  s   g | ]}|  qS r   )rR   rc   r   r   r   rW      rX   z1StoryModel._forward_propagate.<locals>.<listcomp>)
ZpandasImportErrorrF   r4   r(   execglobalsrS   Z	DataFramerI   )rO   pdrV   Zentity_scoper_   Z
row_valuesr   r   r   _forward_propagate   s"    
zStoryModel._forward_propagatec              
   C  s   ddddd}| j jdkrz,dd l}| j}|| j j }|| j _W q |jy~ } z|t	|| j _W Y d }~qd }~0  t
y } zt
d|W Y d }~qd }~0  ty } zt	|| j _W Y d }~qd }~0 0 nd}t| j j| j j|d	d S )
Nr   )errorr   c                 S  s2   d}t || }|r&d|d d S t| S d S )Nzcolumn\s+(.*?)\s+not foundzSQL error:    z# is not an attribute in your story!)researchgroupr   )rt   patternZ	col_matchr   r   r   humanize_sql_error_msg   s    z5StoryModel._run_query.<locals>.humanize_sql_error_msgr   r   zBUnable to import duckdb, please install with `pip install duckdb`.z4LLM maybe failed to translate question to SQL query.)r?   rA   msg)rH   rA   duckdbrI   sqlr@   dfrB   ZBinderExceptionr   ro   	ExceptionrY   r?   )rO   rz   r|   r~   Zquery_resultrV   r{   r   r   r   
_run_query   s0    $$zStoryModel._run_queryc                 C  s4   |    |   |   |   |   |   d S r-   )r`   ra   rf   rm   rs   r   rd   r   r   r   rN     s    zStoryModel._computec                 C  s0   | j | j | jjd}ddlm} || d S )N)outcomerH   resultr   )pprint)rI   rH   rR   rB   r   )rO   reportr   r   r   r   print_debug_report  s    zStoryModel.print_debug_report)r   r    r!   r"   r
   rF   r#   rG   rH   r   rI   rJ   rM   r   classmethodr[   r`   ra   rf   rm   rs   r   rN   r   __classcell__r   r   rP   r   rE      s$   

&rE   )
__future__r   rv   typingr   r   r   r   Z)langchain_community.graphs.networkx_graphr   Zpydanticr   r	   r
   r   r   r   Z%langchain_experimental.cpal.constantsr   r   r$   r1   r5   r7   r8   r<   rD   rE   r   r   r   r   <module>   s    			