Files
xuhdandClaude Opus 4.7 f80a00e211 feat(skills): curator 面板加 pinned 计数 + 运行时输出技能名日志
- get_curator_status 的 agent_created_skills 增加 pinned 计数,与
  active/stale/archived 正交;前端技能进化面板同步展示「被钉住」一项
  (curator/types.ts、skill-evolution-panel.tsx、zh-CN/en-US/types i18n)。
- run_curator_review 每次运行时把涉及的技能名输出到日志:新增
  _log_scanned_skills(扫描到的技能名)与 _candidate_skill_names
  (候选技能名),logger 与 curator_log 双写。

新增 test_curator_status_counts.py、test_curator_skill_logging.py。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 15:25:13 +08:00

57 lines
2.2 KiB
Python

"""技能进化运行时把涉及的技能名输出到日志。"""
from __future__ import annotations
import logging
from deerflow.skills import curator
_CURATOR_LOGGER = "deerflow.skills.curator"
class TestCandidateSkillNames:
def test_extracts_names_from_candidate_lines(self):
text = "- alpha [state=active, use=1]\n- beta-skill [state=stale, use=0]"
assert curator._candidate_skill_names(text) == ["alpha", "beta-skill"]
def test_ignores_non_candidate_lines(self):
# _render_candidate_list 无候选时返回的提示文本不应被误识别为技能名
assert curator._candidate_skill_names("No agent-created active skills found.") == []
def test_empty(self):
assert curator._candidate_skill_names("") == []
class TestLogScannedSkills:
def _patch_common(self, monkeypatch, entries: dict, owned=None) -> None:
monkeypatch.setattr(curator, "_list_user_owned_skill_names", lambda uid: owned)
monkeypatch.setattr("deerflow.skills.usage.agent_created_entries", lambda: entries)
monkeypatch.setattr("deerflow.skills.curator_log.record", lambda *a, **k: None)
def test_logs_and_returns_sorted_skill_names(self, monkeypatch, caplog):
self._patch_common(
monkeypatch,
{"zeta": {"source": "agent"}, "alpha": {"source": "agent"}},
)
with caplog.at_level(logging.INFO, logger=_CURATOR_LOGGER):
names = curator._log_scanned_skills("u1")
assert names == ["alpha", "zeta"]
assert "alpha" in caplog.text
assert "zeta" in caplog.text
def test_filters_to_owned_skills(self, monkeypatch, caplog):
self._patch_common(
monkeypatch,
{"alpha": {"source": "agent"}, "beta": {"source": "agent"}},
owned={"alpha"},
)
with caplog.at_level(logging.INFO, logger=_CURATOR_LOGGER):
names = curator._log_scanned_skills("u1")
assert names == ["alpha"]
def test_empty_skills(self, monkeypatch, caplog):
self._patch_common(monkeypatch, {})
with caplog.at_level(logging.INFO, logger=_CURATOR_LOGGER):
names = curator._log_scanned_skills("u1")
assert names == []