Overview
The skill lifecycle encompasses all stages of a skill’s existence in FastSkill, from initial creation through updates and eventual retirement. Understanding lifecycle management is crucial for maintaining a healthy skill ecosystem.
Proper lifecycle management ensures skills remain relevant, secure, and performant throughout their lifetime.
Skill Lifecycle Stages
1. Created
Skills are initially created as definition files or programmatically.
2. Registered
Skills are registered with FastSkill and become part of the system.
3. Enabled
Registered skills are enabled and available for discovery and execution.
4. Active
Enabled skills are actively used by AI agents and frameworks.
5. Updated
Active skills receive updates through version releases.
6. Deprecated
Skills that are being phased out but still functional are marked as deprecated.
7. Disabled
Deprecated skills are disabled but remain in the system for reference.
8. Removed
Skills are completely removed from the system.
Creating Skills
From Scratch
Define skill requirements
Start by understanding what the skill should do:
- Purpose: What problem does it solve?
- Capabilities: What specific functions does it provide?
- Interface: How do agents interact with it?
- Constraints: What are the limitations and requirements?
Create skill definition
{
"id": "document-converter",
"name": "Document Format Converter",
"description": "Convert documents between different formats including PDF, DOCX, HTML, and plain text",
"version": "1.0.0",
"author": "Your Organization",
"tags": "documents,conversion,formats,pdf,docx,html",
"capabilities": "format_conversion,document_processing,pdf_to_text,docx_to_html",
"skill_file": "document-converter/converter.py",
"enabled": true,
"execution_timeout": 60,
"memory_limit_mb": 512,
"dependencies": ["pypdf2", "python-docx", "beautifulsoup4"],
"metadata": {
"category": "document-processing",
"supported_inputs": ["pdf", "docx", "html", "txt"],
"supported_outputs": ["pdf", "docx", "html", "txt", "json"],
"max_file_size_mb": 50
}
}
Implement the skill
Create the implementation file referenced in the skill definition:import asyncio
from typing import Dict, Any
import tempfile
import os
class DocumentConverter:
"""Convert documents between different formats."""
async def convert(self, input_file: str, output_format: str, options: Dict[str, Any] = None) -> str:
"""Convert a document to the specified format."""
# Implementation details here
pass
async def get_supported_formats(self) -> list:
"""Get list of supported input/output formats."""
return ["pdf", "docx", "html", "txt", "json"]
# FastSkill tool interface
async def convert_document(input_file: str, output_format: str, **kwargs) -> Dict[str, Any]:
"""Convert a document to a different format.
Args:
input_file: Path to input document
output_format: Desired output format (pdf, docx, html, txt, json)
**kwargs: Additional conversion options
Returns:
Dictionary with conversion results and metadata
"""
converter = DocumentConverter()
# Validate input
supported_formats = await converter.get_supported_formats()
if output_format not in supported_formats:
raise ValueError(f"Unsupported output format: {output_format}")
if not os.path.exists(input_file):
raise FileNotFoundError(f"Input file not found: {input_file}")
# Perform conversion
result_path = await converter.convert(input_file, output_format, kwargs)
return {
"output_file": result_path,
"input_format": "auto-detected",
"output_format": output_format,
"file_size_mb": os.path.getsize(result_path) / (1024 * 1024),
"conversion_time_seconds": 0 # Would be measured in real implementation
}
Register and test
import asyncio
from fastskill import FastSkillService
async def create_and_test_skill():
service = FastSkillService()
await service.initialize()
# Load skill definition
import json
with open('skill.json') as f:
skill_definition = json.load(f)
# Register skill
skill_id = await service.register_skill(skill_definition)
print(f"✅ Skill created: {skill_id}")
# Test discovery
skills = await service.discover_skills("convert document")
print(f"🔍 Found {len(skills)} matching skills")
# Test capability search
converter_skills = await service.find_skills_by_capability("format_conversion")
print(f"🛠️ Found {len(converter_skills)} skills with format conversion")
await service.shutdown()
asyncio.run(create_and_test_skill())
Version Management
Semantic Versioning
FastSkill uses semantic versioning (MAJOR.MINOR.PATCH):
- MAJOR: Breaking changes that affect compatibility
- MINOR: New features that are backward compatible
- PATCH: Bug fixes and small improvements
Version Updates
Plan the update
Determine what type of update you’re making:
- Patch: Bug fixes, security updates, performance improvements
- Minor: New features, additional capabilities, extended API
- Major: Breaking changes, API redesign, dependency changes
Update version number
# For a minor feature update
updated_skill = {
"id": "document-converter",
"version": "1.1.0", # Minor version bump
"description": "Enhanced document converter with OCR support", # Updated description
"capabilities": "format_conversion,document_processing,pdf_to_text,docx_to_html,ocr_support", # New capability
"metadata": {
"supports_ocr": True, # New feature flag
"max_pages": 100 # New limit
}
}
await service.update_skill("document-converter", updated_skill)
Update implementation
Modify the skill implementation to match the new version:# Updated converter with OCR support
async def convert_document(input_file: str, output_format: str, enable_ocr: bool = False, **kwargs) -> Dict[str, Any]:
"""Enhanced document converter with OCR support."""
# Implementation with new OCR capability
pass
Test compatibility
Ensure backward compatibility or clearly document breaking changes:# Test old interface still works
result = await convert_document("document.pdf", "txt")
# Test new interface
result = await convert_document("document.pdf", "txt", enable_ocr=True)
Skill Updates
Partial Updates
Update specific fields without replacing the entire skill definition:
# Update only specific fields
update_data = {
"version": "1.0.1",
"execution_timeout": 45, # Increase timeout for larger files
"metadata": {
"max_file_size_mb": 100 # Increase file size limit
}
}
success = await service.update_skill("document-converter", update_data)
Full Updates
Replace the entire skill definition:
# Complete skill replacement
new_skill_definition = {
"id": "document-converter",
"name": "Advanced Document Converter",
"description": "Professional document conversion with AI-powered features",
"version": "2.0.0", # Major version bump
"capabilities": "format_conversion,ai_enhancement,layout_preservation",
# ... all other fields
}
await service.update_skill("document-converter", new_skill_definition)
Enable/Disable Management
Enabling Skills
Enable a skill
# Enable a disabled skill
await service.enable_skill("document-converter")
print("✅ Skill enabled")
# Verify it's available
skills = await service.list_skills()
enabled_skills = [s for s in skills if s['enabled']]
print(f"📋 {len(enabled_skills)} skills enabled")
Batch enable skills
# Enable multiple skills
skill_ids = ["skill-1", "skill-2", "skill-3"]
for skill_id in skill_ids:
await service.enable_skill(skill_id)
print(f"✅ Enabled: {skill_id}")
Disabling Skills
Disable a skill
# Disable a skill (soft delete)
await service.disable_skill("old-skill")
print("✅ Skill disabled")
# Verify it's not available for discovery
skills = await service.discover_skills("old functionality")
print(f"🔍 Found {len(skills)} matching skills") # Should be 0
Batch disable skills
# Disable multiple skills
deprecated_skills = ["legacy-skill-1", "legacy-skill-2"]
for skill_id in deprecated_skills:
await service.disable_skill(skill_id)
print(f"⏸️ Disabled: {skill_id}")
Deprecation Process
Marking as Deprecated
Update skill status
# Mark skill as deprecated
deprecated_skill = {
"id": "legacy-converter",
"deprecated": True,
"deprecation_notice": "This skill is deprecated. Use 'document-converter' instead.",
"removal_date": "2024-12-31", # When it will be removed
"replacement_skill": "document-converter"
}
await service.update_skill("legacy-converter", deprecated_skill)
Notify users
# Get all deprecated skills
all_skills = await service.list_skills()
deprecated_skills = [s for s in all_skills if s.get('deprecated', False)]
for skill in deprecated_skills:
print(f"⚠️ DEPRECATED: {skill['name']}")
print(f" Notice: {skill.get('deprecation_notice', 'No notice')}")
if 'replacement_skill' in skill:
print(f" Use instead: {skill['replacement_skill']}")
Skill Removal
Complete Removal
Skill removal is permanent and cannot be undone. Always disable skills first and give users time to migrate.
Remove the skill
# Remove skill completely
await service.remove_skill("legacy-skill")
print("🗑️ Skill removed permanently")
# Verify removal
all_skills = await service.list_skills()
remaining_ids = [s['id'] for s in all_skills]
assert "legacy-skill" not in remaining_ids
print("✅ Skill removal verified")
Clean up resources
# Clean up associated files and cache
await service.cleanup_skill_resources("legacy-skill")
# Clear any cached data
await service.clear_skill_cache("legacy-skill")
Safe Removal Process
async def safe_skill_removal(skill_id: str, replacement_id: str = None):
"""Safely remove a skill with proper migration path."""
service = FastSkillService()
await service.initialize()
# 1. Get skill information
skill = await service.get_skill(skill_id)
if not skill:
print(f"❌ Skill {skill_id} not found")
return
# 2. Disable the skill
await service.disable_skill(skill_id)
print(f"⏸️ Disabled skill: {skill_id}")
# 3. Update with deprecation notice
deprecated_update = {
"deprecated": True,
"deprecation_notice": f"Removed in favor of {replacement_id or 'newer alternatives'}",
"removal_date": "2024-12-31"
}
if replacement_id:
deprecated_update["replacement_skill"] = replacement_id
await service.update_skill(skill_id, deprecated_update)
print(f"⚠️ Marked as deprecated: {skill_id}")
# 4. Wait for migration period (in real scenario)
print(f"📅 Migration period: 30 days")
print(f" Users should migrate to: {replacement_id or 'newer alternatives'}")
# 5. Remove after migration period
await service.remove_skill(skill_id)
print(f"🗑️ Permanently removed: {skill_id}")
await service.shutdown()
Lifecycle Monitoring
Track Skill Usage
async def monitor_skill_lifecycle():
service = FastSkillService()
await service.initialize()
# Get lifecycle statistics
all_skills = await service.list_skills()
stats = {
"total": len(all_skills),
"enabled": len([s for s in all_skills if s.get('enabled', True)]),
"disabled": len([s for s in all_skills if not s.get('enabled', True)]),
"deprecated": len([s for s in all_skills if s.get('deprecated', False)])
}
print("📊 Skill Lifecycle Statistics:")
print(f" Total skills: {stats['total']}")
print(f" Enabled: {stats['enabled']}")
print(f" Disabled: {stats['disabled']}")
print(f" Deprecated: {stats['deprecated']}")
# Show deprecated skills requiring attention
deprecated_skills = [s for s in all_skills if s.get('deprecated', False)]
if deprecated_skills:
print(f"\n⚠️ Deprecated skills:")
for skill in deprecated_skills:
print(f" - {skill['name']} (ID: {skill['id']})")
if 'removal_date' in skill:
print(f" Removal date: {skill['removal_date']}")
await service.shutdown()
Version History
# Track version changes
async def track_version_history(skill_id: str):
"""Track version changes for a skill."""
# In a real implementation, this would come from version history
version_history = [
{"version": "1.0.0", "date": "2024-01-15", "changes": "Initial release"},
{"version": "1.0.1", "date": "2024-02-01", "changes": "Bug fixes"},
{"version": "1.1.0", "date": "2024-03-15", "changes": "Added OCR support"},
{"version": "2.0.0", "date": "2024-06-01", "changes": "Major rewrite with AI features"}
]
print(f"📈 Version history for {skill_id}:")
for entry in version_history:
print(f" {entry['version']} ({entry['date']}): {entry['changes']}")
Best Practices
Plan for the full lifecycle
Consider the entire lifecycle when designing skills, from creation to eventual removal.
Use semantic versioning
Follow semantic versioning conventions to clearly communicate the impact of changes.
Provide migration paths
When deprecating or removing skills, always provide clear migration paths to replacement skills.
Monitor skill health
Regularly review skill usage, performance, and relevance to identify candidates for updates or removal.
Document lifecycle decisions
Maintain documentation of why skills were deprecated or removed for future reference.
Always disable skills before removing them. This gives users time to migrate and prevents sudden service disruptions.