feat(toolset): 工具系统重构为 toolset 统一管理,新增系统预置工具集

将工具管理从"agent 挂单个 tool"改为"agent 挂 toolset"模式:
- 三个系统预置工具集(system_basic/system_chat/system_workflow)入 DB
- 新增 send_file 工具(系统对话工具集)、修复 approval actor 调用 bug
- 后端 agent 加载全部走 toolset 链路,移除 load_tools_from_list
- 前端工具集中心卡片展示 + agent 配置改为 toolset 多选
- resource API 增加 category 过滤与系统 toolset 保护

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-05 18:03:49 +00:00
parent d39c80743d
commit 0e57c5cf16
23 changed files with 584 additions and 169 deletions
+2 -2
View File
@@ -50,7 +50,7 @@ def test_valid_affinities_accepted():
for aff in _VALID_AFFINITIES:
m = WorkerIndividualCreate(
agent_name="x", agent_type="ordinary", description="d",
provider_title="p", model_id="m", system_prompt="s",
provider_title="p", model_id="m", persona_id="pid",
output_template={}, bound_skill={}, workspace=[], node_affinity=aff,
)
assert m.node_affinity == aff
@@ -62,7 +62,7 @@ def test_invalid_affinity_raises():
with pytest.raises(ValidationError):
WorkerIndividualCreate(
agent_name="x", agent_type="ordinary", description="d",
provider_title="p", model_id="m", system_prompt="s",
provider_title="p", model_id="m", persona_id="pid",
output_template={}, bound_skill={}, workspace=[], node_affinity="bad",
)
+6 -12
View File
@@ -312,7 +312,7 @@ async def test_fetch_snapshot_use_cache_false_skips_cache(monkeypatch):
def test_build_toolsets_for_scope_assembles_system_and_custom():
"""客户端按 snapshot 的 system_tools_by_scope + custom_toolsets 现场组装。"""
"""客户端按 snapshot 的 custom_toolsets + all_funcs 现场组装。"""
from kilostar.core.global_state_machine.gsm_snapshot import (
build_toolsets_for_scope,
)
@@ -327,22 +327,17 @@ def test_build_toolsets_for_scope_assembles_system_and_custom():
return "a"
snap = GSMSnapshot(
tool_funcs={"sys_default": _sys_default, "sys_scope": _sys_scope},
third_party_funcs={"tp_a": _tp_a},
system_tools_by_scope={
"default": ["sys_default"],
"control_node": ["sys_scope"],
},
all_funcs={"sys_default": _sys_default, "sys_scope": _sys_scope, "tp_a": _tp_a},
custom_toolsets={
"system_basic": {"toolset_id": "system_basic", "tools": ["sys_default", "sys_scope"]},
"grp": {"toolset_id": "grp", "tools": ["tp_a"]},
},
)
result = build_toolsets_for_scope(snap, "control_node")
# 应包含两个 system bucket + 一个 custom toolset
assert len(result) == 3
assert len(result) == 2
ids = [getattr(t, "id", None) for t in result]
assert ids == ["system::default", "system::control_node", "custom::grp"]
assert ids == ["toolset::system_basic", "toolset::grp"]
def test_build_toolsets_for_scope_skips_empty_buckets():
@@ -352,8 +347,7 @@ def test_build_toolsets_for_scope_skips_empty_buckets():
)
snap = GSMSnapshot(
tool_funcs={},
system_tools_by_scope={"default": [], "control_node": []},
all_funcs={},
custom_toolsets={},
)
assert build_toolsets_for_scope(snap, "control_node") == []
+1 -1
View File
@@ -127,7 +127,7 @@ async def test_get_all_toolsets_for_scope_merges_local_and_mcp(monkeypatch):
monkeypatch.setattr(
snap_mod,
"build_toolsets_for_scope",
lambda s, scope: [local_a, local_b],
lambda s, scope, **kw: [local_a, local_b],
)
result = await mcp_helper.get_all_toolsets_for_scope("control_node")