/ examples / skills / custom_skill_example.py
custom_skill_example.py
  1  """
  2  Custom Skill Creation Example
  3  
  4  This example demonstrates how to programmatically create and validate
  5  custom Agent Skills using PraisonAI Agents.
  6  """
  7  
  8  import tempfile
  9  from pathlib import Path
 10  
 11  from praisonaiagents.skills import (
 12      SkillManager,
 13      SkillLoader,
 14      validate,
 15      read_properties,
 16  )
 17  
 18  
 19  def create_custom_skill(
 20      name: str,
 21      description: str,
 22      instructions: str,
 23      base_dir: str = None
 24  ) -> Path:
 25      """Create a custom skill programmatically.
 26      
 27      Args:
 28          name: Skill name (kebab-case)
 29          description: What the skill does
 30          instructions: Markdown instructions for the skill
 31          base_dir: Directory to create skill in (default: temp dir)
 32          
 33      Returns:
 34          Path to the created skill directory
 35      """
 36      if base_dir is None:
 37          base_dir = tempfile.mkdtemp()
 38      
 39      skill_dir = Path(base_dir) / name
 40      skill_dir.mkdir(parents=True, exist_ok=True)
 41      
 42      # Create SKILL.md
 43      skill_md_content = f"""---
 44  name: {name}
 45  description: {description}
 46  license: Apache-2.0
 47  metadata:
 48    author: custom
 49    version: "1.0"
 50  ---
 51  
 52  {instructions}
 53  """
 54      (skill_dir / "SKILL.md").write_text(skill_md_content)
 55      
 56      # Create optional directories
 57      (skill_dir / "scripts").mkdir(exist_ok=True)
 58      (skill_dir / "references").mkdir(exist_ok=True)
 59      (skill_dir / "assets").mkdir(exist_ok=True)
 60      
 61      return skill_dir
 62  
 63  
 64  def main():
 65      print("=" * 60)
 66      print("Custom Skill Creation Example")
 67      print("=" * 60)
 68      
 69      # Create a custom skill
 70      print("\n1. Creating a custom skill...")
 71      
 72      skill_path = create_custom_skill(
 73          name="code-review",
 74          description="Review code for best practices, bugs, and improvements. Use when asked to review or analyze code quality.",
 75          instructions="""
 76  # Code Review Skill
 77  
 78  ## Overview
 79  This skill enables thorough code review with focus on:
 80  - Code quality and readability
 81  - Potential bugs and edge cases
 82  - Performance considerations
 83  - Security vulnerabilities
 84  - Best practices adherence
 85  
 86  ## Instructions
 87  
 88  When reviewing code:
 89  
 90  1. **Read the code carefully** - Understand the purpose and flow
 91  2. **Check for bugs** - Look for null checks, edge cases, error handling
 92  3. **Evaluate readability** - Variable names, comments, structure
 93  4. **Consider performance** - Time/space complexity, unnecessary operations
 94  5. **Security review** - Input validation, injection risks, data exposure
 95  6. **Suggest improvements** - Provide actionable recommendations
 96  
 97  ## Output Format
 98  
 99  Structure your review as:
100  - Summary: Brief overview of the code
101  - Issues: List of problems found (severity: high/medium/low)
102  - Suggestions: Recommended improvements
103  - Positive aspects: What's done well
104  """
105      )
106      
107      print(f"   Created skill at: {skill_path}")
108      
109      # Validate the skill
110      print("\n2. Validating the skill...")
111      errors = validate(skill_path)
112      
113      if errors:
114          print("   Validation errors:")
115          for error in errors:
116              print(f"   - {error}")
117      else:
118          print("   ✓ Skill is valid!")
119      
120      # Load and inspect the skill
121      print("\n3. Loading skill properties...")
122      props = read_properties(skill_path)
123      print(f"   Name: {props.name}")
124      print(f"   Description: {props.description[:60]}...")
125      print(f"   License: {props.license}")
126      
127      # Use with SkillLoader for progressive loading
128      print("\n4. Using SkillLoader for progressive disclosure...")
129      loader = SkillLoader()
130      
131      # Level 1: Load metadata only
132      skill = loader.load_metadata(str(skill_path))
133      print(f"   Level 1 - Metadata loaded: {skill.properties.name}")
134      print(f"   Instructions loaded: {skill.is_activated}")
135      
136      # Level 2: Activate (load instructions)
137      loader.activate(skill)
138      print(f"   Level 2 - Activated: {skill.is_activated}")
139      print(f"   Instructions preview: {skill.instructions[:100]}...")
140      
141      # Use with SkillManager
142      print("\n5. Using with SkillManager...")
143      manager = SkillManager()
144      manager.add_skill(str(skill_path))
145      
146      # Generate prompt XML
147      prompt = manager.to_prompt()
148      print("   Generated prompt XML:")
149      print(prompt)
150      
151      # Clean up
152      print("\n6. Cleanup...")
153      import shutil
154      shutil.rmtree(skill_path.parent)
155      print("   Temporary files removed.")
156      
157      print("\n" + "=" * 60)
158      print("Example complete!")
159      print("=" * 60)
160  
161  
162  if __name__ == "__main__":
163      main()