feat: manage_skill + 全局 skills 目录
新增: - manage_skill: LLM 可调用的 Skill 创建/删除/列出工具 (High) - 全局 skills 支持: ~/.ias/skills/ 自动加载 - SkillRegistry::register_skill() 动态注册 - SkillRegistry::load() 三元加载: system → global → user manage_skill 操作: create: 写 SKILL.md + 执行脚本到 skills/<name>/ delete: 移除 skills/<name>/ list: 列出所有自定义 Skill 目前一共 9 个系统 Skills
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
# manage_skill
|
||||
|
||||
管理 Skill:创建新的 Skill,列出所有已加载的 Skill,删除 Skill。
|
||||
|
||||
创建的 Skill 会持久化到 `skills/` 目录,重启后自动加载。
|
||||
|
||||
## Risk Level
|
||||
High
|
||||
|
||||
## Parameters
|
||||
```json
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
"description": "操作类型",
|
||||
"enum": ["create", "delete", "list"]
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Skill 名称(create/delete 时需要)"
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "Skill 描述(create 时需要)"
|
||||
},
|
||||
"command": {
|
||||
"type": "string",
|
||||
"description": "Skill 执行的命令(create 时需要)"
|
||||
},
|
||||
"parameters": {
|
||||
"type": "string",
|
||||
"description": "参数 JSON Schema(create 时需要,JSON 字符串)"
|
||||
},
|
||||
"risk_level": {
|
||||
"type": "string",
|
||||
"description": "风险等级 Low|High,默认 Low",
|
||||
"enum": ["Low", "High"]
|
||||
}
|
||||
},
|
||||
"required": ["action"]
|
||||
}
|
||||
```
|
||||
|
||||
## Execute
|
||||
```bash
|
||||
scripts/manage.sh
|
||||
```
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
#!/bin/bash
|
||||
read -r INPUT
|
||||
export MANAGE_INPUT="$INPUT"
|
||||
|
||||
python3 - "skills" << 'PYEOF'
|
||||
import sys, json, os, stat
|
||||
|
||||
skills_dir = sys.argv[1]
|
||||
input_raw = os.environ.get('MANAGE_INPUT', '{}')
|
||||
|
||||
try:
|
||||
req = json.loads(input_raw) if input_raw else json.loads(sys.stdin.read())
|
||||
except:
|
||||
print("无效的 JSON 输入")
|
||||
sys.exit(1)
|
||||
|
||||
action = req.get('action', 'list')
|
||||
name = req.get('name', '').strip()
|
||||
desc = req.get('description', '')
|
||||
command = req.get('command', '')
|
||||
params = req.get('parameters', '{"type":"object","properties":{}}')
|
||||
risk = req.get('risk_level', 'Low')
|
||||
|
||||
os.makedirs(skills_dir, exist_ok=True)
|
||||
|
||||
if action == 'list':
|
||||
if not os.path.isdir(skills_dir):
|
||||
print("skills 目录不存在")
|
||||
sys.exit(0)
|
||||
entries = [d for d in os.listdir(skills_dir) if os.path.isdir(os.path.join(skills_dir, d))]
|
||||
if not entries:
|
||||
print("暂无自定义 Skill")
|
||||
else:
|
||||
print("自定义 Skills:")
|
||||
for d in sorted(entries):
|
||||
md = os.path.join(skills_dir, d, "SKILL.md")
|
||||
if os.path.exists(md):
|
||||
first = open(md).readline().strip('# \n')
|
||||
print(f" • {d} — {first}")
|
||||
|
||||
elif action == 'create':
|
||||
if not name:
|
||||
print("请提供 name 参数")
|
||||
sys.exit(1)
|
||||
if not command:
|
||||
print("请提供 command 参数")
|
||||
sys.exit(1)
|
||||
|
||||
skill_dir = os.path.join(skills_dir, name)
|
||||
scripts_dir = os.path.join(skill_dir, "scripts")
|
||||
os.makedirs(scripts_dir, exist_ok=True)
|
||||
|
||||
# 解析参数 JSON(美化)
|
||||
try:
|
||||
params_obj = json.loads(params) if isinstance(params, str) else params
|
||||
params_pretty = json.dumps(params_obj, indent=2, ensure_ascii=False)
|
||||
except:
|
||||
params_pretty = params
|
||||
|
||||
# 写 SKILL.md
|
||||
md_content = f"""# {name}
|
||||
|
||||
{desc}
|
||||
|
||||
## Risk Level
|
||||
{risk}
|
||||
|
||||
## Parameters
|
||||
```json
|
||||
{params_pretty}
|
||||
```
|
||||
|
||||
## Execute
|
||||
```bash
|
||||
scripts/main.sh
|
||||
```
|
||||
"""
|
||||
with open(os.path.join(skill_dir, "SKILL.md"), "w") as f:
|
||||
f.write(md_content.strip() + "\n")
|
||||
|
||||
# 写执行脚本
|
||||
script = os.path.join(scripts_dir, "main.sh")
|
||||
with open(script, "w") as f:
|
||||
f.write(f"#!/bin/bash\n{command}\n")
|
||||
os.chmod(script, 0o755)
|
||||
|
||||
print(f"✅ 已创建 Skill: {name}")
|
||||
print(f" 位置: {skill_dir}")
|
||||
print(f" 风险: {risk}")
|
||||
|
||||
elif action == 'delete':
|
||||
if not name:
|
||||
print("请提供 name 参数")
|
||||
sys.exit(1)
|
||||
skill_dir = os.path.join(skills_dir, name)
|
||||
if not os.path.isdir(skill_dir):
|
||||
print(f"Skill 不存在: {name}")
|
||||
sys.exit(1)
|
||||
import shutil
|
||||
shutil.rmtree(skill_dir)
|
||||
print(f"✅ 已删除 Skill: {name}")
|
||||
|
||||
else:
|
||||
print(f"未知操作: {action}(支持: create, delete, list)")
|
||||
sys.exit(1)
|
||||
PYEOF
|
||||
Reference in New Issue
Block a user