mirror of
https://github.com/openai/codex.git
synced 2026-11-02 19:43:24 +00:00
## Disclaimer This is only here for iteration purpose! Do not make any code rely on this ## Why Skills still live behind `codex-core` discovery and injection paths, but the extension system needs an authority-aware home before that logic can move. This adds that boundary without changing current skills behavior, and keeps host, executor, and remote skills distinct so future list/read/search flows do not collapse back to ambient local paths. ## What changed - Add the `codex-skills-extension` workspace/Bazel crate under `ext/skills`. - Define the initial catalog, authority, provider, and turn-state types for authority-bound skill packages and resources. - Register placeholder thread/config/prompt/turn lifecycle contributors plus host, executor, and remote provider aggregation points. - Capture the remaining extraction work as TODOs, including the missing extension API hooks needed for per-turn catalog construction and typed skill injection. - Keep plugins outside the runtime skills model: plugin-installed skills are treated as materialized host-owned skill sources once available. ## Verification - Not run locally.
87 lines
2.4 KiB
Rust
87 lines
2.4 KiB
Rust
/// Source authority that owns a skill package and must be used to read it.
|
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
|
pub enum SkillSourceKind {
|
|
Host,
|
|
Executor,
|
|
Remote,
|
|
}
|
|
|
|
/// Opaque authority identity for list/read routing.
|
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
|
pub struct SkillAuthority {
|
|
pub kind: SkillSourceKind,
|
|
pub id: String,
|
|
}
|
|
|
|
impl SkillAuthority {
|
|
pub fn new(kind: SkillSourceKind, id: impl Into<String>) -> Self {
|
|
Self {
|
|
kind,
|
|
id: id.into(),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Opaque package id. Callers should not parse local paths out of this value.
|
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
|
pub struct SkillPackageId(pub String);
|
|
|
|
/// Opaque resource id inside a skill package.
|
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
|
pub struct SkillResourceId(pub String);
|
|
|
|
/// Metadata shown in the always-visible skills catalog.
|
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
pub struct SkillCatalogEntry {
|
|
pub id: SkillPackageId,
|
|
pub authority: SkillAuthority,
|
|
pub name: String,
|
|
pub description: String,
|
|
pub entrypoint: SkillResourceId,
|
|
}
|
|
|
|
/// Merged catalog for one turn.
|
|
#[derive(Clone, Debug, Default, PartialEq, Eq)]
|
|
pub struct SkillCatalog {
|
|
pub entries: Vec<SkillCatalogEntry>,
|
|
pub warnings: Vec<String>,
|
|
}
|
|
|
|
impl SkillCatalog {
|
|
pub fn extend(&mut self, other: SkillCatalog) {
|
|
// TODO(skills-extension): dedupe by authority-bound id first, then
|
|
// apply name precedence/conflict rules for user-facing mention
|
|
// resolution. Names are not stable identities.
|
|
self.entries.extend(other.entries);
|
|
self.warnings.extend(other.warnings);
|
|
}
|
|
}
|
|
|
|
/// Contents returned after resolving a skill resource through its owner.
|
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
pub struct SkillReadResult {
|
|
pub resource: SkillResourceId,
|
|
pub contents: String,
|
|
}
|
|
|
|
/// Search results for a package whose files are not readable through ordinary
|
|
/// executor filesystem access.
|
|
#[derive(Clone, Debug, Default, PartialEq, Eq)]
|
|
pub struct SkillSearchResult {
|
|
pub matches: Vec<SkillSearchMatch>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
pub struct SkillSearchMatch {
|
|
pub resource: SkillResourceId,
|
|
pub title: String,
|
|
pub snippet: String,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
pub struct SkillProviderError {
|
|
pub message: String,
|
|
}
|
|
|
|
pub type SkillProviderResult<T> = Result<T, SkillProviderError>;
|