§
    ‰eîiA'  ã                   ó@  — d Z ddlZddlmZmZmZmZ h d£Z G d„ d¦  «        Z	 	 	 d&deeee	ef                           d	e
d
ee         de	fd„Zde
fd„Zdddddddddœdddœdg d¢ddœdœg d¢dœdœddddœd œg dœd!œZdd"lmZmZ  ej        dded#„ ed$¬%¦  «         dS )'a4  
Todo Tool Module - Planning & Task Management

Provides an in-memory task list the agent uses to decompose complex tasks,
track progress, and maintain focus across long conversations. The state
lives on the AIAgent instance (one per session) and is re-injected into
the conversation after context compression events.

Design:
- Single `todo` tool: provide `todos` param to write, omit to read
- Every call returns the full current list
- No system prompt mutation, no tool response modification
- Behavioral guidance lives entirely in the tool schema description
é    N)ÚDictÚAnyÚListÚOptional>   ÚpendingÚ	cancelledÚ	completedÚin_progressc            
       óJ  — e Zd ZdZd„ Zddeeeef                  de	deeeef                  fd„Z
deeeef                  fd„Zde	fd	„Zdee         fd
„Zedeeef         deeef         fd„¦   «         Zedeeeef                  deeeef                  fd„¦   «         ZdS )Ú	TodoStorea"  
    In-memory todo list. One instance per AIAgent (one per session).

    Items are ordered -- list position is priority. Each item has:
      - id: unique string identifier (agent-chosen)
      - content: task description
      - status: pending | in_progress | completed | cancelled
    c                 ó   — g | _         d S )N©Ú_items©Úselfs    ú1/home/div/.hermes/hermes-agent/tools/todo_tool.pyÚ__init__zTodoStore.__init__#   s   € Ø,.ˆŒˆˆó    FÚtodosÚmergeÚreturnc                 óÜ  ‡ — |s(ˆ fd„‰                       |¦  «        D ¦   «         ‰ _        �n®d„ ‰ j        D ¦   «         }‰                       |¦  «        D �]}t          |                     dd¦  «        ¦  «                             ¦   «         }|sŒ;||v r–d|v r8|d         r0t          |d         ¦  «                             ¦   «         ||         d<   d|v rU|d         rMt          |d         ¦  «                             ¦   «                              ¦   «         }|t          v r|||         d<   ŒÕ‰                      |¦  «        }|||d         <   ‰ j                             |¦  «         �Œt          ¦   «         }g }	‰ j        D ]X}
|                     |
d         |
¦  «        }|d         |vr0|	                     |¦  «         | 
                    |d         ¦  «         ŒY|	‰ _        ‰                      ¦   «         S )a  
        Write todos. Returns the full current list after writing.

        Args:
            todos: list of {id, content, status} dicts
            merge: if False, replace the entire list. If True, update
                   existing items by id and append new ones.
        c                 ó:   •— g | ]}‰                      |¦  «        ‘ŒS © )Ú	_validate)Ú.0Útr   s     €r   ú
