
    i.              
          d Z ddlmZ ddl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ZddlmZ  ee      j%                         j&                  d   Zed	z  d
z  j%                         ZdZ G d de      Z ed       G d d             Zdeez  defdZdededeeef   fdZdedededee   fdZdedededeeef   fdZ G d d      Z y)z+Agent Skills discovery and loading helpers.    )	dataclass)escape)Path)CallableDictIterableListMappingSequenceN)ToolSpec   z.agentsskillsi   c                       e Zd ZdZy)SkillValidationErrorz:Raised when a skill directory or SKILL.md file is invalid.N)__name__
__module____qualname____doc__     N/Users/bowang/.openclaw/workspace/ChatDev/runtime/node/agent/skills/manager.pyr   r      s    Dr   r   T)frozenc                   r    e Zd ZU eed<   eed<   eed<   eed<   eeef   ed<   eedf   ed<   eeef   ed<   y	)
SkillMetadatanamedescription	skill_dir
skill_filefrontmatter.allowed_toolscompatibilityN)	r   r   r   str__annotations__r   r
   objecttupler   r   r   r   r      sD    
IOf%%c?"3;''r   r   r   returnc                    t        |       j                         }|j                  d      }t        ||      }|j	                  d      }|j	                  d      }t        |t              r|j                         st        | d      t        |t              r|j                         st        | d      |j                         }|j                         }|j                  j                  |k7  r(t        | d| d|j                  j                   d	      t        |j	                  d
      |d
      }t        |j	                  d      |d      }	t        |||j                  |t        |      t        |      t        |	            S )Nutf-8encodingr   r   z0: skill frontmatter must define a non-empty namez7: skill frontmatter must define a non-empty descriptionz: skill name 'z' must match directory name ''zallowed-toolsr!   )r   r   r   r   r   r    r!   )r   resolve	read_text_parse_frontmatterget
isinstancer"   stripr   parentr   _parse_optional_str_list_parse_optional_mappingr   dictr%   )
r   pathtextr   raw_nameraw_descriptionr   r   r    r!   s
             r   parse_skill_filer:   !   s^   
##%D>>7>+D$T40Kv&H!oom4Oh$HNN,<"dV+[#\]]os+?3H3H3J"dV+b#cdd>>D!'')K{{4"fN4&(EdkkFVFVEWWXY
 	
 -[___-MtUdeM+KOOO,LdTcdM++%M*=) r   r7   r6   c                    | j                  d      st        | d      | j                         }d }t        dt	        |            D ]  }||   j                         dk(  s|} n |t        | d      dj                  |d|       }	 t        j                  |      xs i }t        |t              st        | d      |S # t        j                  $ r}t        | d|       |d }~ww xY w)Nz---z+: SKILL.md must start with YAML frontmatter   z): closing frontmatter delimiter not found
z: invalid YAML frontmatter: z%: skill frontmatter must be a mapping)
startswithr   
splitlinesrangelenr1   joinyaml	safe_load	YAMLErrorr0   r
   )r7   r6   linesend_idxidxpayloaddataexcs           r   r.   r.   B   s   ??5!"dV+V#WXXOOEGQE
#:&G $ "dV+T#UVViia()GX~~g&," dG$"dV+P#QRRK	 >> X"dV+Gu#MNTWWXs   C C-C((C-value
field_namec           	         | g S t        | t              r!| j                         D cg c]  }|s|	 c}S t        | t              st	        | d| d      g }t        |       D ]X  \  }}t        |t              r|j                         st	        | d| d| d      |j                  |j                                Z |S c c}w )N: z must be a list of strings[z] must be a non-empty string)r0   r"   splitlistr   	enumerater1   append)rL   r6   rM   itemresultrH   s         r   r3   r3   Y   s    }	%!&7$77eT""dV2j\9S#TUUFu%	T$$DJJL&$r*QseC_'`aadjjl# & M 8s
   CCc                     | i S t        | t              st        | d| d      | D ci c]  }t        |      | |    c}S c c}w )NrO   z must be a mapping)r0   r
   r   r"   )rL   r6   rM   keys       r   r4   r4   i   sT    }	eW%"dV2j\9K#LMM,12ESCHeCj E222s   Ac            	       T   e Zd ZdZ	 	 	 ddee   dz  dee   dz  deegdf   dz  ddfdZdee	   fdZ
