6d658b4f4d
- 工具系统从 kilostar/plugin/tool_plugin/ 迁移到 data/toolset/(manifest.json 声明式) - 新增 plugin_runtime 模块:BaseOrganization / GlobalPluginManager / loader / tool_bridge - 新增 org_task + org_task_event 表及 DAO(alembic 0009) - 新增 /api/v1/plugin 路由(submit/status/stream/install/reload) - 新增 data/plugin/example_dept 示例重型插件 - regulatory_node 支持聊天历史上下文注入 - send_file 改为 artifact 存盘 + SSE 推送下载链接 - 前端 WorkflowFileCard 组件 + ToolSettings README 渲染 - utils 整理:合并 access/role_check、standalone_proxy→ray_compat、删除废弃模块 - 项目结构文档移至 docs/STRUCTURE.md 并详细展开 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
90 lines
2.9 KiB
Python
90 lines
2.9 KiB
Python
"""``data/toolset/`` manifest.json 加载正确性测试。
|
|
|
|
验证 GlobalToolManager 从 manifest.json 正确读取工具元数据。
|
|
"""
|
|
|
|
import json
|
|
from pathlib import Path
|
|
|
|
_toolset_dir = Path(__file__).parent.parent.parent / "data" / "toolset"
|
|
_base_toolset_dir = _toolset_dir / "base_toolset"
|
|
_interactive_toolset_dir = _toolset_dir / "interactive_toolset"
|
|
|
|
|
|
def _read_manifest(toolset_dir=_base_toolset_dir):
|
|
with open(toolset_dir / "manifest.json", "r", encoding="utf-8") as f:
|
|
return json.load(f)
|
|
|
|
|
|
def _get_tool_def(manifest, name):
|
|
for tool in manifest["tools"]:
|
|
if tool["name"] == name:
|
|
return tool
|
|
return None
|
|
|
|
|
|
def test_manifest_json_exists():
|
|
assert (_base_toolset_dir / "manifest.json").exists()
|
|
assert (_interactive_toolset_dir / "manifest.json").exists()
|
|
|
|
|
|
def test_manifest_has_all_tools():
|
|
base_names = {t["name"] for t in _read_manifest(_base_toolset_dir)["tools"]}
|
|
interactive_names = {
|
|
t["name"] for t in _read_manifest(_interactive_toolset_dir)["tools"]
|
|
}
|
|
assert base_names == {
|
|
"shell_executor", "file_reader", "edit_file", "write_file",
|
|
"search_file", "python_executor", "tavily_search",
|
|
}
|
|
assert interactive_names == {"approval", "send_file"}
|
|
|
|
|
|
def test_approval_metadata():
|
|
manifest = _read_manifest(_interactive_toolset_dir)
|
|
tool = _get_tool_def(manifest, "approval")
|
|
assert tool["is_system"] is True
|
|
assert tool["category"] == "system"
|
|
assert tool["action_scope"] == []
|
|
|
|
|
|
def test_tavily_search_metadata():
|
|
manifest = _read_manifest()
|
|
tool = _get_tool_def(manifest, "tavily_search")
|
|
assert tool["is_system"] is False
|
|
assert tool["category"] == "search"
|
|
assert "control_node" in tool["action_scope"]
|
|
assert "consciousness_node" in tool["action_scope"]
|
|
assert "api_key" in tool["config_args"]
|
|
|
|
|
|
def test_all_tool_files_exist():
|
|
for toolset_dir in (_base_toolset_dir, _interactive_toolset_dir):
|
|
manifest = _read_manifest(toolset_dir)
|
|
for tool in manifest["tools"]:
|
|
file_path = toolset_dir / tool["file"]
|
|
assert file_path.exists(), f"Missing tool file: {tool['file']}"
|
|
|
|
|
|
def test_tool_manager_loads_all_tools():
|
|
from kilostar.core.global_state_machine.tool_manager import GlobalToolManager
|
|
|
|
tm = GlobalToolManager()
|
|
assert len(tm.tool_metadata) == 9
|
|
assert "shell_executor" in tm.tool_metadata
|
|
assert "tavily_search" in tm.tool_metadata
|
|
assert "approval" in tm.tool_metadata
|
|
|
|
|
|
def test_tool_manager_system_vs_third_party():
|
|
from kilostar.core.global_state_machine.tool_manager import GlobalToolManager
|
|
|
|
tm = GlobalToolManager()
|
|
system_tools = tm.get_system_tools()
|
|
third_party = tm.get_third_party_tools()
|
|
system_names = {t["name"] for t in system_tools}
|
|
tp_names = {t["name"] for t in third_party}
|
|
assert "shell_executor" in system_names
|
|
assert "tavily_search" in tp_names
|
|
assert "tavily_search" not in system_names
|