移除了所有Hermes相关的命名引用,包括: - 从.gitignore中清理相关构建缓存文件 - 将README中的beaver-home路径配置更新 - 完善backend/README.md文档说明Beaver后端主线实现 - 移除Hermes风格的相关注释和兼容性代码 - 清理nanobot环境变量兼容性处理 - 删除技能迁移和服务迁移相关功能代码 - 更新测试用例中相关命名和函数名 BREAKING CHANGE: 移除了Hermes迁移相关API和CLI命令,不再支持nanobot环境变量兼容性
85 lines
2.7 KiB
Python
85 lines
2.7 KiB
Python
"""Beaver 内置 skill_view tool。
|
||
|
||
这个工具对应显式 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
|
||
toolset: str = "skills"
|
||
always_available: bool = True
|
||
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)
|