修改skill加载机制

This commit is contained in:
xiaoski 2026-05-15 10:39:35 +08:00
parent c92b07f2c6
commit 7a30848f65

View File

@ -55,7 +55,7 @@ impl SkillsLoader {
let home = dirs::home_dir().unwrap_or_else(|| PathBuf::from("."));
Self {
picobot_skills_dir: home.join(".picobot/skills"),
agent_skills_dir: home.join(".agent/skills"),
agent_skills_dir: home.join(".agents/skills"),
workspace_skills_dir: None,
state: Arc::new(Mutex::new(SkillsState::default())),
}
@ -76,7 +76,9 @@ impl SkillsLoader {
self.workspace_skills_dir = Some(workspace_path.join("skills"));
}
/// Load all skills from both directories and record modification times
/// Load all skills from all directories and record modification times.
/// Priority: workspace > ~/.picobot/skills > ~/.agents/skills.
/// Same-name skills from higher-priority directories replace lower-priority ones.
pub fn load_skills(&self) {
let mut state = self.state.lock().unwrap();
state.loaded_skills.clear();
@ -90,19 +92,7 @@ impl SkillsLoader {
}
}
// Load from ~/.picobot/skills
if self.picobot_skills_dir.exists() {
let loaded = self.load_skills_from_dir(&self.picobot_skills_dir);
tracing::debug!(
dir = %self.picobot_skills_dir.display(),
count = loaded.len(),
"Loaded skills from picobot directory"
);
state.loaded_skills.extend(loaded);
state.last_picobot_mtime = Self::get_dir_mtime(&self.picobot_skills_dir);
}
// Load from ~/.agent/skills
// Load from ~/.agents/skills (lowest priority)
if self.agent_skills_dir.exists() {
let loaded = self.load_skills_from_dir(&self.agent_skills_dir);
tracing::debug!(
@ -114,16 +104,48 @@ impl SkillsLoader {
state.last_agent_mtime = Self::get_dir_mtime(&self.agent_skills_dir);
}
// Load from workspace ./skills (if set)
// Load from ~/.picobot/skills (medium priority) — replace same-name skills
if self.picobot_skills_dir.exists() {
let loaded = self.load_skills_from_dir(&self.picobot_skills_dir);
let count = loaded.len();
let mut replaced = 0usize;
for skill in loaded {
if let Some(existing) = state.loaded_skills.iter_mut().find(|s| s.name == skill.name) {
*existing = skill;
replaced += 1;
} else {
state.loaded_skills.push(skill);
}
}
tracing::debug!(
dir = %self.picobot_skills_dir.display(),
count = count,
replaced = replaced,
"Loaded skills from picobot directory"
);
state.last_picobot_mtime = Self::get_dir_mtime(&self.picobot_skills_dir);
}
// Load from workspace skills dir (highest priority) — replace same-name skills
if let Some(ref ws_dir) = self.workspace_skills_dir
&& ws_dir.exists() {
let loaded = self.load_skills_from_dir(ws_dir);
let count = loaded.len();
let mut replaced = 0usize;
for skill in loaded {
if let Some(existing) = state.loaded_skills.iter_mut().find(|s| s.name == skill.name) {
*existing = skill;
replaced += 1;
} else {
state.loaded_skills.push(skill);
}
}
tracing::debug!(
dir = %ws_dir.display(),
count = loaded.len(),
count = count,
replaced = replaced,
"Loaded skills from workspace directory"
);
state.loaded_skills.extend(loaded);
state.last_workspace_mtime = Self::get_dir_mtime(ws_dir);
}
@ -245,10 +267,10 @@ impl SkillsLoader {
// Directory conventions
prompt.push_str("### 目录说明\n\n");
prompt.push_str("- `~/.agent/skills/` — 外部共享 skill 目录(第三方、系统级 skill\n");
prompt.push_str("- `~/.agents/skills/` — 外部共享 skill 目录(第三方、系统级 skill\n");
prompt.push_str("- `~/.picobot/skills/` — 安装 skill 的默认目录\n");
prompt.push_str("- `./skills/` — 工作目录下的 skillpicobot 自行创建的 skill 存放于此\n\n");
prompt.push_str("安装或创建 skill 时请按上述目录规范存放\n\n");
prompt.push_str("- `{workspace}/skills/` — 工作目录下的 skillpicobot 自行创建的 skill 存放于此\n\n");
prompt.push_str("安装或创建 skill 时请按上述目录规范存放创建skill时不要和已有skill同名\n\n");
// Always skills summary
let always_skills: Vec<_> = state.loaded_skills.iter().filter(|s| s.always).collect();