mirror of
https://github.com/openai/codex.git
synced 2026-04-30 01:16:54 +00:00
Support enable/disable skill via config/api. (#9328)
In config.toml: ``` [[skills.config]] path = "/Users/xl/.codex/skills/my_skill/SKILL.md" enabled = false ``` API: skills/list, skills/config/write
This commit is contained in:
@@ -85,6 +85,8 @@ use codex_app_server_protocol::ServerNotification;
|
||||
use codex_app_server_protocol::SessionConfiguredNotification;
|
||||
use codex_app_server_protocol::SetDefaultModelParams;
|
||||
use codex_app_server_protocol::SetDefaultModelResponse;
|
||||
use codex_app_server_protocol::SkillsConfigWriteParams;
|
||||
use codex_app_server_protocol::SkillsConfigWriteResponse;
|
||||
use codex_app_server_protocol::SkillsListParams;
|
||||
use codex_app_server_protocol::SkillsListResponse;
|
||||
use codex_app_server_protocol::Thread;
|
||||
@@ -131,6 +133,7 @@ use codex_core::auth::login_with_api_key;
|
||||
use codex_core::config::Config;
|
||||
use codex_core::config::ConfigOverrides;
|
||||
use codex_core::config::ConfigService;
|
||||
use codex_core::config::edit::ConfigEdit;
|
||||
use codex_core::config::edit::ConfigEditsBuilder;
|
||||
use codex_core::config::types::McpServerTransportConfig;
|
||||
use codex_core::default_client::get_codex_user_agent;
|
||||
@@ -400,6 +403,9 @@ impl CodexMessageProcessor {
|
||||
ClientRequest::SkillsList { request_id, params } => {
|
||||
self.skills_list(request_id, params).await;
|
||||
}
|
||||
ClientRequest::SkillsConfigWrite { request_id, params } => {
|
||||
self.skills_config_write(request_id, params).await;
|
||||
}
|
||||
ClientRequest::TurnStart { request_id, params } => {
|
||||
self.turn_start(request_id, params).await;
|
||||
}
|
||||
@@ -3246,7 +3252,7 @@ impl CodexMessageProcessor {
|
||||
for cwd in cwds {
|
||||
let outcome = skills_manager.skills_for_cwd(&cwd, force_reload).await;
|
||||
let errors = errors_to_info(&outcome.errors);
|
||||
let skills = skills_to_info(&outcome.skills);
|
||||
let skills = skills_to_info(&outcome.skills, &outcome.disabled_paths);
|
||||
data.push(codex_app_server_protocol::SkillsListEntry {
|
||||
cwd,
|
||||
skills,
|
||||
@@ -3258,6 +3264,37 @@ impl CodexMessageProcessor {
|
||||
.await;
|
||||
}
|
||||
|
||||
async fn skills_config_write(&self, request_id: RequestId, params: SkillsConfigWriteParams) {
|
||||
let SkillsConfigWriteParams { path, enabled } = params;
|
||||
let edits = vec![ConfigEdit::SetSkillConfig { path, enabled }];
|
||||
let result = ConfigEditsBuilder::new(&self.config.codex_home)
|
||||
.with_edits(edits)
|
||||
.apply()
|
||||
.await;
|
||||
|
||||
match result {
|
||||
Ok(()) => {
|
||||
self.thread_manager.skills_manager().clear_cache();
|
||||
self.outgoing
|
||||
.send_response(
|
||||
request_id,
|
||||
SkillsConfigWriteResponse {
|
||||
effective_enabled: enabled,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
}
|
||||
Err(err) => {
|
||||
let error = JSONRPCErrorError {
|
||||
code: INTERNAL_ERROR_CODE,
|
||||
message: format!("failed to update skill settings: {err}"),
|
||||
data: None,
|
||||
};
|
||||
self.outgoing.send_error(request_id, error).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn interrupt_conversation(
|
||||
&mut self,
|
||||
request_id: RequestId,
|
||||
@@ -3918,25 +3955,30 @@ impl CodexMessageProcessor {
|
||||
|
||||
fn skills_to_info(
|
||||
skills: &[codex_core::skills::SkillMetadata],
|
||||
disabled_paths: &std::collections::HashSet<PathBuf>,
|
||||
) -> Vec<codex_app_server_protocol::SkillMetadata> {
|
||||
skills
|
||||
.iter()
|
||||
.map(|skill| codex_app_server_protocol::SkillMetadata {
|
||||
name: skill.name.clone(),
|
||||
description: skill.description.clone(),
|
||||
short_description: skill.short_description.clone(),
|
||||
interface: skill.interface.clone().map(|interface| {
|
||||
codex_app_server_protocol::SkillInterface {
|
||||
display_name: interface.display_name,
|
||||
short_description: interface.short_description,
|
||||
icon_small: interface.icon_small,
|
||||
icon_large: interface.icon_large,
|
||||
brand_color: interface.brand_color,
|
||||
default_prompt: interface.default_prompt,
|
||||
}
|
||||
}),
|
||||
path: skill.path.clone(),
|
||||
scope: skill.scope.into(),
|
||||
.map(|skill| {
|
||||
let enabled = !disabled_paths.contains(&skill.path);
|
||||
codex_app_server_protocol::SkillMetadata {
|
||||
name: skill.name.clone(),
|
||||
description: skill.description.clone(),
|
||||
short_description: skill.short_description.clone(),
|
||||
interface: skill.interface.clone().map(|interface| {
|
||||
codex_app_server_protocol::SkillInterface {
|
||||
display_name: interface.display_name,
|
||||
short_description: interface.short_description,
|
||||
icon_small: interface.icon_small,
|
||||
icon_large: interface.icon_large,
|
||||
brand_color: interface.brand_color,
|
||||
default_prompt: interface.default_prompt,
|
||||
}
|
||||
}),
|
||||
path: skill.path.clone(),
|
||||
scope: skill.scope.into(),
|
||||
enabled,
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user