§
    øžyj“2  ã                   óT  — d Z ddlZddlmZmZmZmZ h d£ZdZdZ	dZ
dZ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_progressi   é   i Ð u   â€¦ [truncated]z@[Your active task list was preserved across context compression]c            
       ó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d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    ú5/home/ragecks/.hermes/hermes-agent/tools/todo_tool.pyÚ__init__zTodoStore.__init__8   s   € Ø,.ˆŒˆˆó    FÚtodosÚmergeÚreturnc                 ón  ‡ — |s(ˆ fd„‰                       |¦  «        D ¦   «         ‰ _        �nÁd„ ‰ j        D ¦   «         }‰                       |¦  «        D �]"}t          |                     dd¦  «        ¦  «                             ¦   «         }|sŒ;||v r©d|v rK|d         rC‰                      t          |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|	‰ _        t          ‰ j        ¦  «        t          k    r‰ j        dt          …         ‰ _        ‰                      ¦   «         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>F   s%   ø€ ÐPÐPÐP°˜4Ÿ>š>¨!Ñ,Ô,ÐPÐPÐPr   c                 ó    — i | ]}|d          |“ŒS )Úidr   ©r   Úitems     r   ú
<dictcomp>z#TodoStore.write.<locals>.<dictcomp>I   s   € ÐAÐAÐA¨T˜˜Tœ
 DÐAÐAÐAr   r!   Ú ÚcontentÚstatusN)Ú_dedupe_by_idr   ÚstrÚgetÚstripÚ_cap_contentÚlowerÚVALID_STATUSESr   ÚappendÚsetÚaddÚlenÚMAX_TODO_ITEMSÚ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;×7HÒ7HÍÈQÈyÌ\ÑIZÔIZ×I`ÒI`ÑIbÔIbÑ7cÔ7c˜ Ô)¨)Ñ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õ ˆtŒ{ÑÔ�nÒ,Ð,Øœ+ o¥~ oÔ6ˆ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>n   s    € Ð4Ð4Ð4 �—	’	‘”Ð4Ð4Ð4r   r   r   s    r   r4   zTodoStore.readl   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_itemsp   s   € å�D”KÑ Ô Ð r   c                 ó0  — | j         sdS dddddœ}d„ | j         D ¦   «         }|sdS t          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>ˆ   s2   € ð 
ð 
ð 
ØØ�HŒ~Ð!;Ð;Ð;ð Ø;Ð;Ð;r   r'   z[?]z- Ú r!   z. r&   z (ú)Ú
)r   ÚTODO_INJECTION_HEADERr*   r/   Újoin)r   ÚmarkersÚactive_itemsÚlinesr#   Úmarkers         r   Úformat_for_injectionzTodoStore.format_for_injectiont   sã   € ð Œ{ð 	Ø�4ð Ø ØØð	
ð 
ˆð
ð 
Ø!œ[ð
ñ 
ô 
ˆð ð 	Ø�4å&Ð'ˆØ ð 	[ð 	[ˆ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          | ¦  «        t          k    r.t          t          t          ¦  «        z
  }| d|…         t          z   S | S )u$  Truncate oversized todo content to MAX_TODO_CONTENT_CHARS.

        A single huge item would otherwise inflate the post-compression
        re-injection block (format_for_injection) without bound. Keep the
        head â€” the actionable part of a task description â€” plus a marker.
        N)r2   ÚMAX_TODO_CONTENT_CHARSÚ_TRUNCATION_MARKER)r&   Úkeeps     r   r,   zTodoStore._cap_content–   sB   € õ ˆw‰<Œ<Õ0Ò0Ð0Ý)­CÕ0BÑ,CÔ,CÑCˆDØ˜5˜D˜5”>Õ$6Ñ6Ð6Øˆr   r#   c                 ó  — t          | t          ¦  «        sddddœS t          |                      dd¦  «        ¦  «                             ¦   «         }|sd}t          |                      dd¦  «        ¦  «                             ¦   «         }|sd}nt
                               |¦  «        }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}.
        ú?z(invalid item)r   ©r!   r&   r'   r!   r%   r&   z(no description)r'   )	Ú
