feat(multi-llm): Phase 1 - Foundation adaptor architecture
Implement base adaptor pattern for multi-LLM support (Issue #179) **Architecture:** - Created adaptors/ package with base SkillAdaptor class - Implemented factory pattern with get_adaptor() registry - Refactored Claude-specific code into ClaudeAdaptor **Changes:** - New: src/skill_seekers/cli/adaptors/base.py (SkillAdaptor + SkillMetadata) - New: src/skill_seekers/cli/adaptors/__init__.py (registry + factory) - New: src/skill_seekers/cli/adaptors/claude.py (refactored upload + enhance logic) - Modified: package_skill.py (added --target flag, uses adaptor.package()) - Modified: upload_skill.py (added --target flag, uses adaptor.upload()) - Modified: enhance_skill.py (added --target flag, uses adaptor.enhance()) **Tests:** - New: tests/test_adaptors/test_base.py (10 tests passing) - All existing tests still pass (backward compatible) **Backward Compatibility:** - Default --target=claude maintains existing behavior - All CLI tools work exactly as before without --target flag - No breaking changes **Next:** Phase 2 - Implement Gemini, OpenAI, Markdown adaptors
This commit is contained in:
@@ -1,12 +1,18 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
SKILL.md Enhancement Script
|
||||
Uses Claude API to improve SKILL.md by analyzing reference documentation.
|
||||
Uses platform AI APIs to improve SKILL.md by analyzing reference documentation.
|
||||
|
||||
Usage:
|
||||
skill-seekers enhance output/steam-inventory/
|
||||
# Claude (default)
|
||||
skill-seekers enhance output/react/
|
||||
skill-seekers enhance output/godot/ --api-key YOUR_API_KEY
|
||||
skill-seekers enhance output/react/ --api-key sk-ant-...
|
||||
|
||||
# Gemini
|
||||
skill-seekers enhance output/react/ --target gemini --api-key AIzaSy...
|
||||
|
||||
# OpenAI
|
||||
skill-seekers enhance output/react/ --target openai --api-key sk-proj-...
|
||||
"""
|
||||
|
||||
import os
|
||||
@@ -195,18 +201,26 @@ Return ONLY the complete SKILL.md content, starting with the frontmatter (---).
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Enhance SKILL.md using Claude API',
|
||||
description='Enhance SKILL.md using platform AI APIs',
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog="""
|
||||
Examples:
|
||||
# Using ANTHROPIC_API_KEY environment variable
|
||||
# Claude (default)
|
||||
export ANTHROPIC_API_KEY=sk-ant-...
|
||||
skill-seekers enhance output/steam-inventory/
|
||||
skill-seekers enhance output/react/
|
||||
|
||||
# Providing API key directly
|
||||
# Gemini
|
||||
export GOOGLE_API_KEY=AIzaSy...
|
||||
skill-seekers enhance output/react/ --target gemini
|
||||
|
||||
# OpenAI
|
||||
export OPENAI_API_KEY=sk-proj-...
|
||||
skill-seekers enhance output/react/ --target openai
|
||||
|
||||
# With explicit API key
|
||||
skill-seekers enhance output/react/ --api-key sk-ant-...
|
||||
|
||||
# Show what would be done (dry run)
|
||||
# Dry run
|
||||
skill-seekers enhance output/godot/ --dry-run
|
||||
"""
|
||||
)
|
||||
@@ -214,7 +228,11 @@ Examples:
|
||||
parser.add_argument('skill_dir', type=str,
|
||||
help='Path to skill directory (e.g., output/steam-inventory/)')
|
||||
parser.add_argument('--api-key', type=str,
|
||||
help='Anthropic API key (or set ANTHROPIC_API_KEY env var)')
|
||||
help='Platform API key (or set environment variable)')
|
||||
parser.add_argument('--target',
|
||||
choices=['claude', 'gemini', 'openai'],
|
||||
default='claude',
|
||||
help='Target LLM platform (default: claude)')
|
||||
parser.add_argument('--dry-run', action='store_true',
|
||||
help='Show what would be done without calling API')
|
||||
|
||||
@@ -249,18 +267,57 @@ Examples:
|
||||
print(f" skill-seekers enhance {skill_dir}")
|
||||
return
|
||||
|
||||
# Create enhancer and run
|
||||
# Check if platform supports enhancement
|
||||
try:
|
||||
enhancer = SkillEnhancer(skill_dir, api_key=args.api_key)
|
||||
success = enhancer.run()
|
||||
from skill_seekers.cli.adaptors import get_adaptor
|
||||
|
||||
adaptor = get_adaptor(args.target)
|
||||
|
||||
if not adaptor.supports_enhancement():
|
||||
print(f"❌ Error: {adaptor.PLATFORM_NAME} does not support AI enhancement")
|
||||
print(f"\nSupported platforms for enhancement:")
|
||||
print(" - Claude AI (Anthropic)")
|
||||
print(" - Google Gemini")
|
||||
print(" - OpenAI ChatGPT")
|
||||
sys.exit(1)
|
||||
|
||||
# Get API key
|
||||
api_key = args.api_key
|
||||
if not api_key:
|
||||
api_key = os.environ.get(adaptor.get_env_var_name(), '').strip()
|
||||
|
||||
if not api_key:
|
||||
print(f"❌ Error: {adaptor.get_env_var_name()} not set")
|
||||
print(f"\nSet your API key for {adaptor.PLATFORM_NAME}:")
|
||||
print(f" export {adaptor.get_env_var_name()}=...")
|
||||
print("Or provide it directly:")
|
||||
print(f" skill-seekers enhance {skill_dir} --target {args.target} --api-key ...")
|
||||
sys.exit(1)
|
||||
|
||||
# Run enhancement using adaptor
|
||||
print(f"\n{'='*60}")
|
||||
print(f"ENHANCING SKILL: {skill_dir}")
|
||||
print(f"Platform: {adaptor.PLATFORM_NAME}")
|
||||
print(f"{'='*60}\n")
|
||||
|
||||
success = adaptor.enhance(Path(skill_dir), api_key)
|
||||
|
||||
if success:
|
||||
print(f"\n✅ Enhancement complete!")
|
||||
print(f"\nNext steps:")
|
||||
print(f" 1. Review: {Path(skill_dir) / 'SKILL.md'}")
|
||||
print(f" 2. If you don't like it, restore backup: {Path(skill_dir) / 'SKILL.md.backup'}")
|
||||
print(f" 3. Package your skill:")
|
||||
print(f" skill-seekers package {skill_dir}/ --target {args.target}")
|
||||
|
||||
sys.exit(0 if success else 1)
|
||||
|
||||
except ImportError as e:
|
||||
print(f"❌ Error: {e}")
|
||||
print("\nAdaptor system not available. Reinstall skill-seekers.")
|
||||
sys.exit(1)
|
||||
except ValueError as e:
|
||||
print(f"❌ Error: {e}")
|
||||
print("\nSet your API key:")
|
||||
print(" export ANTHROPIC_API_KEY=sk-ant-...")
|
||||
print("Or provide it directly:")
|
||||
print(f" skill-seekers enhance {skill_dir} --api-key sk-ant-...")
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
print(f"❌ Unexpected error: {e}")
|
||||
|
||||
Reference in New Issue
Block a user