Add per-agent skill workspaces and TraderView management
This commit is contained in:
191
backend/tests/test_agent_workspace.py
Normal file
191
backend/tests/test_agent_workspace.py
Normal file
@@ -0,0 +1,191 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from backend.agents.prompt_factory import build_agent_system_prompt
|
||||
from backend.agents.skills_manager import SkillsManager
|
||||
from backend.agents.workspace_manager import WorkspaceManager
|
||||
|
||||
|
||||
class _DummyToolkit:
|
||||
def get_agent_skill_prompt(self):
|
||||
return ""
|
||||
|
||||
def get_activated_notes(self):
|
||||
return ""
|
||||
|
||||
|
||||
def test_workspace_manager_creates_extended_agent_files(tmp_path):
|
||||
manager = WorkspaceManager(project_root=tmp_path)
|
||||
|
||||
manager.initialize_default_assets(
|
||||
config_name="demo",
|
||||
agent_ids=["risk_manager"],
|
||||
analyst_personas={},
|
||||
)
|
||||
|
||||
asset_dir = tmp_path / "runs" / "demo" / "agents" / "risk_manager"
|
||||
assert (asset_dir / "SOUL.md").exists()
|
||||
assert (asset_dir / "PROFILE.md").exists()
|
||||
assert (asset_dir / "AGENTS.md").exists()
|
||||
assert (asset_dir / "MEMORY.md").exists()
|
||||
assert (asset_dir / "HEARTBEAT.md").exists()
|
||||
assert (asset_dir / "agent.yaml").exists()
|
||||
assert (asset_dir / "skills" / "installed").is_dir()
|
||||
assert (asset_dir / "skills" / "active").is_dir()
|
||||
assert (asset_dir / "skills" / "disabled").is_dir()
|
||||
assert (asset_dir / "skills" / "local").is_dir()
|
||||
|
||||
|
||||
def test_agent_workspace_config_controls_prompt_files(tmp_path, monkeypatch):
|
||||
manager = WorkspaceManager(project_root=tmp_path)
|
||||
manager.initialize_default_assets(
|
||||
config_name="demo",
|
||||
agent_ids=["risk_manager"],
|
||||
analyst_personas={},
|
||||
)
|
||||
asset_dir = tmp_path / "runs" / "demo" / "agents" / "risk_manager"
|
||||
(asset_dir / "SOUL.md").write_text("soul-line", encoding="utf-8")
|
||||
(asset_dir / "PROFILE.md").write_text("profile-line", encoding="utf-8")
|
||||
(asset_dir / "MEMORY.md").write_text("memory-line", encoding="utf-8")
|
||||
(asset_dir / "agent.yaml").write_text(
|
||||
"prompt_files:\n"
|
||||
" - SOUL.md\n"
|
||||
" - MEMORY.md\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
from backend.agents import prompt_factory
|
||||
|
||||
monkeypatch.setattr(
|
||||
prompt_factory,
|
||||
"SkillsManager",
|
||||
lambda: SkillsManager(project_root=tmp_path),
|
||||
)
|
||||
|
||||
prompt = build_agent_system_prompt(
|
||||
agent_id="risk_manager",
|
||||
config_name="demo",
|
||||
toolkit=_DummyToolkit(),
|
||||
)
|
||||
|
||||
assert "soul-line" in prompt
|
||||
assert "memory-line" in prompt
|
||||
assert "profile-line" not in prompt
|
||||
|
||||
|
||||
def test_skills_manager_applies_agent_level_skill_toggles(tmp_path):
|
||||
builtin_root = tmp_path / "backend" / "skills" / "builtin"
|
||||
for skill_name in ("risk_review", "extra_guard"):
|
||||
skill_dir = builtin_root / skill_name
|
||||
skill_dir.mkdir(parents=True, exist_ok=True)
|
||||
(skill_dir / "SKILL.md").write_text(
|
||||
f"# {skill_name}\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
manager = WorkspaceManager(project_root=tmp_path)
|
||||
manager.initialize_default_assets(
|
||||
config_name="demo",
|
||||
agent_ids=["risk_manager"],
|
||||
analyst_personas={},
|
||||
)
|
||||
asset_dir = tmp_path / "runs" / "demo" / "agents" / "risk_manager"
|
||||
(asset_dir / "agent.yaml").write_text(
|
||||
"enabled_skills:\n"
|
||||
" - extra_guard\n"
|
||||
"disabled_skills:\n"
|
||||
" - risk_review\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
skills_manager = SkillsManager(project_root=tmp_path)
|
||||
active_map = skills_manager.prepare_active_skills(
|
||||
config_name="demo",
|
||||
agent_defaults={"risk_manager": ["risk_review"]},
|
||||
)
|
||||
|
||||
active_dirs = active_map["risk_manager"]
|
||||
assert [path.name for path in active_dirs] == ["extra_guard"]
|
||||
assert (asset_dir / "skills" / "installed" / "extra_guard" / "SKILL.md").exists()
|
||||
assert (asset_dir / "skills" / "active" / "extra_guard" / "SKILL.md").exists()
|
||||
assert (asset_dir / "skills" / "disabled" / "risk_review" / "SKILL.md").exists()
|
||||
assert not (asset_dir / "skills" / "active" / "risk_review").exists()
|
||||
|
||||
|
||||
def test_agent_local_skill_is_activated_from_agent_workspace(tmp_path):
|
||||
manager = WorkspaceManager(project_root=tmp_path)
|
||||
manager.initialize_default_assets(
|
||||
config_name="demo",
|
||||
agent_ids=["risk_manager"],
|
||||
analyst_personas={},
|
||||
)
|
||||
asset_dir = tmp_path / "runs" / "demo" / "agents" / "risk_manager"
|
||||
local_skill = asset_dir / "skills" / "local" / "local_guard"
|
||||
local_skill.mkdir(parents=True, exist_ok=True)
|
||||
(local_skill / "SKILL.md").write_text(
|
||||
"---\nname: 本地风控\ndescription: local skill\nversion: 1.0.0\n---\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
skills_manager = SkillsManager(project_root=tmp_path)
|
||||
active_map = skills_manager.prepare_active_skills(
|
||||
config_name="demo",
|
||||
agent_defaults={"risk_manager": []},
|
||||
)
|
||||
|
||||
assert [path.name for path in active_map["risk_manager"]] == ["local_guard"]
|
||||
assert (asset_dir / "skills" / "active" / "local_guard" / "SKILL.md").exists()
|
||||
|
||||
|
||||
def test_prompt_includes_active_skill_metadata_summary(tmp_path, monkeypatch):
|
||||
builtin_root = tmp_path / "backend" / "skills" / "builtin"
|
||||
skill_dir = builtin_root / "extra_guard"
|
||||
skill_dir.mkdir(parents=True, exist_ok=True)
|
||||
(skill_dir / "SKILL.md").write_text(
|
||||
"---\n"
|
||||
"name: extra_guard\n"
|
||||
"description: This skill should be used when the user asks to \"run a risk check\".\n"
|
||||
"version: 1.0.0\n"
|
||||
"tools:\n"
|
||||
" - risk_ops\n"
|
||||
"---\n\n"
|
||||
"# Extra Guard\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
manager = WorkspaceManager(project_root=tmp_path)
|
||||
manager.initialize_default_assets(
|
||||
config_name="demo",
|
||||
agent_ids=["risk_manager"],
|
||||
analyst_personas={},
|
||||
)
|
||||
asset_dir = tmp_path / "runs" / "demo" / "agents" / "risk_manager"
|
||||
(asset_dir / "agent.yaml").write_text(
|
||||
"enabled_skills:\n"
|
||||
" - extra_guard\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
skills_manager = SkillsManager(project_root=tmp_path)
|
||||
skills_manager.prepare_active_skills(
|
||||
config_name="demo",
|
||||
agent_defaults={"risk_manager": []},
|
||||
)
|
||||
|
||||
from backend.agents import prompt_factory
|
||||
|
||||
monkeypatch.setattr(
|
||||
prompt_factory,
|
||||
"SkillsManager",
|
||||
lambda: SkillsManager(project_root=tmp_path),
|
||||
)
|
||||
|
||||
prompt = build_agent_system_prompt(
|
||||
agent_id="risk_manager",
|
||||
config_name="demo",
|
||||
toolkit=_DummyToolkit(),
|
||||
)
|
||||
|
||||
assert "Active Skill Catalog" in prompt
|
||||
assert "This skill should be used when the user asks to \"run a risk check\"." in prompt
|
||||
assert "version: 1.0.0" in prompt
|
||||
assert "risk_ops" not in prompt
|
||||
Reference in New Issue
Block a user