Files
beaver_project/app-instance/backend/beaver/tools/builtins/skill_view.py

83 lines
2.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Beaver 内置 skill_view tool。
这个工具对应 Hermes 风格的显式 skill loading path
1. skill 正文默认不会长期塞进 system prompt
2. 模型若想查看某个 skill 的完整正文或支持文件,必须显式调用 `skill_view`
这样 skill 的按需展开路径会保持显式,而不是依赖 prompt 里长期堆目录信息。
"""
from __future__ import annotations
import json
from dataclasses import dataclass, field
from typing import Any
from beaver.skills.catalog.loader import SkillsLoader
SKILL_VIEW_TOOL_DESCRIPTION = (
"Load the full content of a skill or one of its supporting files. "
"Use this when you want to inspect a skill in detail."
)
SKILL_VIEW_TOOL_PARAMETERS: dict[str, Any] = {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The skill name to inspect.",
},
"file_path": {
"type": "string",
"description": (
"Optional relative path to a supporting file inside the skill directory, "
"for example 'references/usage.md'. Omit to load SKILL.md itself."
),
},
},
"required": ["name"],
}
def skill_view(*, name: str, file_path: str | None = None, loader: SkillsLoader | None = None) -> str:
"""读取 skill 正文或支持文件,并返回结构化 JSON。"""
if loader is None:
return json.dumps({"success": False, "error": "Skills loader is not available."}, ensure_ascii=False)
try:
viewed = loader.view_skill(name, file_path=file_path)
except FileNotFoundError as exc:
return json.dumps({"success": False, "error": str(exc)}, ensure_ascii=False)
except ValueError as exc:
return json.dumps({"success": False, "error": str(exc)}, ensure_ascii=False)
if viewed is None:
return json.dumps({"success": False, "error": f"Unknown skill '{name}'."}, ensure_ascii=False)
display_name, content = viewed
support_files = loader.list_skill_supporting_files(name)
return json.dumps(
{
"success": True,
"name": name,
"file": display_name,
"content": content,
"supporting_files": support_files,
},
ensure_ascii=False,
)
@dataclass(slots=True)
class SkillViewTool:
"""面向 runtime 的 skill_view 工具封装。"""
loader: SkillsLoader
name: str = "skill_view"
description: str = SKILL_VIEW_TOOL_DESCRIPTION
parameters: dict[str, Any] = field(default_factory=lambda: dict(SKILL_VIEW_TOOL_PARAMETERS))
async def execute(self, **kwargs: Any) -> str:
return skill_view(loader=self.loader, **kwargs)