
    {h08                        d dl 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
 d dlmZmZmZ d dlmZmZ d dlmZ eeefZ G d d	e      Z G d
 d      Zedk(  rpd dlZd dlmZmZ d dlZ G d de      Z G d de      Z G d de      Z G d de      Z ed      Z e jC                  d eddg d edd                   e jC                  d  ed!d" ed#d       ed$d%      d&'             ejD                  jG                  d(d)      Z$ejD                  jK                  e$      r4e jC                  d ed*ej                  jM                  e$      g+             e jO                         Z( e)d,        e)e(        e       Z*e*jW                  e(        e)d-        e,e*jZ                        D ]  \  Z.Z/ e)d.e.d/z    d0        e)d1e/j`                           e)d2e/jb                           e)d3 e2e/jf                        j.                           e)d4       e/jf                  ji                         jk                         D ]  \  Z6Z7 e)d5e6 d6e7           e)d7        e)d8e*jp                           e)d9e*js                                  e)d:       e*jZ                  d;   Z: e)e:jf                  ji                                yy)<    N)Enum)Path)DictListOptionalType)PDFImageAudio)	BaseModelField)BaseIOSchemac                   :    e Zd ZU dZeed<   eed<   dZee   ed<   y)Messagea.  
    Represents a message in the chat history.

    Attributes:
        role (str): The role of the message sender (e.g., 'user', 'system', 'tool').
        content (BaseIOSchema): The content of the message.
        turn_id (Optional[str]): Unique identifier for the turn this message belongs to.
    rolecontentNturn_id)	__name__
__module____qualname____doc__str__annotations__r   r   r        c/var/www/html/hubwallet-dev/venv/lib/python3.12/site-packages/atomic_agents/context/chat_history.pyr   r      s"     I!GXc]!r   r   c                       e Zd ZdZddee   fdZddZdede	ddfd	Z
dd
Zdee   fdZddZdee   fdZdefdZdefdZdefdZdeddfdZededee	   fd       Zd Zy)ChatHistorya1  
    Manages the chat history for an AI agent.

    Attributes:
        history (List[Message]): A list of messages representing the chat history.
        max_messages (Optional[int]): Maximum number of messages to keep in history.
        current_turn_id (Optional[str]): The ID of the current turn.
    Nmax_messagesc                 .    g | _         || _        d| _        y)a  
        Initializes the ChatHistory with an empty history and optional constraints.

        Args:
            max_messages (Optional[int]): Maximum number of messages to keep in history.
                When exceeded, oldest messages are removed first.
        Nhistoryr   current_turn_id)selfr   s     r   __init__zChatHistory.__init__)   s     ')(.2r   returnc                 H    t        t        j                               | _        y)zH
        Initializes a new turn by generating a random turn ID.
        N)r   uuiduuid4r#   r$   s    r   initialize_turnzChatHistory.initialize_turn5   s      #4::<0r   r   r   c                     | j                   | j                          t        ||| j                         }| j                  j	                  |       | j                          y)z
        Adds a message to the chat history and manages overflow.

        Args:
            role (str): The role of the message sender.
            content (BaseIOSchema): The content of the message.
        Nr   r   r   )r#   r+   r   r"   append_manage_overflow)r$   r   r   messages       r   add_messagezChatHistory.add_message;   sU     '  "((

 	G$r   c                     | j                   bt        | j                        | j                   kD  r?| j                  j                  d       t        | j                        | j                   kD  r>yyy)zU
        Manages the chat history overflow based on max_messages constraint.
        Nr   )r   lenr"   popr*   s    r   r/   zChatHistory._manage_overflowR   sW     (dll#d&7&77  # dll#d&7&77 )r   c                 F   g }| j                   D ]  }|j                  }g }|j                  j                  j	                         D ]  \  }}t        ||      }t        |t              rSd}|D ]&  }	t        |	t              s|j                  |	       d}( |rR|j                  |j                  |h             ut        |t              r|j                  |       |j                  |j                  |h              |j                  |j                  |d        |S )aX  
        Retrieves the chat history, handling both regular and multimodal content.

        Returns:
            List[Dict]: The list of messages in the chat history as dictionaries.
            Each dictionary has 'role' and 'content' keys, where 'content' is a list
            that may contain strings (JSON) or multimodal objects.

        Note:
            This method does not support nested multimodal content. If your schema
            contains nested objects that themselves contain multimodal content,
            only the top-level multimodal content will be properly processed.

        FT)include)r   r   )r"   r   	__class__model_fieldsitemsgetattr