defd	Zdefd
Zdedeeeee   z  f   fdZdededeeef   fdZdedefdZde	dz  fdZdee   fdZdee   fdZdedee	   fdZdede	fdZde	defdZdeddfdZy)AgentSkillManagerzMDiscover and read Agent Skills from the fixed project-level skills directory.Nallowavailable_tool_nameswarning_reporterr&   c                 n   t         | _        |xs g D ch c]&  }|s|j                         s|j                         ( c}| _        |xs g D ch c]&  }|s|j                         s|j                         ( c}| _        || _        d | _        i | _        i | _        d | _	        g | _
        y c c}w c c}w N)DEFAULT_SKILLS_ROOTrootr1   r[   r\   r]   _skills_by_name_skill_content_cache_activation_state_current_skill_name_discovery_warnings)selfr[   r\   r]   rU   s        r   __init__zAgentSkillManager.__init__t   s     (	05VtdjjlV
?S?YWY?Y$t?Yd^bgkgqgqgsTZZ\?Y$t! 0@D46!24/3 .0  W$ts!   B-B-B-B2B2(B2c                    | j                   i }| j                  }|j                         ry|j                         ri| j	                  |      D ]U  }| j
                  r|j                  | j
                  vr(| j                  |      s:|j                  |j                  |       W || _         t        | j                   j                               S r_   )rb   ra   existsis_dir_iter_root_skillsr[   r   _is_skill_compatible
setdefaultrR   values)rg   
discoveredra   metadatas       r   discoverzAgentSkillManager.discover   s    '35J99D{{} $ 6 6t <Hzzhmm4::&E 44X> ))(--B != $.D D((//122r   c                 4    t        | j                               S r_   )boolrr   rg   s    r   
has_skillszAgentSkillManager.has_skills   s    DMMO$$r   c                 "   | j                         }|sydg}|D ]  }|j                  ddt        |j                         ddt        |j                         ddt        t        |j                               d	g       |j                  rQ|j                  d
       |j                  D ]   }|j                  dt        |       d       " |j                  d       |j                  d        |j                  d       dj                  |      S )N z<available_skills>z	  <skill>z
    <name>z</name>z    <description>z</description>z    <location>z</location>z    <allowed_tools>z      <tool>z</tool>z    </allowed_tools>z
  </skill>z</available_skills>r=   )
rr   extendr   r   r   r"   r   r    rT   rB   )rg   r   rF   skill	tool_names        r   build_available_skills_xmlz,AgentSkillManager.build_available_skills_xml   s    %&ELL 

!3 4G<'u/@/@(A'B.Q$VC0@0@,A%B$C;O	 ""23!&!4!4ILL<y0A/B'!JK "534LL&  	*+yyr   
skill_namec                    | j                  |      }| j                  j                  |j                        }|5|j                  j                  d      }|| j                  |j                  <   d| j                  |j                  <   |j                  | _        |j                  t        |j                        |t        |j                        dS )Nr(   r)   T)r}   r6   instructionsr    )
_get_skillrc   r/   r   r   r-   rd   re   r"   rR   r    )rg   r}   rz   cacheds       r   activate_skillz AgentSkillManager.activate_skill   s    
+**..uzz:>%%///AF4:D%%ejj1-1uzz*#(:: **(()"!%"5"56	
 	
r   relative_pathc                    | j                  |      }| j                  |j                        st        d|j                   d      |j	                         }|st        d      |j
                  |z  j                         }	 |j                  |j
                         |j                         r|j                         st        d| d      |j                         j                  t        kD  rt        d| dt         d      |j                  t        |      t        |j                  |j
                              |j                  d	
      dS # t        $ r}t        d      |d }~ww xY w)NSkill 'z(' must be activated before reading fileszrelative_path is requiredz2relative_path must stay within the skill directoryzSkill file '' not foundz' exceeds the z byte limitr(   r)   )r}   r6   r   content)r   is_activatedr   
