mirror of
https://github.com/openai/codex.git
synced 2026-04-30 19:32:04 +03:00
Inject SKILL.md when it's explicitly mentioned. (#7763)
1. Skills load once in core at session start; the cached outcome is reused across core and surfaced to TUI via SessionConfigured. 2. TUI detects explicit skill selections, and core injects the matching SKILL.md content into the turn when a selected skill is present.
This commit is contained in:
@@ -300,36 +300,37 @@ impl From<Vec<UserInput>> for ResponseInputItem {
|
||||
role: "user".to_string(),
|
||||
content: items
|
||||
.into_iter()
|
||||
.map(|c| match c {
|
||||
UserInput::Text { text } => ContentItem::InputText { text },
|
||||
UserInput::Image { image_url } => ContentItem::InputImage { image_url },
|
||||
.filter_map(|c| match c {
|
||||
UserInput::Text { text } => Some(ContentItem::InputText { text }),
|
||||
UserInput::Image { image_url } => Some(ContentItem::InputImage { image_url }),
|
||||
UserInput::LocalImage { path } => match load_and_resize_to_fit(&path) {
|
||||
Ok(image) => ContentItem::InputImage {
|
||||
Ok(image) => Some(ContentItem::InputImage {
|
||||
image_url: image.into_data_url(),
|
||||
},
|
||||
}),
|
||||
Err(err) => {
|
||||
if matches!(&err, ImageProcessingError::Read { .. }) {
|
||||
local_image_error_placeholder(&path, &err)
|
||||
Some(local_image_error_placeholder(&path, &err))
|
||||
} else if err.is_invalid_image() {
|
||||
invalid_image_error_placeholder(&path, &err)
|
||||
Some(invalid_image_error_placeholder(&path, &err))
|
||||
} else {
|
||||
let Some(mime_guess) = mime_guess::from_path(&path).first() else {
|
||||
return local_image_error_placeholder(
|
||||
return Some(local_image_error_placeholder(
|
||||
&path,
|
||||
"unsupported MIME type (unknown)",
|
||||
);
|
||||
));
|
||||
};
|
||||
let mime = mime_guess.essence_str().to_owned();
|
||||
if !mime.starts_with("image/") {
|
||||
return local_image_error_placeholder(
|
||||
return Some(local_image_error_placeholder(
|
||||
&path,
|
||||
format!("unsupported MIME type `{mime}`"),
|
||||
);
|
||||
));
|
||||
}
|
||||
unsupported_image_error_placeholder(&path, &mime)
|
||||
Some(unsupported_image_error_placeholder(&path, &mime))
|
||||
}
|
||||
}
|
||||
},
|
||||
UserInput::Skill { .. } => None, // Skill bodies are injected later in core
|
||||
})
|
||||
.collect::<Vec<ContentItem>>(),
|
||||
}
|
||||
|
||||
@@ -1624,6 +1624,25 @@ pub struct ListCustomPromptsResponseEvent {
|
||||
pub custom_prompts: Vec<CustomPrompt>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||
pub struct SkillInfo {
|
||||
pub name: String,
|
||||
pub description: String,
|
||||
pub path: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||
pub struct SkillErrorInfo {
|
||||
pub path: PathBuf,
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS, Default)]
|
||||
pub struct SkillLoadOutcomeInfo {
|
||||
pub skills: Vec<SkillInfo>,
|
||||
pub errors: Vec<SkillErrorInfo>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||
pub struct SessionConfiguredEvent {
|
||||
/// Name left as session_id instead of conversation_id for backwards compatibility.
|
||||
@@ -1659,6 +1678,9 @@ pub struct SessionConfiguredEvent {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub initial_messages: Option<Vec<EventMsg>>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub skill_load_outcome: Option<SkillLoadOutcomeInfo>,
|
||||
|
||||
pub rollout_path: PathBuf,
|
||||
}
|
||||
|
||||
@@ -1786,6 +1808,7 @@ mod tests {
|
||||
history_log_id: 0,
|
||||
history_entry_count: 0,
|
||||
initial_messages: None,
|
||||
skill_load_outcome: None,
|
||||
rollout_path: rollout_file.path().to_path_buf(),
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -21,4 +21,10 @@ pub enum UserInput {
|
||||
LocalImage {
|
||||
path: std::path::PathBuf,
|
||||
},
|
||||
|
||||
/// Skill selected by the user (name + path to SKILL.md).
|
||||
Skill {
|
||||
name: String,
|
||||
path: std::path::PathBuf,
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user