isinstancelistINSTRUCTOR_MULTIMODAL_TYPESr.   model_dump_jsonr   )
r$   r"   r0   input_contentprocessed_content
field_namefieldfield_valuehas_multimodal_in_listitems
             r   get_historyzChatHistory.get_historyZ   s    || 	QG#OOM "%2%<%<%I%I%O%O%Q f!
E%mZ@k40-2* + :%d,GH-44T:592: 2)001N1NXbWc1N1de!+/JK)00=)001N1NXbWc1N1de!f$ NNGLL=NOP+	Q. r   c                     t        | j                        }|j                  | j                                | j                  |_        |S )z|
        Creates a copy of the chat history.

        Returns:
            ChatHistory: A copy of the chat history.
        r   )r   r   loaddumpr#   )r$   new_historys     r   copyzChatHistory.copy   s<     "t/@/@A%&*&:&:#r   c                     | j                   S )z
        Returns the current turn ID.

        Returns:
            Optional[str]: The current turn ID, or None if not set.
        )r#   r*   s    r   get_current_turn_idzChatHistory.get_current_turn_id   s     ###r   r   c                 z   t        | j                        }| j                  D cg c]  }|j                  |k7  s| c}| _        t        | j                        |k(  rt        d| d      t        | j                        sd| _        y|| j                  k(  r| j                  d   j                  | _        yyc c}w )a@  
        Delete messages from the history by its turn ID.

        Args:
            turn_id (int): The turn ID of the message to delete.

        Returns:
            str: A success message with the deleted turn ID.

        Raises:
            ValueError: If the specified turn ID is not found in the history.
        zTurn ID z not found in history.N)r3   r"   r   
ValueErrorr#   )r$   r   initial_lengthmsgs       r   delete_turn_idzChatHistory.delete_turn_id   s     T\\*'+||Ns{{g7MNt||.xy0FGHH 4<< #'D ,,,#'<<#3#;#;D  - Os
   B8B8c                 ,    t        | j                        S )z
        Returns the number of messages in the chat history.

        Returns:
            int: The number of messages.
        )r3   r"   r*   s    r   get_message_countzChatHistory.get_message_count   s     4<<  r   c                 p   g }| j                   D ]w  }|j                  j                  }|j                  |j                   d|j
                   |j                  j                         d|j                  d}|j                  |       y || j                  | j                  d}t        j                  |      S )z
        Serializes the entire ChatHistory instance to a JSON string.

        Returns:
            str: A JSON string representation of the ChatHistory.
        .)
class_namedatar-   r!   )r"   r   r7   r   r   r   r>   r   r.   r   r#   jsondumps)r$   serialized_historyr0   content_classserialized_messagehistory_datas         r   rJ   zChatHistory.dump   s      || 
	:G#OO55M%2%=%=$>a@V@V?W"X#OO;;= #??" %%&89
	: * --#33

 zz,''r   serialized_datac                    	 t        j                  |      }g | _        |d   | _        |d   | _        |d   D ]o  }|d   }| j                  |d         }|j                  |d         }| j                  |       t        |d   ||d   	      }| j                  j                  |       q y# t         j                  t        t        t        f$ r}t        d
|       d}~ww xY w)a!  
        Deserializes a JSON string and loads it into the ChatHistory instance.

        Args:
            serialized_data (str): A JSON string representation of the ChatHistory.

        Raises:
            ValueError: If the serialized data is invalid or cannot be deserialized.
        r   r#   r"   r   rY   rZ   r   r   r-   zInvalid serialized data: N)r[   loadsr"   r   r#   _get_class_from_stringmodel_validate_json_process_multimodal_pathsr   r.   JSONDecodeErrorKeyErrorAttributeError	TypeErrorrQ   )	r$   ra   r`   message_datacontent_infor^   content_instancer0   es	            r   rI   zChatHistory.load   s    	>::o6LDL ,^ <D#/0A#BD  ,Y 7 	-+I6 $ ; ;L<V W#0#D#D\RXEY#Z  ../?@!|F';EU_klu_vw##G,	- $$h	J 	>8<==	>s   B'B* *#C CC class_stringc                 `    | j                  dd      \  }}t        ||g      }t        ||      S )a(  
        Retrieves a class object from its string representation.

        Args:
            class_string (str): The fully qualified class name.

        Returns:
            Type[BaseIOSchema]: The class object.

        Raises:
            AttributeError: If the class cannot be found.
        rX      )fromlist)rsplit
