Initial commit: Ajarbot with optimizations
Features: - Multi-platform bot (Slack, Telegram) - Memory system with SQLite FTS - Tool use capabilities (file ops, commands) - Scheduled tasks system - Dynamic model switching (/sonnet, /haiku) - Prompt caching for cost optimization Optimizations: - Default to Haiku 4.5 (12x cheaper) - Reduced context: 3 messages, 2 memory results - Optimized SOUL.md (48% smaller) - Automatic caching when using Sonnet (90% savings) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
399
docs/SKILLS_INTEGRATION.md
Normal file
399
docs/SKILLS_INTEGRATION.md
Normal file
@@ -0,0 +1,399 @@
|
||||
# Skills Integration Guide for Ajarbot
|
||||
|
||||
This guide explains how to integrate local Claude Code skills into your ajarbot runtime, allowing users to invoke them from messaging platforms (Slack, Telegram, etc.).
|
||||
|
||||
## 🎯 Architecture
|
||||
|
||||
```
|
||||
User (Slack/Telegram)
|
||||
↓
|
||||
"Hey bot, /adapter-dev create Discord adapter"
|
||||
↓
|
||||
Runtime Preprocessor
|
||||
↓
|
||||
Skill Invoker → Load .claude/skills/adapter-dev/SKILL.md
|
||||
↓
|
||||
Agent (processes skill instructions + message)
|
||||
↓
|
||||
Response sent back to user
|
||||
```
|
||||
|
||||
## 📁 File Structure
|
||||
|
||||
```
|
||||
ajarbot/
|
||||
├── .claude/
|
||||
│ ├── skills/ # Local skills (version controlled)
|
||||
│ │ ├── adapter-dev/ # Example skill
|
||||
│ │ │ ├── SKILL.md # Main skill definition
|
||||
│ │ │ └── examples/
|
||||
│ │ │ └── usage.md
|
||||
│ │ └── my-custom-skill/ # Your skills here
|
||||
│ │ └── SKILL.md
|
||||
│ └── SKILLS_README.md # Skills documentation
|
||||
├── adapters/
|
||||
│ └── skill_integration.py # Skill system integration
|
||||
└── example_bot_with_skills.py # Example with skills enabled
|
||||
```
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### 1. Skills are Already Set Up
|
||||
|
||||
Your project now has:
|
||||
- ✅ **Skill directory**: `.claude/skills/adapter-dev/`
|
||||
- ✅ **Skill invoker**: `adapters/skill_integration.py`
|
||||
- ✅ **Example bot**: `example_bot_with_skills.py`
|
||||
|
||||
### 2. Test Skills Locally (in Claude Code)
|
||||
|
||||
From the command line or in Claude Code:
|
||||
|
||||
```
|
||||
/adapter-dev create a WhatsApp adapter
|
||||
```
|
||||
|
||||
This will invoke the skill and Claude will help build the adapter.
|
||||
|
||||
### 3. Enable Skills in Your Bot
|
||||
|
||||
**Option A: Use the example bot**
|
||||
```python
|
||||
python example_bot_with_skills.py
|
||||
```
|
||||
|
||||
**Option B: Add to your existing bot_runner.py**
|
||||
|
||||
```python
|
||||
from adapters.skill_integration import SkillInvoker
|
||||
|
||||
# In BotRunner.setup(), after creating runtime:
|
||||
skill_invoker = SkillInvoker()
|
||||
|
||||
def skill_preprocessor(message):
|
||||
if message.text.startswith("/"):
|
||||
parts = message.text.split(maxsplit=1)
|
||||
skill_name = parts[0][1:]
|
||||
args = parts[1] if len(parts) > 1 else ""
|
||||
|
||||
if skill_name in skill_invoker.list_available_skills():
|
||||
skill_info = skill_invoker.get_skill_info(skill_name)
|
||||
skill_body = skill_info.get("body", "")
|
||||
message.text = skill_body.replace("$ARGUMENTS", args)
|
||||
|
||||
return message
|
||||
|
||||
self.runtime.add_preprocessor(skill_preprocessor)
|
||||
```
|
||||
|
||||
### 4. Use Skills from Messaging Platforms
|
||||
|
||||
**From Slack:**
|
||||
```
|
||||
@yourbot /adapter-dev create Discord adapter
|
||||
|
||||
@yourbot /skills
|
||||
```
|
||||
|
||||
**From Telegram:**
|
||||
```
|
||||
/adapter-dev create Discord adapter
|
||||
|
||||
/skills
|
||||
```
|
||||
|
||||
## 🛠️ Creating Your Own Skills
|
||||
|
||||
### Example: Code Review Skill
|
||||
|
||||
```bash
|
||||
mkdir -p .claude/skills/code-review
|
||||
```
|
||||
|
||||
Create `.claude/skills/code-review/SKILL.md`:
|
||||
|
||||
```yaml
|
||||
---
|
||||
name: code-review
|
||||
description: Review code changes for quality and security
|
||||
user-invocable: true
|
||||
disable-model-invocation: true
|
||||
allowed-tools: Read, Grep, Glob
|
||||
context: fork
|
||||
agent: Explore
|
||||
---
|
||||
|
||||
# Code Review Skill
|
||||
|
||||
Review the following code changes: $ARGUMENTS
|
||||
|
||||
## Review checklist
|
||||
|
||||
1. **Security**: Check for vulnerabilities (SQL injection, XSS, etc.)
|
||||
2. **Performance**: Identify potential bottlenecks
|
||||
3. **Code Quality**: Review patterns and best practices
|
||||
4. **Documentation**: Verify docstrings and comments
|
||||
5. **Testing**: Suggest test cases
|
||||
|
||||
## Output format
|
||||
|
||||
Provide:
|
||||
- Security findings (if any)
|
||||
- Performance concerns
|
||||
- Code quality issues
|
||||
- Recommendations
|
||||
|
||||
Focus on actionable feedback.
|
||||
```
|
||||
|
||||
**Invoke from bot:**
|
||||
```
|
||||
@bot /code-review adapters/slack/adapter.py
|
||||
```
|
||||
|
||||
### Example: Deploy Skill
|
||||
|
||||
```yaml
|
||||
---
|
||||
name: deploy
|
||||
description: Deploy the bot to production
|
||||
user-invocable: true
|
||||
disable-model-invocation: true
|
||||
allowed-tools: Bash(git:*), Bash(docker:*)
|
||||
---
|
||||
|
||||
# Deploy Skill
|
||||
|
||||
Deploy ajarbot to production environment: $ARGUMENTS
|
||||
|
||||
## Steps
|
||||
|
||||
1. Check git status - ensure working tree is clean
|
||||
2. Run tests to verify everything passes
|
||||
3. Build Docker image
|
||||
4. Tag with version
|
||||
5. Push to container registry
|
||||
6. Update deployment manifest
|
||||
7. Apply to production cluster
|
||||
|
||||
Confirm each step before proceeding.
|
||||
```
|
||||
|
||||
## 🔐 Security Best Practices
|
||||
|
||||
### 1. Restrict Tool Access
|
||||
|
||||
In SKILL.md frontmatter:
|
||||
|
||||
```yaml
|
||||
allowed-tools: Read, Grep, Glob
|
||||
```
|
||||
|
||||
This prevents the skill from:
|
||||
- Running arbitrary bash commands
|
||||
- Editing files
|
||||
- Making network requests
|
||||
|
||||
### 2. Disable Auto-Invocation
|
||||
|
||||
```yaml
|
||||
disable-model-invocation: true
|
||||
```
|
||||
|
||||
This ensures only you (not Claude autonomously) can invoke the skill.
|
||||
|
||||
### 3. Run in Isolated Context
|
||||
|
||||
```yaml
|
||||
context: fork
|
||||
```
|
||||
|
||||
Skill runs in a forked subagent, isolated from your main session.
|
||||
|
||||
### 4. Permission Allowlist
|
||||
|
||||
In `.claude/settings.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Skill(adapter-dev)",
|
||||
"Skill(code-review)",
|
||||
"Skill(deploy)"
|
||||
],
|
||||
"deny": [
|
||||
"Skill(*)" // Deny all other skills
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Version Control All Skills
|
||||
|
||||
```bash
|
||||
git add .claude/skills/
|
||||
git commit -m "Add code-review skill"
|
||||
```
|
||||
|
||||
This allows team review before skills are used.
|
||||
|
||||
## 📊 Skill Arguments
|
||||
|
||||
Skills can receive arguments in multiple ways:
|
||||
|
||||
### Positional Arguments
|
||||
|
||||
**Invoke:**
|
||||
```
|
||||
/my-skill arg1 arg2 arg3
|
||||
```
|
||||
|
||||
**Access in SKILL.md:**
|
||||
```yaml
|
||||
First arg: $0
|
||||
Second arg: $1
|
||||
All args: $ARGUMENTS
|
||||
```
|
||||
|
||||
### Named Arguments Pattern
|
||||
|
||||
**Create a skill that parses flags:**
|
||||
|
||||
```yaml
|
||||
---
|
||||
name: smart-deploy
|
||||
---
|
||||
|
||||
Parse deployment arguments: $ARGUMENTS
|
||||
|
||||
Expected format: --env <env> --version <ver>
|
||||
|
||||
Extract:
|
||||
- Environment (--env): prod, staging, dev
|
||||
- Version (--version): semver tag
|
||||
- Optional flags: --dry-run, --rollback
|
||||
|
||||
Then execute deployment with extracted parameters.
|
||||
```
|
||||
|
||||
**Invoke:**
|
||||
```
|
||||
/smart-deploy --env prod --version v1.2.3 --dry-run
|
||||
```
|
||||
|
||||
## 🔧 Advanced Integration
|
||||
|
||||
### Auto-Generate Skills from Code
|
||||
|
||||
```python
|
||||
from adapters.skill_integration import SkillInvoker
|
||||
from pathlib import Path
|
||||
|
||||
def generate_adapter_skill(platform_name: str):
|
||||
"""Auto-generate a skill for creating adapters."""
|
||||
skill_dir = Path(f".claude/skills/create-{platform_name}-adapter")
|
||||
skill_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
skill_content = f"""---
|
||||
name: create-{platform_name}-adapter
|
||||
description: Create a new {platform_name} adapter
|
||||
user-invocable: true
|
||||
allowed-tools: Read, Write, Edit
|
||||
---
|
||||
|
||||
Create a new {platform_name} messaging adapter for ajarbot.
|
||||
|
||||
1. Read existing adapters (Slack, Telegram) as templates
|
||||
2. Create adapters/{platform_name}/adapter.py
|
||||
3. Implement BaseAdapter interface
|
||||
4. Add configuration template
|
||||
5. Update bot_runner.py
|
||||
"""
|
||||
|
||||
(skill_dir / "SKILL.md").write_text(skill_content)
|
||||
print(f"✓ Generated skill: /create-{platform_name}-adapter")
|
||||
|
||||
# Usage
|
||||
generate_adapter_skill("discord")
|
||||
generate_adapter_skill("whatsapp")
|
||||
```
|
||||
|
||||
### Dynamic Skill Loading
|
||||
|
||||
```python
|
||||
def reload_skills(skill_invoker: SkillInvoker):
|
||||
"""Hot-reload skills without restarting bot."""
|
||||
available = skill_invoker.list_available_skills()
|
||||
print(f"Reloaded {len(available)} skills: {', '.join(available)}")
|
||||
return available
|
||||
```
|
||||
|
||||
### Skill Metrics
|
||||
|
||||
```python
|
||||
from collections import Counter
|
||||
|
||||
skill_usage = Counter()
|
||||
|
||||
def tracked_skill_preprocessor(message):
|
||||
if message.text.startswith("/"):
|
||||
skill_name = message.text.split()[0][1:]
|
||||
skill_usage[skill_name] += 1
|
||||
print(f"[Metrics] Skill usage: {skill_usage}")
|
||||
return message
|
||||
```
|
||||
|
||||
## 📝 Skill Best Practices
|
||||
|
||||
1. **Clear descriptions** - User-facing help text
|
||||
2. **Argument documentation** - Explain expected format
|
||||
3. **Error handling** - Graceful failures
|
||||
4. **Output format** - Consistent structure
|
||||
5. **Examples** - Provide usage examples in `examples/`
|
||||
|
||||
## 🔍 Debugging Skills
|
||||
|
||||
### Test skill locally
|
||||
|
||||
```bash
|
||||
# In project root
|
||||
python -c "from adapters.skill_integration import SkillInvoker; \
|
||||
si = SkillInvoker(); \
|
||||
print(si.get_skill_info('adapter-dev'))"
|
||||
```
|
||||
|
||||
### Validate skill syntax
|
||||
|
||||
```bash
|
||||
# Check YAML frontmatter is valid
|
||||
python -c "import yaml; \
|
||||
f = open('.claude/skills/adapter-dev/SKILL.md'); \
|
||||
content = f.read(); \
|
||||
parts = content.split('---'); \
|
||||
print(yaml.safe_load(parts[1]))"
|
||||
```
|
||||
|
||||
## 📚 Resources
|
||||
|
||||
- **Claude Code Skills Docs**: https://code.claude.com/docs/en/skills.md
|
||||
- **Security Guide**: https://code.claude.com/docs/en/security.md
|
||||
- **Example Skills**: `.claude/skills/adapter-dev/`
|
||||
- **Integration Code**: `adapters/skill_integration.py`
|
||||
|
||||
## 🎉 Summary
|
||||
|
||||
You now have:
|
||||
|
||||
✅ **Local skills** stored in `.claude/skills/`
|
||||
✅ **No registry dependencies** - fully offline
|
||||
✅ **Version controlled** - reviewed in PRs
|
||||
✅ **Invokable from bots** - Slack, Telegram, etc.
|
||||
✅ **Secure by default** - restricted tool access
|
||||
✅ **Team-shareable** - consistent across developers
|
||||
|
||||
**Next steps:**
|
||||
1. Try `/adapter-dev` in Claude Code
|
||||
2. Test `example_bot_with_skills.py`
|
||||
3. Create your own custom skills
|
||||
4. Share skills with your team via git
|
||||
Reference in New Issue
Block a user