172 lines
5.3 KiB
Python
172 lines
5.3 KiB
Python
"""Skill management CLI commands"""
|
|
|
|
import os
|
|
from typing import Optional
|
|
|
|
import typer
|
|
from rich import print as rprint
|
|
from rich.table import Table
|
|
|
|
skill_app = typer.Typer(name="skill", help="Skill management commands", no_args_is_help=True)
|
|
|
|
|
|
@skill_app.command("list")
|
|
def list_skills(
|
|
server_url: Optional[str] = typer.Option(None, "--server-url", help="AgentKit server URL"),
|
|
):
|
|
"""List registered skills"""
|
|
if server_url:
|
|
# Remote mode: call API
|
|
import httpx
|
|
try:
|
|
with httpx.Client(timeout=10.0) as client:
|
|
response = client.get(f"{server_url}/api/v1/skills")
|
|
response.raise_for_status()
|
|
skills = response.json()
|
|
except Exception as e:
|
|
rprint(f"[red]Error connecting to server: {e}[/red]")
|
|
raise typer.Exit(code=1)
|
|
else:
|
|
# Local mode: use SkillRegistry directly, loading from default configs/skills/
|
|
from agentkit.skills.loader import SkillLoader
|
|
from agentkit.skills.registry import SkillRegistry
|
|
from agentkit.tools.registry import ToolRegistry
|
|
|
|
registry = SkillRegistry()
|
|
# Load skills from the default configs/skills/ directory if it exists
|
|
default_skills_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "configs", "skills")
|
|
if os.path.isdir(default_skills_dir):
|
|
loader = SkillLoader(registry, ToolRegistry())
|
|
loader.load_from_directory(default_skills_dir)
|
|
skills = [
|
|
{
|
|
"name": s.name,
|
|
"agent_type": s.config.agent_type,
|
|
"version": s.config.version,
|
|
"description": s.config.description,
|
|
}
|
|
for s in registry.list_skills()
|
|
]
|
|
|
|
if not skills:
|
|
rprint("[dim]No skills registered[/dim]")
|
|
return
|
|
|
|
table = Table(title="Skills")
|
|
table.add_column("Name", style="cyan")
|
|
table.add_column("Type")
|
|
table.add_column("Description")
|
|
for s in skills:
|
|
table.add_row(
|
|
s.get("name", ""),
|
|
s.get("agent_type", ""),
|
|
s.get("description", ""),
|
|
)
|
|
rprint(table)
|
|
|
|
|
|
@skill_app.command("load")
|
|
def load_skill(
|
|
path: str = typer.Argument(help="Path to skill YAML file"),
|
|
):
|
|
"""Load a skill from YAML file"""
|
|
if not os.path.exists(path):
|
|
rprint(f"[red]Error: File not found: {path}[/red]")
|
|
raise typer.Exit(code=1)
|
|
|
|
try:
|
|
from agentkit.skills.loader import SkillLoader
|
|
from agentkit.skills.registry import SkillRegistry
|
|
from agentkit.tools.registry import ToolRegistry
|
|
|
|
registry = SkillRegistry()
|
|
loader = SkillLoader(registry, ToolRegistry())
|
|
skill = loader.load_from_file(path)
|
|
rprint(f"[green]Skill loaded:[/green] {skill.name}")
|
|
rprint(f" Description: {skill.config.description}")
|
|
rprint(f" Mode: {skill.config.task_mode}")
|
|
except Exception as e:
|
|
rprint(f"[red]Error loading skill: {e}[/red]")
|
|
raise typer.Exit(code=1)
|
|
|
|
|
|
@skill_app.command("create")
|
|
def skill_create(
|
|
name: str = typer.Argument(..., help="Skill name"),
|
|
output_dir: Optional[str] = typer.Option(".", "--output-dir", "-o", help="Output directory"),
|
|
):
|
|
"""Create a new SKILL.md template"""
|
|
template = f'''---
|
|
name: {name}
|
|
description: "Description of {name}"
|
|
agent_type: {name}
|
|
execution_mode: react
|
|
intent:
|
|
keywords: ["{name}"]
|
|
description: "Tasks related to {name}"
|
|
quality_gate:
|
|
required_fields: []
|
|
min_word_count: 0
|
|
---
|
|
|
|
# Trigger
|
|
- When to use this skill
|
|
|
|
# Steps
|
|
1. Step one
|
|
2. Step two
|
|
3. Step three
|
|
|
|
# Pitfalls
|
|
- Common mistakes to avoid
|
|
|
|
# Verification
|
|
- How to verify the output
|
|
'''
|
|
output_path = os.path.join(output_dir, f"{name}.md")
|
|
os.makedirs(output_dir, exist_ok=True)
|
|
with open(output_path, "w", encoding="utf-8") as f:
|
|
f.write(template)
|
|
rprint(f"[green]Created SKILL.md template:[/green] {output_path}")
|
|
|
|
|
|
@skill_app.command("info")
|
|
def skill_info(
|
|
name: str = typer.Argument(help="Skill name"),
|
|
server_url: Optional[str] = typer.Option(None, "--server-url", help="AgentKit server URL"),
|
|
):
|
|
"""Show skill details"""
|
|
if server_url:
|
|
import httpx
|
|
try:
|
|
with httpx.Client(timeout=10.0) as client:
|
|
response = client.get(f"{server_url}/api/v1/skills/{name}")
|
|
response.raise_for_status()
|
|
info = response.json()
|
|
except Exception as e:
|
|
rprint(f"[red]Error: {e}[/red]")
|
|
raise typer.Exit(code=1)
|
|
else:
|
|
from agentkit.skills.registry import SkillRegistry
|
|
registry = SkillRegistry()
|
|
try:
|
|
skill = registry.get(name)
|
|
info = {
|
|
"name": skill.name,
|
|
"agent_type": skill.config.agent_type,
|
|
"version": skill.config.version,
|
|
"description": skill.config.description,
|
|
"task_mode": skill.config.task_mode,
|
|
"execution_mode": skill.config.execution_mode,
|
|
}
|
|
except Exception as e:
|
|
rprint(f"[red]Skill '{name}' not found: {e}[/red]")
|
|
raise typer.Exit(code=1)
|
|
|
|
table = Table(title=f"Skill: {name}")
|
|
table.add_column("Field", style="cyan")
|
|
table.add_column("Value")
|
|
for key, value in info.items():
|
|
table.add_row(key, str(value))
|
|
rprint(table)
|