"""Runtime skill resolver。 这层负责回答一个运行时问题: “这一次调用,哪些 skill 要被激活,并以什么形式注入上下文?” 第一版保持保守,只综合三类来源: 1. `always` skills 不在这里做复杂的语义匹配或自动推荐。 """ from __future__ import annotations from dataclasses import dataclass, field from beaver.engine.context import SkillContext from beaver.skills.catalog.loader import SkillsLoader from beaver.skills.catalog.utils import strip_frontmatter @dataclass(slots=True) class ResolvedSkillSet: """一次运行最终解析出的 skills 结果。""" activated_skills: list[SkillContext] = field(default_factory=list) class RuntimeSkillResolver: """把 profile/request 转成当前轮次真正激活的 skill 集合。""" def __init__(self, loader: SkillsLoader) -> None: self.loader = loader def resolve( self, ) -> ResolvedSkillSet: selected: list[str] = [] for name in self.loader.get_always_skills(): if name not in selected: selected.append(name) activated_skills: list[SkillContext] = [] for name in selected: raw_content = self.loader.load_skill(name) content = strip_frontmatter(raw_content).strip() if raw_content else "" if not content: continue activated_skills.append(SkillContext(name=name, content=content)) return ResolvedSkillSet(activated_skills=activated_skills)