isinstanceÚdictr)   r*   r+   r   r,   r-   r.   )r#   r6   r&   r'   s       r   r   zTodoStore._validate£   sø   € õ ˜$¥Ñ%Ô%ð 	QØÐ*:ÀiÐPÐPÐPå�d—h’h˜t RÑ(Ô(Ñ)Ô)×/Ò/Ñ1Ô1ˆØð 	ØˆGå�d—h’h˜y¨"Ñ-Ô-Ñ.Ô.×4Ò4Ñ6Ô6ˆØð 	6Ø(ˆGˆGå×,Ò,¨WÑ5Ô5ˆGå�T—X’X˜h¨	Ñ2Ô2Ñ3Ô3×9Ò9Ñ;Ô;×AÒAÑCÔCˆØ�Ð'Ð'ØˆFà¨'¸VÐDÐDÐDr   c                 ó@  ‡ — i }t          ‰ ¦  «        D ]_\  }}t          |t          ¦  «        s	||d|› �<   Œ#t          |                     dd¦  «        ¦  «                             ¦   «         pd}|||<   Œ`ˆ fd„t          |                     ¦   «         ¦  «        D ¦   «         S )zDCollapse duplicate ids, keeping the last occurrence in its position.Ú
__invalid_r!   r%   rS   c                 ó    •— g | ]
}‰|         ‘ŒS r   r   )r   Úir   s     €r   r   z+TodoStore._dedupe_by_id.<locals>.<listcomp>É   s   ø€ Ð>Ð>Ð>˜Q��a”Ð>Ð>Ð>r   )Ú	enumeraterU   rV   r)   r*   r+   ÚsortedÚvalues)r   Ú
last_indexrZ   r#   r6   s   `    r   r(   zTodoStore._dedupe_by_id¾   s´   ø€ ð &(ˆ
Ý  Ñ'Ô'ð 	$ð 	$‰GˆAˆtÝ˜d¥DÑ)Ô)ð à/0�
Ð+¨Ð+Ð+Ñ,ØÝ˜$Ÿ(š( 4¨Ñ,Ô,Ñ-Ô-×3Ò3Ñ5Ô5Ð<¸ˆGØ"#ˆJ�wÑÐØ>Ð>Ð>Ð>¥&¨×):Ò):Ñ)<Ô)<Ñ"=Ô"=Ð>Ñ>Ô>Ð>r   N)F)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r)   r   r@   r;   r4   rA   r   rM   Ústaticmethodr,   r   r(   r   r   r   r   r   .   s–  € € € € € ðð ð/ð /ð /ð/ð /˜4  S¨# X¤Ô/ð /¸ð /ÈÈdÐSVÐX[ÐS[ÌnÔI]ð /ð /ð /ð /ðb5�d˜4  S œ>Ô*ð 5ð 5ð 5ð 5ð!˜4ð !ð !ð !ð !ð   h¨s¤mð   ð   ð   ð   ðD ð
˜cð 
 cð 
ð 
ð 
ñ „\ð
ð ðE˜˜S #˜Xœð E¨4°°S°¬>ð Eð Eð Eñ „\ðEð4 ð
?˜T $ s¨C x¤.Ô1ð 
?°d¸4ÀÀSÀ¼>Ô6Jð 
?ð 
?ð 
?ñ „\ð
?ð 
?ð 
?r   r   Fr   r   Ústorer   c           	      ó¼  — |€t          d¦  «        S | �¦t          | t          ¦  «        rA	 t          j        | ¦  «        } n+# t          j        t          f$ r t          d¦  «        cY S w xY wt          | t          ¦  «        s$t          dt          | ¦  «        j	        › �¦  «        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 initializedz7todos must be a list of objects, got unparseable stringztodos must be a list, got c              3   ó2   K  — | ]}|d          dk    ¯dV — ŒdS )r'   r   é   Nr   ©r   rZ   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
   rg   Nr   rh   s     r   ri   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	   rg   Nr   rh   s     r   ri   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   rg   Nr   rh   s     r   ri   ztodo_tool.<locals>.<genexpr>ò   rl   r   )Útotalr   r
   r	   r   )r   ÚsummaryF)Úensure_ascii)Ú