<listcomp>z#TodoStore.write.<locals>.<listcomp>1   s%   ø€ ÐPÐPÐP°˜4Ÿ>š>¨!Ñ,Ô,ÐPÐPÐPr   c                 ó    — i | ]}|d          |“ŒS )Úidr   ©r   Úitems     r   ú
<dictcomp>z#TodoStore.write.<locals>.<dictcomp>4   s   € ÐAÐAÐA¨T˜˜Tœ
 DÐAÐAÐAr   r    Ú ÚcontentÚstatus)Ú_dedupe_by_idr   ÚstrÚgetÚstripÚlowerÚVALID_STATUSESr   ÚappendÚsetÚaddÚread)r   r   r   Úexistingr   Úitem_idr&   Ú	validatedÚseenÚrebuiltr"   Úcurrents   `           r   ÚwritezTodoStore.write&   sò  ø€ ð ð  	"àPÐPÐPÐP°d×6HÒ6HÈÑ6OÔ6OÐPÑPÔPˆDŒK‰Kð BÐA°T´[ÐAÑAÔAˆHØ×'Ò'¨Ñ.Ô.ð 2ñ 2�Ý˜aŸeše D¨"™oœoÑ.Ô.×4Ò4Ñ6Ô6�Øð Øà˜hÐ&Ð&à  A�~�~¨!¨I¬,�~Ý7:¸1¸Y¼<Ñ7HÔ7H×7NÒ7NÑ7PÔ7P˜ Ô)¨)Ñ4Ø 1�}�}¨¨8¬�}Ý!$ Q x¤[Ñ!1Ô!1×!7Ò!7Ñ!9Ô!9×!?Ò!?Ñ!AÔ!A˜Ø!¥^Ð3Ð3Ø:@˜H WÔ-¨hÑ7øð !%§¢¨qÑ 1Ô 1�IØ09�H˜Y tœ_Ñ-Ø”K×&Ò& yÑ1Ô1Ð1Ñ1å‘5”5ˆDØˆGØœð ,ð ,�Ø"Ÿ,š, t¨D¤z°4Ñ8Ô8�Ø˜4”=¨Ð,Ð,Ø—N’N 7Ñ+Ô+Ð+Ø—H’H˜W Tœ]Ñ+Ô+Ð+øØ!ˆDŒKØ�yŠy‰{Œ{Ðr   c                 ó$   — d„ | j         D ¦   «         S )z"Return a copy of the current list.c                 ó6   — g | ]}|                      ¦   «         ‘ŒS r   )Úcopyr!   s     r   r   z"TodoStore.read.<locals>.<listcomp>T   s    € Ð4Ð4Ð4 �—	’	‘”Ð4Ð4Ð4r   r   r   s    r   r0   zTodoStore.readR   s   € à4Ð4¨¬Ð4Ñ4Ô4Ð4r   c                 ó*   — t          | j        ¦  «        S )z)Check if there are any items in the list.)Úboolr   r   s    r   Ú	has_itemszTodoStore.has_itemsV   s   € å�D”KÑ Ô Ð r   c                 ó&  — | j         sdS dddddœ}d„ | j         D ¦   «         }|sdS dg}|D ]R}|                     |d	         d
¦  «        }|                     d|› d|d         › d|d         › d|d	         › d�	¦  «         ŒSd                     |¦  «        S )zÂ
        Render the todo list for post-compression injection.

        Returns a human-readable string to append to the compressed
        message history, or None if the list is empty.
        Nz[x]z[>]z[ ]z[~])r	   r
   r   r   c                 ó&   — g | ]}|d          dv ¯|‘ŒS )r&   )r   r
   r   r!   s     r   r   z2TodoStore.format_for_injection.<locals>.<listcomp>n   s2   € ð 
