scripts-skill-expert
""" Skill Type Expert
Specializes in understanding what makes a document a "skill" document. Skills define reusable patterns, automation capabilities, and specialized knowledge.
Key characteristics:
- Activation triggers/conditions
- Reusable patterns or procedures
- Input/output specifications
- Integration with framework
- Use case examples """
import re from typing import Dict, List from pathlib import Path import sys
sys.path.insert(0, str(Path(file).parent.parent)) from core.models import Document, AnalystVote from .base import TypeExpert, TypeAnalysis, ContentEnhancement
class SkillExpert(TypeExpert): """Expert in identifying and enhancing skill documents."""
expert_type = "skill"
strong_indicators = [
r'skill',
r'pattern',
r'when to use',
r'activation',
r'triggers?',
r'reusable',
r'template',
r'automation',
]
analyst_expectations = {
'metadata': ["type: skill in frontmatter", "component_type: skill"],
'content': ["## When to Use", "## Pattern/Template", "## Examples"],
'structural': ["Path contains /skills/", "SKILL.md filename"],
'semantic': ["Pattern description language", "Reusability focus"],
'pattern': ["Filename matches skill patterns", "Title describes capability"],
}
def analyze(
self,
document: Document,
analyst_votes: List[AnalystVote]
) -> TypeAnalysis:
"""Analyze if document is truly a skill definition."""
content = document.body or document.content
headings = self.extract_headings(content)
h2_texts = [h[1].lower() for h in headings if h[0] == 2]
evidence_for = []
evidence_against = []
# Check strong indicators
for indicator in self.strong_indicators:
if re.search(indicator, content, re.I):
evidence_for.append(f"Contains skill indicator: '{indicator}'")
# Check for skill-specific sections
if any('when to use' in h for h in h2_texts):
evidence_for.append("Has 'When to Use' section")
if any('pattern' in h or 'template' in h for h in h2_texts):
evidence_for.append("Has pattern/template section")
if any('trigger' in h or 'activation' in h for h in h2_texts):
evidence_for.append("Has trigger/activation section")
# Check for reusability language
if re.search(r'reusable|reuse|apply this|use this (?:pattern|template|skill)', content, re.I):
evidence_for.append("Contains reusability language")
# Check for input/output specs
if re.search(r'input[s]?:|output[s]?:|returns?:', content, re.I):
evidence_for.append("Has input/output specifications")
# Check for code templates
code_blocks = self.extract_code_blocks(content)
if len(code_blocks) >= 2:
evidence_for.append(f"Has {len(code_blocks)} code templates")
# Check path
path_str = str(document.path).lower()
if '/skill' in path_str:
evidence_for.append("Located in skills directory")
if 'skill.md' in path_str:
evidence_for.append("Has SKILL.md filename pattern")
# Evidence against
if any('step' in h and 'how to' in content.lower() for h in h2_texts):
evidence_against.append("Has step sections with how-to - might be guide")
if re.search(r'you are\b', content, re.I):
evidence_against.append("Has persona language - might be agent")
if any('api' in h or 'endpoint' in h for h in h2_texts):
evidence_against.append("Has API sections - might be reference")
confidence = min(0.98, len(evidence_for) * 0.14)
if evidence_against:
confidence -= len(evidence_against) * 0.1
is_skill = len(evidence_for) >= 2 and confidence > 0.5
# Missing signals
missing = []
if not any('when to use' in h for h in h2_texts):
missing.append('when_to_use')
if not any('pattern' in h or 'template' in h for h in h2_texts):
missing.append('pattern')
if not re.search(r'input|output|returns?', content, re.I):
missing.append('io_spec')
if len(code_blocks) < 1:
missing.append('examples')
disagreeing = self.identify_disagreeing_analysts(analyst_votes, 'skill')
analysts_to_sway = {
name: f"Needs skill signals (when to use, patterns, templates) to classify as skill"
for name in disagreeing
}
return TypeAnalysis(
is_this_type=is_skill,
confidence=max(0, confidence),
evidence_for=evidence_for,
evidence_against=evidence_against,
semantic_purpose=self.analyze_semantic_purpose(document),
missing_signals=missing,
recommended_changes=[],
analysts_to_sway=analysts_to_sway,
expert_type=self.expert_type
)
def generate_enhancements(
self,
document: Document,
analysis: TypeAnalysis
) -> List[ContentEnhancement]:
"""Generate contextual skill enhancements."""
enhancements = []
content = document.body or document.content
title = document.frontmatter.get('title', 'Skill')
# Infer skill purpose
purpose = self._infer_skill_purpose(title, content)
if 'when_to_use' in analysis.missing_signals:
triggers = self._infer_triggers(content)
enhancements.append(ContentEnhancement(
signal_type='when_to_use',
content=self._generate_when_to_use(purpose, triggers),
insertion_point='after_frontmatter',
reason="Skills need clear activation criteria",
expected_analyst_boost={'content': 0.20, 'semantic': 0.15},
priority=1
))
if 'pattern' in analysis.missing_signals:
enhancements.append(ContentEnhancement(
signal_type='pattern',
content=self._generate_pattern(purpose, content),
insertion_point='after_when_to_use',
reason="Skills need pattern/template definition",
expected_analyst_boost={'content': 0.15, 'structural': 0.10},
priority=1
))
if 'io_spec' in analysis.missing_signals:
enhancements.append(ContentEnhancement(
signal_type='io_spec',
content=self._generate_io_spec(content),
insertion_point='after_pattern',
reason="Skills should specify inputs and outputs",
expected_analyst_boost={'content': 0.10, 'semantic': 0.10},
priority=2
))
if 'examples' in analysis.missing_signals:
enhancements.append(ContentEnhancement(
signal_type='examples',
content=self._generate_examples(purpose),
insertion_point='before_end',
reason="Skills benefit from usage examples",
expected_analyst_boost={'content': 0.10, 'pattern': 0.05},
priority=2
))
return enhancements
def _infer_skill_purpose(self, title: str, content: str) -> str:
"""Infer what the skill does."""
# Look for purpose patterns
purpose_match = re.search(r'(?:this skill|pattern|template)\s+(?:is for|helps|enables)\s+(.+?)(?:\.|$)', content, re.I)
if purpose_match:
return purpose_match.group(1).strip()
# Clean up title
return title.lower().replace('skill', '').replace('-', ' ').replace('_', ' ').strip()
def _infer_triggers(self, content: str) -> List[str]:
"""Infer when the skill should be activated."""
triggers = []
# Look for "when" patterns
when_matches = re.findall(r'when\s+(.+?)(?:\.|,|$)', content, re.I)
triggers.extend(when_matches[:3])
# Look for condition patterns
if_matches = re.findall(r'if\s+(?:you|the user|a user)\s+(.+?)(?:\.|,|$)', content, re.I)
triggers.extend(if_matches[:2])
if not triggers:
triggers = [
"the user needs this functionality",
"the task matches this pattern",
"automation is beneficial"
]
return triggers[:4]
def _generate_when_to_use(self, purpose: str, triggers: List[str]) -> str:
"""Generate When to Use section."""
items = "\n".join(f"- {t}" for t in triggers)
return f"""
When to Use This Skill
Use this skill when: {items}
Activation Triggers
-
User explicitly requests {purpose}
-
Task matches the defined pattern
-
Automation would improve efficiency """
def _generate_pattern(self, purpose: str, content: str) -> str: """Generate pattern section.""" return f"""
Pattern Definition
Template Structure
[Input] → [Process: {purpose}] → [Output]
Reusable Components
- Input Validation - Verify inputs meet requirements
- Core Processing - Execute the main pattern
- Output Generation - Format and return results
Customization Points
-
Configure processing parameters
-
Extend with additional steps
-
Integrate with other components """
def _generate_io_spec(self, content: str) -> str: """Generate input/output specification.""" return """
Input/Output Specification
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
input1 | string | Yes | Primary input |
options | object | No | Configuration options |
Outputs
| Name | Type | Description |
|---|---|---|
result | object | Processing result |
status | string | Success or error status |
Return Values
-
Success: Returns processed result
-
Error: Returns error object with details """
def _generate_examples(self, purpose: str) -> str: """Generate examples section.""" return f"""
Usage Examples
Basic Usage
# Apply the skill
result = apply_skill(input_data)
With Options
# Customize the skill behavior
result = apply_skill(
input_data,
options={{"verbose": True}}
)
Integration Example
# Use with other components
from skills import {purpose.replace(' ', '_')}
output = {purpose.replace(' ', '_')}.execute(context)
"""