9b73ae4db4
Bug fixes: - fix(dao): AsyncSession.delete 补齐漏掉的 await(provider/user/individual 共 4 处) - fix(worker): result.data.output → result.output.output(pydantic-ai 1.x API 适配) - fix(api): 删除 create_worker_from_template 死端点(ORM 字段不匹配必崩) - fix(api): /provider/test 按 provider_type 分支适配 Anthropic/Gemini/OpenAI 三种协议 - fix(chat): SSE 流式聊天在 distributed 模式 fallback 到非流式,避免 asyncio.Queue 序列化崩溃 Features (previously unstaged): - feat(provider): Provider 管理页重做(品牌图标、5 种类型、Test Connection、编辑模式) - feat(provider): 新增 Gemini provider_type 支持 - feat(workflow): Finalize 节点输出 blackboard 摘要 + 失败原因;步骤完成/失败实时推送 SSE - feat(i18n): regulatory_node 提示词从路由模式改为直接对话模式(中英双语) - feat(consciousness): dynamic_prompt 支持 locale 国际化 - feat(logs): SystemLogsView 自动刷新 + 暂停按钮 Docs: - docs: README/README-EN 统一为"开源通用多 Agent 协作平台"口径 - docs: ROADMAP 按 v0.1.x / v0.2.x / v0.3.x 重组 - docs: project.md 重写为结构化项目介绍 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
94 lines
3.5 KiB
Python
94 lines
3.5 KiB
Python
"""``GlobalToolManager`` 在真实仓库目录上的扫描结果。
|
||
|
||
期望(基于现有 plugin 目录):
|
||
- approval / file_reader:is_system=True,进 system toolset
|
||
- tavily_search:is_system=False,category=search,进 third_party
|
||
"""
|
||
|
||
import pytest
|
||
|
||
from kilostar.core.global_state_machine.tool_manager import GlobalToolManager
|
||
|
||
|
||
@pytest.fixture(scope="module")
|
||
def manager() -> GlobalToolManager:
|
||
return GlobalToolManager()
|
||
|
||
|
||
def test_metadata_contains_known_plugins(manager: GlobalToolManager):
|
||
names = set(manager.tool_metadata.keys())
|
||
assert {"approval", "file_reader", "tavily_search"} <= names
|
||
|
||
|
||
def test_system_and_third_party_classification(manager: GlobalToolManager):
|
||
sys_tools = {m["name"] for m in manager.get_system_tools()}
|
||
tp_tools = {m["name"] for m in manager.get_third_party_tools()}
|
||
assert {"approval", "file_reader"} <= sys_tools
|
||
assert "tavily_search" in tp_tools
|
||
assert sys_tools.isdisjoint(tp_tools)
|
||
|
||
|
||
def test_get_tools_by_category_returns_correct_buckets(manager: GlobalToolManager):
|
||
by_system = {m["name"] for m in manager.get_tools_by_category("system")}
|
||
by_search = {m["name"] for m in manager.get_tools_by_category("search")}
|
||
assert {"approval", "file_reader"} <= by_system
|
||
assert "tavily_search" in by_search
|
||
|
||
|
||
def test_is_third_party_tool(manager: GlobalToolManager):
|
||
assert manager.is_third_party_tool("tavily_search") is True
|
||
assert manager.is_third_party_tool("approval") is False
|
||
assert manager.is_third_party_tool("nonexistent") is False
|
||
|
||
|
||
def test_get_toolsets_for_scope_returns_function_toolsets(manager: GlobalToolManager):
|
||
from pydantic_ai.toolsets import FunctionToolset
|
||
|
||
sets = manager.get_toolsets_for_scope("control_node")
|
||
assert sets, "control_node 应该至少有 system toolset"
|
||
for ts in sets:
|
||
assert isinstance(ts, FunctionToolset)
|
||
|
||
|
||
def test_system_toolsets_have_correct_ids(manager: GlobalToolManager):
|
||
sets = manager.get_toolsets_for_scope("consciousness_node")
|
||
ids = {getattr(ts, "id", None) for ts in sets}
|
||
for tid in ids:
|
||
assert tid.startswith("system::") or tid.startswith("custom::")
|
||
|
||
|
||
def test_no_mcp_category_in_metadata_for_local_plugins(manager: GlobalToolManager):
|
||
for m in manager.tool_metadata.values():
|
||
if m["category"] == "mcp":
|
||
assert m["name"] not in manager._third_party_funcs
|
||
for scope_funcs in manager._tool_funcs.values():
|
||
assert m["name"] not in scope_funcs
|
||
|
||
|
||
def test_unknown_scope_returns_only_default_and_custom(manager: GlobalToolManager):
|
||
sets = manager.get_toolsets_for_scope("not_a_real_scope")
|
||
for ts in sets:
|
||
tid = getattr(ts, "id", "")
|
||
assert tid.endswith("::default") or tid.startswith("custom::")
|
||
|
||
|
||
def test_rebuild_custom_toolsets(manager: GlobalToolManager):
|
||
custom_defs = {
|
||
"grp1": {"tools": ["tavily_search"], "name": "search-group"},
|
||
}
|
||
manager.rebuild_custom_toolsets(custom_defs)
|
||
assert "grp1" in manager._custom_toolsets
|
||
sets = manager.get_toolsets_for_scope("default")
|
||
custom_ids = [getattr(ts, "id", "") for ts in sets if "toolset::" in getattr(ts, "id", "")]
|
||
assert any("grp1" in cid for cid in custom_ids)
|
||
manager.rebuild_custom_toolsets({})
|
||
assert manager._custom_toolsets == {}
|
||
|
||
|
||
def test_get_personal_tools_compat(manager: GlobalToolManager):
|
||
assert manager.get_personal_tools() == manager.get_third_party_tools()
|
||
|
||
|
||
def test_get_non_system_tools_compat(manager: GlobalToolManager):
|
||
assert manager.get_non_system_tools() == manager.get_third_party_tools()
|