tool_errorrU   r)   ÚjsonÚloadsÚJSONDecodeErrorÚ	TypeErrorÚlistÚtyper_   r;   r4   ÚsumÚdumpsr2   )r   r   rd   Úitemsr   r
   r	   r   s           r   Ú	todo_toolr{   Ì   sœ  € ð  €}ÝÐ5Ñ6Ô6Ð6àÐå�e�SÑ!Ô!ð 	]ð]Ýœ
 5Ñ)Ô)��øÝÔ(­)Ð4ð ]ð ]ð ]Ý!Ð"[Ñ\Ô\Ð\Ð\Ð\ð]øøøå˜%¥Ñ&Ô&ð 	ÝØC­T°%©[¬[Ô-AÐCÐCñô ð ð —’˜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ØØ&Ø"Ø"ð
ð 
ð	ð 	ð ð	ñ 	ô 	ð 	s   ª? ¿%A'Á&A'c                  ó   — dS )z;Todo tool has no external requirements -- always available.Tr   r   r   r   Úcheck_todo_requirementsr}      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)rw   ÚdescriptionzTask description)r   r
   r	   r   zCurrent status)rw   Úenumr‚   rT   )rw   Ú
propertiesÚrequired)rw   r‚   rz   ÚbooleanzZtrue: update existing items by id, add new ones. false (default): replace the entire list.)rw   r‚   Údefault)r   r   )Únamer‚   Ú
parameters)Úregistryrq   c                 óš   — t          |                      d¦  «        |                      dd¦  «        |                     d¦  «        ¬¦  «        S )Nr   r   Frd   )r   r   rd   )r{   r*   )ÚargsÚkws     r   ú<lambda>rŽ   K  sC   € �yØ�hŠh�wÑÔ t§x¢x°¸Ñ'?Ô'?ÀrÇvÂvÈgÁÄð Xñ  Xô  X€ r   u   ðŸ“‹)rˆ   ÚtoolsetÚschemaÚhandlerÚcheck_fnÚemoji)NFN)rb   rr   Útypingr   r   r   r   r.   rO   r3   ÚMAX_TODO_RESULT_CHARSrP   rG   r   r)   r@   r{   r}   ÚTODO_SCHEMAÚtools.registryrŠ   rq   Úregisterr   r   r   ú<module>r™      s=  ððð ð €€€Ø ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,ð FÐEÐE€ð Ð Ø€ð
  Ð Ø&Ð ð Gð ð
[?ð [?ð [?ð [?ð [?ñ [?ô [?ð [?ð~ -1ØØ!%ð1ð 1Ø�D˜˜c 3˜hœÔ(Ô)ð1àð1ð �IÔð1ð 	ð	1ð 1ð 1ð 1ðh ð ð ð ð ð ð	0ð ð  ØPà$ð %-Ø+Cðð ð
 %-Ø+=ð$ð $ð
 %-Ø$XÐ$XÐ$XØ+;ð#ð #ð#ð #ð !<Ð ;Ð ;ð#ð ðð ð0 "ð@ð !ðð ð1 
ð  
ðB ðG$ð $ð#6ð 6€ðt 0Ð /Ð /Ð /Ð /Ð /Ð /Ð /à €Ô Ø	ØØðXð Xà$Ø
ðñ ô ð ð ð r   