mirror of
https://github.com/openai/codex.git
synced 2026-11-13 14:46:14 +00:00
Enable resource reads for explicit executor skills (#35198)
## Why Executor skills that disallow implicit invocation are omitted from `skills.list`, so an explicitly selected skill did not provide the authority and package identifiers needed to read its referenced resources. ## What changed - Add `resource_access` metadata to injected instructions for explicit-only executor skills. - Teach the `skills.read` description to accept that metadata as well as values returned by `skills.list`. - Keep discoverable executor skill instructions unchanged. ## Testing Add an app-server integration scenario that selects an explicit-only executor skill, confirms it remains absent from `skills.list`, and reads a referenced file through `skills.read`. GitOrigin-RevId: 97d3b93d1618c013363788452303c8a31e32cc56
This commit is contained in:
1 parent
5f6a2c3adb
commit
fe8500c0a0
4 files changed
+166
-66
No files matched your search
@@ -36,6 +36,7 @@ use crate::catalog::SkillCatalogEntry;
|
||||
use crate::catalog::SkillReadResult;
|
||||
use crate::catalog::SkillSourceKind;
|
||||
use crate::fragments::AvailableSkillsInstructions;
|
||||
use crate::fragments::ExecutorSkillResourceAccess;
|
||||
use crate::fragments::SkillInstructions;
|
||||
use crate::provider::HostSkillProvider;
|
||||
use crate::provider::SkillListQuery;
|
||||
@@ -464,6 +465,13 @@ where
|
||||
)
|
||||
.0,
|
||||
contents,
|
||||
executor_resource_access: (!entry.prompt_visible
|
||||
&& entry.authority.kind == SkillSourceKind::Executor)
|
||||
.then(|| ExecutorSkillResourceAccess {
|
||||
authority_id: entry.authority.id.clone(),
|
||||
package: entry.id.0.clone(),
|
||||
main_resource: entry.main_prompt.as_str().to_string(),
|
||||
}),
|
||||
};
|
||||
fragments.push(Box::new(fragment));
|
||||
main_prompts_injected = true;
|
||||
|
||||
@@ -77,6 +77,14 @@ pub(crate) struct SkillInstructions {
|
||||
pub(crate) name: String,
|
||||
pub(crate) path: String,
|
||||
pub(crate) contents: String,
|
||||
pub(crate) executor_resource_access: Option<ExecutorSkillResourceAccess>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub(crate) struct ExecutorSkillResourceAccess {
|
||||
pub(crate) authority_id: String,
|
||||
pub(crate) package: String,
|
||||
pub(crate) main_resource: String,
|
||||
}
|
||||
|
||||
impl ContextualUserFragment for SkillInstructions {
|
||||
@@ -96,6 +104,21 @@ impl ContextualUserFragment for SkillInstructions {
|
||||
let name = &self.name;
|
||||
let path = &self.path;
|
||||
let contents = &self.contents;
|
||||
format!("\n<name>{name}</name>\n<path>{path}</path>\n{contents}\n")
|
||||
let resource_access = self
|
||||
.executor_resource_access
|
||||
.as_ref()
|
||||
.map(|access| {
|
||||
let metadata = serde_json::json!({
|
||||
"authority": {
|
||||
"kind": "executor",
|
||||
"id": access.authority_id,
|
||||
},
|
||||
"package": access.package,
|
||||
"main_resource": access.main_resource,
|
||||
});
|
||||
format!("\n<resource_access>{metadata}</resource_access>")
|
||||
})
|
||||
.unwrap_or_default();
|
||||
format!("\n<name>{name}</name>\n<path>{path}</path>{resource_access}\n{contents}\n")
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,7 @@ impl ToolExecutor<ToolCall> for ReadTool {
|
||||
fn spec(&self) -> ToolSpec {
|
||||
skill_function_tool::<ReadArgs, ReadResponse>(
|
||||
TOOL_NAME,
|
||||
"Read one page from a skill resource. Pass the exact authority and package from skills.list, plus its main_resource or a referenced resource beneath that package. Pass next_cursor back as cursor to continue.",
|
||||
"Read one page from a skill resource. Pass the exact authority and package from skills.list or an explicitly selected skill's resource_access metadata, plus its main_resource or a referenced resource beneath that package. Pass next_cursor back as cursor to continue.",
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user