mirror of
https://github.com/openai/codex.git
synced 2026-05-05 20:07:02 +00:00
Support SYSTEM skills. (#8220)
1. Remove PUBLIC skills and introduce SYSTEM skills embedded in the binary and installed into $CODEX_HOME/skills/.system at startup. 2. Skills are now always enabled (feature flag removed). 3. Update skills/list to accept forceReload and plumb it through (not used by clients yet).
This commit is contained in:
@@ -2,68 +2,35 @@ use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::RwLock;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
use crate::skills::SkillLoadOutcome;
|
||||
use crate::skills::loader::load_skills_from_roots;
|
||||
use crate::skills::loader::public_skills_root;
|
||||
use crate::skills::loader::repo_skills_root;
|
||||
use crate::skills::loader::system_skills_root;
|
||||
use crate::skills::loader::user_skills_root;
|
||||
use crate::skills::public::refresh_public_skills;
|
||||
use tokio::sync::broadcast;
|
||||
|
||||
use crate::skills::system::install_system_skills;
|
||||
pub struct SkillsManager {
|
||||
codex_home: PathBuf,
|
||||
cache_by_cwd: RwLock<HashMap<PathBuf, SkillLoadOutcome>>,
|
||||
attempted_public_refresh: AtomicBool,
|
||||
skills_update_tx: broadcast::Sender<()>,
|
||||
}
|
||||
|
||||
impl SkillsManager {
|
||||
pub fn new(codex_home: PathBuf) -> Self {
|
||||
let (skills_update_tx, _skills_update_rx) = broadcast::channel(1);
|
||||
if let Err(err) = install_system_skills(&codex_home) {
|
||||
tracing::error!("failed to install system skills: {err}");
|
||||
}
|
||||
|
||||
Self {
|
||||
codex_home,
|
||||
cache_by_cwd: RwLock::new(HashMap::new()),
|
||||
attempted_public_refresh: AtomicBool::new(false),
|
||||
skills_update_tx,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn subscribe_skills_update_notifications(&self) -> broadcast::Receiver<()> {
|
||||
self.skills_update_tx.subscribe()
|
||||
}
|
||||
|
||||
pub fn skills_for_cwd(&self, cwd: &Path) -> SkillLoadOutcome {
|
||||
self.skills_for_cwd_with_options(cwd, false)
|
||||
}
|
||||
|
||||
pub(crate) fn skills_for_cwd_with_options(
|
||||
&self,
|
||||
cwd: &Path,
|
||||
force_reload: bool,
|
||||
) -> SkillLoadOutcome {
|
||||
// Best-effort refresh: attempt at most once per manager instance.
|
||||
if self
|
||||
.attempted_public_refresh
|
||||
.compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
|
||||
.is_ok()
|
||||
{
|
||||
let codex_home = self.codex_home.clone();
|
||||
let skills_update_tx = self.skills_update_tx.clone();
|
||||
std::thread::spawn(move || match refresh_public_skills(&codex_home) {
|
||||
Ok(outcome) => {
|
||||
if outcome.updated() {
|
||||
let _ = skills_update_tx.send(());
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
tracing::error!("failed to refresh public skills: {err}");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn skills_for_cwd_with_options(&self, cwd: &Path, force_reload: bool) -> SkillLoadOutcome {
|
||||
let cached = match self.cache_by_cwd.read() {
|
||||
Ok(cache) => cache.get(cwd).cloned(),
|
||||
Err(err) => err.into_inner().get(cwd).cloned(),
|
||||
@@ -77,7 +44,7 @@ impl SkillsManager {
|
||||
roots.push(repo_root);
|
||||
}
|
||||
roots.push(user_skills_root(&self.codex_home));
|
||||
roots.push(public_skills_root(&self.codex_home));
|
||||
roots.push(system_skills_root(&self.codex_home));
|
||||
let outcome = load_skills_from_roots(roots);
|
||||
match self.cache_by_cwd.write() {
|
||||
Ok(mut cache) => {
|
||||
|
||||
Reference in New Issue
Block a user