Coverage for merco/tools/skill_tools.py: 79%
33 statements
« prev ^ index » next coverage.py v7.15.0, created at 2026-07-07 14:04 +0800
« prev ^ index » next coverage.py v7.15.0, created at 2026-07-07 14:04 +0800
1"""技能工具 — skill_view 让 LLM 按需加载技能完整内容"""
3from .base import BaseTool
6class SkillViewTool(BaseTool):
7 """加载指定技能的完整说明文档
9 对标 Hermes/OpenCode:LLM 调用 skill_view(name) 加载技能正文。
10 工具描述动态列出可用技能,无需在 system prompt 中重复。
11 """
13 name = "skill_view"
14 description = "加载指定技能的完整说明文档。使用前先调用此工具获取详细指引。"
15 toolset = "skills"
16 parameters = {
17 "type": "object",
18 "properties": {
19 "name": {
20 "type": "string",
21 "description": "技能名称(如 project-vision)",
22 },
23 },
24 "required": ["name"],
25 }
27 def __init__(self):
28 self._skill_registry = None
30 def set_skill_registry(self, registry):
31 """注入技能注册表(由 CLI 在构造 Agent 时调用)"""
32 self._skill_registry = registry
34 def describe(self, context: dict | None = None) -> str:
35 """动态描述:列出所有可用技能的名称和简介"""
36 base = self.description
37 registry = self._skill_registry
38 if registry:
39 skills = registry.list_skills()
40 if skills:
41 lines = [f"\n\n可用技能:"]
42 for s in skills:
43 lines.append(f"- **{s['name']}**: {s.get('description', '')}")
44 base += "\n".join(lines)
45 return base
47 def check(self) -> bool:
48 """有可用技能时才显示此工具"""
49 return self._skill_registry is not None and len(self._skill_registry.list_skills()) > 0
51 async def execute(self, name: str) -> dict:
52 """返回技能的完整内容(正文 + 元数据)"""
53 if not self._skill_registry:
54 return {"error": "技能系统未初始化"}
56 skill = self._skill_registry.get(name)
57 if not skill:
58 available = [s['name'] for s in self._skill_registry.list_skills()]
59 return {
60 "error": f"未找到技能: {name}",
61 "available_skills": available,
62 }
64 return {
65 "name": skill["name"],
66 "description": skill.get("description", ""),
67 "content": skill.get("content", ""),
68 }
71from .registry import tool_registry # noqa: E402 — 模块末尾自注册
73tool_registry.register(SkillViewTool())