__import__r:   )ro   module_namerY   modules       r   rd   z"ChatHistory._get_class_from_string   s6     #/"5"5c1"=ZK:,?vz**r   c                    t        |t        t        f      rQt        |j                  t              r7|j                  j                  d      st        |j                        |_        yyt        |t              r|D ]  }| j                  |        yt        |t              r'|j                         D ]  }| j                  |        yt        |d      r:|j                  D ]*  }t        ||      s| j                  t        ||             , yt        |d      rKt        |t              s:|j                  j!                         D ]  \  }}|dk7  s| j                  |        yyy)a:  
        Process multimodal objects to convert string paths to Path objects.

        Note: this is necessary only for PDF and Image instructor types. The from_path
        behavior is slightly different for Audio as it keeps the source as a string.

        Args:
            obj: The object to process.

        )zhttp://zhttps://zdata:r8   __dict____pydantic_fields_set__N)r;   r
   r	   sourcer   
startswithr   r<   rf   dictvalueshasattrr8   r:   r   rx   r9   )r$   objrE   valuerA   	attr_name
attr_values          r   rf   z%ChatHistory._process_multimodal_paths  s2    cE3<(Z

C-H::(()IJ!#**-
 KT" 5..t45T" 6..u56S.)!.. M
3
+2273
3KLM S*%jd.C),););)= ?%	: 9922:>? /D%r   )N)r&   N)r&   r   )r   r   r   r   r   intr%   r+   r   r   r1   r/   r   r   rF   rL   rN   rT   rV   rJ   rI   staticmethodr   rd   rf   r   r   r   r   r      s    
3Xc] 
31     
	 .$'T$Z 'R
$Xc] $<c <4!3 !(c (6>C >D >: +S +T,5G + +" ?r   r   __main__)r   r   c                   N    e Zd ZU dZ edd      Zeed<    edd      Ze	ed<   y)	NestedSchemazA nested schema for testing.zA nested fielddescriptionnested_fieldzA nested integer
nested_intN)
r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   .  s)    )!#3CDcD1CD
CDr   r   c                       e Zd ZU dZ edd      Zeed<    edd      Ze	ed<    edd      Z
ee   ed	<    edd
      Zeed<   y)ComplexInputSchemazComplex Input Schema.zA text fieldr   
text_fieldzA number fieldnumber_fieldzA list of strings
list_fieldzA nested schemar   N)r   r   r   r   r   r   r   r   r   floatr   TypeListr   r   r   r   r   r   r   4  sP    "@
C@#C5EFeF$)#;N$O
HSMO%*3<M%NlNr   r   c                   v    e Zd ZU dZ edd      Zeed<    edd      Ze	ed<    edd      Z
eeef   ed	<   y
)ComplexOutputSchemazComplex Output Schema.zA response textr   response_textzA calculated valuecalculated_valuezA dictionary of nested schemas	data_dictN)r   r   r   r   r   r   r   r   r   r   r   TypeDictr   r   r   r   r   r   <  sF    #"34EFsF %c7K L#L16sHh1i	8C-.ir   r   c                   h    e Zd ZU dZ edd      Zeed<    edd      Ze	e
j                     ed<   y)	MultimodalSchemaz%Schema for testing multimodal content.zThe instruction textr   instruction_textzThe images to analyzeimagesN)r   r   r   r   r   r   r   r   r   r   
instructorr
   r   r   r   r   r   D  s5    3 %c7M N#N).s@W)XZ%%&Xr   r   
   rH   userzHello, this is a complex inputgn!	@)item1item2item3zNested input*   )r   r   )r   r   r   r   	assistantzThis is a complex responsed   zNested output 1zNested output 2   )key1key2)r   r   r   test_imagesztest.jpgzPlease analyze this image)r   r   zDumped data:z
Loaded history details:z	
Message rq   :zRole: z	Turn ID: zContent type: zContent:z  z: z
Final verification:zMax messages: zCurrent turn ID: zLast message content:rP   );r[   r(   enumr   pathlibr   typingr   r   r   r   instructor.multimodalr	   r
   r   pydanticr   r   !atomic_agents.base.base_io_schemar   r=   r   r   r   r   r   r   osr   r   r   r   original_historyr1   pathjointest_image_pathexists	from_pathrJ   dumped_dataprintloaded_historyrI   	enumerater"   ir0   r   r   typer   
model_dumpr9   rB   r   r   rN   last_messager   r   r   <module>r      s       - - 3 3 % :  %eS1 "i "F? F?R z9E| EO\ Ojl jY< Y #3   7 2%>bQ		
   6 $2CPRS$2CPRS	

 ggll=*=O	ww~~o&$$!<jFVFVF`F`apFqEr	
 #'')K	.	+ !]N$ 

%& 6 67 )
7
1q5'#$w||n%&	'//*+,tGOO4==>?@j#OO668>>@ 	)LE5BugRw'(	)) 

!"	N>667
89	n@@BC
DE	
!"!))"-L	,


)
)
+,E r   