ValueErrorr1   r   r,   relative_torj   is_filestatst_sizeMAX_SKILL_FILE_BYTESr"   r-   )rg   r}   r   rz   
normalized	candidaterK   s          r   read_skill_filez!AgentSkillManager.read_skill_file   sL   
+  ,wuzzl2Z[\\"((*
899__z1::<		\!!%//2 !):):)<|J<{CDD>>##&::|J<~FZE[[fghh  **	N !6!6u!GH **G*<	
 	
  	\QRX[[	\s   E 	E(E##E(c                 J    t        | j                  j                  |            S r_   )rt   rd   r/   )rg   r}   s     r   r   zAgentSkillManager.is_activated   s    D**..z:;;r   c                 p    | j                   y | j                  }|y |j                  | j                         S r_   )re   rb   r/   )rg   r   s     r   active_skillzAgentSkillManager.active_skill   s9    ##+%%>zz$2233r   c                 L    | j                          t        | j                        S r_   )rr   rR   rf   ru   s    r   discovery_warningsz$AgentSkillManager.discovery_warnings   s    D,,--r   c           
          | j                         sg S t        dddddddidgdd	d
i      t        ddddddddddddgdd	d
i      gS )Nr   zALoad the full SKILL.md instructions for a discovered agent skill.r$   r}   stringz)Exact skill name from <available_skills>.)typer   )r   
propertiesrequiredsourceagent_skill_internal)r   r   
parametersrq   r   zTRead a text file inside an activated skill directory, such as references or scripts.z3Exact activated skill name from <available_skills>.zHPath relative to the skill directory, for example references/example.md.)r}   r   r   )rv   r   ru   s    r   build_tool_specsz"AgentSkillManager.build_tool_specs   s     I%_$$$,+V'# ".	 #$:; &r$ %-+`'
 %-+u*	# ". ? #$:;#!#
 #	
r   ra   c              #     K   t        |j                               D ]7  }|j                         s|dz  }|j                         s*	 t	        |       9 y # t
        $ r$}| j                  t        |             Y d }~cd }~ww xY ww)NzSKILL.md)sortediterdirrk   r   r:   r   _warnr"   )rg   ra   r   r   rK   s        r   rl   z#AgentSkillManager._iter_root_skills  sw     /I##%"Z/J%%'&z22 0 ( 

3s8$s0   ABAB	B A?:B?BBc                 p    | j                         D ]  }|j                  |k(  s|c S  t        d| d      )Nr   r   )rr   r   r   )rg   r}   rz   s      r   r   zAgentSkillManager._get_skill  s9    ]]_EzzZ' % 7:,k:;;r   rz   c                 L    |j                   sy j                  s6 j                  d|j                   dt	        |j                          d       yt         fd|j                   D              s6 j                  d|j                   dt	        |j                          d       yy)	NTzSkipping skill 'z ': skill declares allowed-tools z, but this agent has no bound external tools.Fc              3   :   K   | ]  }|j                   v   y wr_   )r\   ).0r{   rg   s     r   	<genexpr>z9AgentSkillManager._is_skill_compatible.<locals>.<genexpr>*  s     _K^i9 9 99K^s   z': none of its allowed-tools z are configured on this agent.)r    r\   r   r   rR   any)rg   rz   s   ` r   rm   z&AgentSkillManager._is_skill_compatible!  s    ""((JJ"5::,.N++,--Y[ _5K^K^__JJ"5::,.K++,--KM r   messagec                 v    | j                   j                  |       | j                  | j                  |       y y r_   )rf   rT   r]   )rg   r   s     r   r   zAgentSkillManager._warn2  s5      ''0  ,!!'* -r   )NNN)r   r   r   r   r   r"   r   rh   r	   r   rr   rt   rv   r|   r   r   r   r   r   r   r   r   r   r   rl   r   rm   r   r   r   r   rZ   rZ   q   sd   W '+599=	1}t#1 'smd21 #C5$;/$6	1
 
1 3$}- 3%D % C  0
 
c3c?6J1K 

# 
c 
d3PS8n 
6<s <t <4md2 4.DI .&
$x. &
Pd x/F <S <] <- D "+S +T +r   rZ   )!r   dataclassesr   htmlr   pathlibr   typingr   r   r   r	   r
   r   rC   entity.tool_specr   __file__r,   parents	REPO_ROOTr`   r   r   r   r   r"   r:   r$   r.   r3   r4   rZ   r   r   r   <module>r      s!   1 !   D D  % N""$,,Q/	 9,x7@@B ! E: E $( ( (t  BS  f1E .F $ C DQTI  36 3 33 37SVX^S^K_ 3D+ D+r   