ð 
ð 
ØØ�HŒ~Ð!;Ð;Ð;ð Ø;Ð;Ð;r   z@[Your active task list was preserved across context compression]r&   z[?]z- Ú r    z. r%   z (ú)Ú
)r   r)   r-   Újoin)r   ÚmarkersÚactive_itemsÚlinesr"   Úmarkers         r   Úformat_for_injectionzTodoStore.format_for_injectionZ   sã   € ð Œ{ð 	Ø�4ð Ø ØØð	
ð 
ˆð
ð 
Ø!œ[ð
ñ 
ô 
ˆð ð 	Ø�4àSÐTˆØ ð 	[ð 	[ˆDØ—[’[  h¤°Ñ7Ô7ˆFØ�LŠLÐY˜fÐYÐY t¨D¤zÐYÐY°T¸)´_ÐYÐYÈÈXÌÐYÐYÐYÑZÔZÐZÐZà�yŠy˜ÑÔÐr   r"   c                 ó–  — t          |                      dd¦  «        ¦  «                             ¦   «         }|sd}t          |                      dd¦  «        ¦  «                             ¦   «         }|sd}t          |                      dd¦  «        ¦  «                             ¦   «                              ¦   «         }|t          vrd}|||dœS )	z¯
        Validate and normalize a todo item.

        Ensures required fields exist and status is valid.
        Returns a clean dict with only {id, content, status}.
        r    r$   ú?r%   z(no description)r&   r   ©r    r%   r&   )r(   r)   r*   r+   r,   )r"   r2   r%   r&   s       r   r   zTodoStore._validate|   s¿   € õ �d—h’h˜t RÑ(Ô(Ñ)Ô)×/Ò/Ñ1Ô1ˆØð 	ØˆGå�d—h’h˜y¨"Ñ-Ô-Ñ.Ô.×4Ò4Ñ6Ô6ˆØð 	)Ø(ˆGå�T—X’X˜h¨	Ñ2Ô2Ñ3Ô3×9Ò9Ñ;Ô;×AÒAÑCÔCˆØ�Ð'Ð'ØˆFà¨'¸VÐDÐDÐDr   c                 ó  ‡ — i }t          ‰ ¦  «        D ]A\  }}t          |                     dd¦  «        ¦  «                             ¦   «         pd}|||<   ŒBˆ fd„t	          |                     ¦   «         ¦  «        D ¦   «         S )zDCollapse duplicate ids, keeping the last occurrence in its position.r    r$   rJ   c                 ó    •— g | ]
}‰|         ‘ŒS r   r   )r   Úir   s     €r   r   z+TodoStore._dedupe_by_id.<locals>.<listcomp>™   s   ø€ Ð>Ð>Ð>˜Q��a”Ð>Ð>Ð>r   )Ú	enumerater(   r)   r*   ÚsortedÚvalues)r   Ú
last_indexrN   r"   r2   s   `    r   r'   zTodoStore._dedupe_by_id’   sŒ   ø€ ð &(ˆ
Ý  Ñ'Ô'ð 	$ð 	$‰GˆAˆtÝ˜$Ÿ(š( 4¨Ñ,Ô,Ñ-Ô-×3Ò3Ñ5Ô5Ð<¸ˆGØ"#ˆJ�wÑÐØ>Ð>Ð>Ð>¥&¨×):Ò):Ñ)<Ô)<Ñ"=Ô"=Ð>Ñ>Ô>Ð>r   N)F)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r(   r   r<   r7   r0   r=   r   rH   Ústaticmethodr   r'   r   r   r   r   r      sh  € € € € € ðð ð/ð /ð /ð*ð *˜4  S¨# X¤Ô/ð *¸ð *ÈÈdÐSVÐX[ÐS[ÌnÔI]ð *ð *ð *ð *ðX5�d˜4  S œ>Ô*ð 5ð 5ð 5ð 5ð!˜4ð !ð !ð !ð !ð   h¨s¤mð   ð   ð   ð   ðD ðE˜˜S #˜Xœð E¨4°°S°¬>ð Eð Eð Eñ „\ðEð* ð?˜T $ s¨C x¤.Ô1ð ?°d¸4ÀÀSÀ¼>Ô6Jð ?ð ?ð ?ñ „\ð?ð ?ð ?r   r   Fr   r   Ústorer   c           	      óž  — |€t          d¦  «        S | �|                     | |¦  «        }n|                     ¦   «         }t          d„ |D ¦   «         ¦  «        }t          d„ |D ¦   «         ¦  «        }t          d„ |D ¦   «         ¦  «        }t          d„ |D ¦   «         ¦  «        }t	          j        |t          |¦  «        ||||dœdœd	¬
¦  «        S )a„  
    Single entry point for the todo tool. Reads or writes depending on params.

    Args:
        todos: if provided, write these items. If None, read current list.
        merge: if True, update by id. If False (default), replace entire list.
        store: the TodoStore instance from the AIAgent.

    Returns:
        JSON string with the full current list and summary metadata.
    NzTodoStore not initializedc              3   ó2   K  — | ]}|d          dk    ¯dV — ŒdS )r&   r   é   Nr   ©r   rN   s     r   ú	<genexpr>ztodo_tool.<locals>.<genexpr>µ   s0   è è € Ð?Ð?˜ a¨¤k°YÒ&>Ð&>�!Ð&>Ð&>Ð&>Ð&>Ð?Ð?r   c              3   ó2   K  — | ]}|d          dk    ¯dV — ŒdS )r&   r
   r[   Nr   r\   s     r   r]   ztodo_tool.<locals>.<genexpr>¶   s0   è è € ÐGÐG˜A¨!¨H¬+¸Ò*FÐ*F�aÐ*FÐ*FÐ*FÐ*FÐGÐGr   c              3   ó2   K  — | ]}|d          dk    ¯dV — ŒdS )r&   r	   r[   Nr   r\   s     r   r]   ztodo_tool.<locals>.<genexpr>·   ó0   è è € ÐCÐC˜!¨¨(¬°{Ò(BÐ(B�AÐ(BÐ(BÐ(BÐ(BÐCÐCr   c              3   ó2   K  — | ]}|d          dk    ¯dV — ŒdS )r&   r   r[   Nr   r\   s     r   r]   ztodo_tool.<locals>.<genexpr>¸   r`   r   )Útotalr   r
   r	   r   )r   ÚsummaryF)Úensure_ascii)Ú
tool_errorr7   r0   ÚsumÚjsonÚdumpsÚlen)r   r   rX   Úitemsr   r
   r	   r   s           r   Ú	todo_toolrk   œ   sü   € ð  €}ÝÐ5Ñ6Ô6Ð6àÐØ—’˜E 5Ñ)Ô)ˆˆà—
’
‘”ˆõ Ð?Ð?˜UÐ?Ñ?Ô?Ñ?Ô?€GÝÐGÐG ÐGÑGÔGÑGÔG€KÝÐCÐC˜uÐCÑCÔCÑCÔC€IÝÐCÐC˜uÐCÑCÔCÑCÔC€IåŒ:Øå˜‘Z”ZØØ&Ø"Ø"ð
ð 
ð	ð 	ð ð	ñ 	ô 	ð 	r   c                  ó   — dS )z;Todo tool has no external requirements -- always available.Tr   r   r   r   Úcheck_todo_requirementsrm   Æ   s   € àˆ4r   Útodoa‡  Manage your task list for the current session. Use for complex tasks with 3+ steps or when the user provides multiple tasks. Call with no parameters to read the current list.

Writing:
- Provide 'todos' array to create/update items
- merge=false (default): replace the entire list with a fresh plan
- merge=true: update existing items by id, add any new ones

Each item: {id: string, content: string, status: pending|in_progress|completed|cancelled}
List order is priority. Only ONE item in_progress at a time.
Mark items completed immediately when done. If something fails, cancel it and add a revised item.

Always returns the full current list.ÚobjectÚarrayz/Task items to write. Omit to read current list.ÚstringzUnique item identifier)ÚtypeÚdescriptionzTask description)r   r
   r	   r   zCurrent status)rr   Úenumrs   rK   )rr   Ú
propertiesÚrequired)rr   rs   rj   ÚbooleanzZtrue: update existing items by id, add new ones. false (default): replace the entire list.)rr   rs   Údefault)r   r   )Únamers   Ú
parameters)Úregistryre   c                 óš   — t          |                      d¦  «        |                      dd¦  «        |                     d¦  «        ¬¦  «        S )Nr   r   FrX   )r   r   rX   )rk   r)   )ÚargsÚkws     r   ú<lambda>r     sC   € �yØ�hŠh�wÑÔ t§x¢x°¸Ñ'?Ô'?ÀrÇvÂvÈgÁÄð Xñ  Xô  X€ r   u   ðŸ“‹)ry   ÚtoolsetÚschemaÚhandlerÚcheck_fnÚemoji)NFN)rV   rg   Útypingr   r   r   r   r,   r   r(   r<   rk   rm   ÚTODO_SCHEMAÚtools.registryr{   re   Úregisterr   r   r   ú<module>r‰      s  ððð ð €€€Ø ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,ð FÐEÐE€ð@?ð @?ð @?ð @?ð @?ñ @?ô @?ð @?ðH -1ØØ!%ð'ð 'Ø�D˜˜c 3˜hœÔ(Ô)ð'àð'ð �IÔð'ð 	ð	'ð 'ð 'ð 'ðT ð ð ð ð ð ð	0ð ð  ØPà$ð %-Ø+Cðð ð
 %-Ø+=ð$ð $ð
 %-Ø$XÐ$XÐ$XØ+;ð#ð #ð#ð #ð !<Ð ;Ð ;ð#ð ðð ð0 "ð@ð !ðð ð1 
ð  
ðB ðG$ð $ð#6ð 6€ðt 0Ð /Ð /Ð /Ð /Ð /Ð /Ð /à €Ô Ø	ØØðXð Xà$Ø
ðñ ô ð ð ð r   