mirror of
https://github.com/openai/codex.git
synced 2026-11-13 14:46:14 +00:00
feat: namespace in ext (#22556)
This commit is contained in:
1 parent
23bb524973
commit
e6939e3969
10 files changed
+128
-73
No files matched your search
@@ -12,9 +12,10 @@ pub(crate) const DEFAULT_SEARCH_MAX_RESULTS: usize = 200;
|
||||
pub(crate) const MAX_SEARCH_RESULTS: usize = 200;
|
||||
pub(crate) const DEFAULT_READ_MAX_TOKENS: usize = 20_000;
|
||||
|
||||
pub(crate) const LIST_TOOL_NAME: &str = "memory_list";
|
||||
pub(crate) const READ_TOOL_NAME: &str = "memory_read";
|
||||
pub(crate) const SEARCH_TOOL_NAME: &str = "memory_search";
|
||||
pub(crate) const MEMORY_TOOLS_NAMESPACE: &str = "memories/";
|
||||
pub(crate) const LIST_TOOL_NAME: &str = "list";
|
||||
pub(crate) const READ_TOOL_NAME: &str = "read";
|
||||
pub(crate) const SEARCH_TOOL_NAME: &str = "search";
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
@@ -62,15 +62,15 @@ fn tools_are_contributed_when_enabled() {
|
||||
let tool_names = extension
|
||||
.tools(&ExtensionData::new("session"), &thread_store)
|
||||
.into_iter()
|
||||
.map(|tool| tool.tool_name().to_string())
|
||||
.map(|tool| tool.tool_name())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
assert_eq!(
|
||||
tool_names,
|
||||
vec![
|
||||
"memory_list".to_string(),
|
||||
"memory_read".to_string(),
|
||||
"memory_search".to_string()
|
||||
memory_tool_name(crate::LIST_TOOL_NAME),
|
||||
memory_tool_name(crate::READ_TOOL_NAME),
|
||||
memory_tool_name(crate::SEARCH_TOOL_NAME),
|
||||
]
|
||||
);
|
||||
}
|
||||
@@ -135,7 +135,7 @@ async fn read_tool_reads_memory_file() {
|
||||
let output = tool
|
||||
.handle(ToolCall {
|
||||
call_id: "call-1".to_string(),
|
||||
tool_name: ToolName::plain(crate::READ_TOOL_NAME),
|
||||
tool_name: memory_tool_name(crate::READ_TOOL_NAME),
|
||||
payload: payload.clone(),
|
||||
})
|
||||
.await
|
||||
@@ -177,7 +177,7 @@ async fn search_tool_accepts_multiple_queries() {
|
||||
let output = tool
|
||||
.handle(ToolCall {
|
||||
call_id: "call-1".to_string(),
|
||||
tool_name: ToolName::plain(crate::SEARCH_TOOL_NAME),
|
||||
tool_name: memory_tool_name(crate::SEARCH_TOOL_NAME),
|
||||
payload: payload.clone(),
|
||||
})
|
||||
.await
|
||||
@@ -245,7 +245,7 @@ async fn search_tool_accepts_windowed_all_match_mode() {
|
||||
let output = tool
|
||||
.handle(ToolCall {
|
||||
call_id: "call-1".to_string(),
|
||||
tool_name: ToolName::plain(crate::SEARCH_TOOL_NAME),
|
||||
tool_name: memory_tool_name(crate::SEARCH_TOOL_NAME),
|
||||
payload: payload.clone(),
|
||||
})
|
||||
.await
|
||||
@@ -293,7 +293,7 @@ async fn search_tool_rejects_legacy_single_query() {
|
||||
let err = tool
|
||||
.handle(ToolCall {
|
||||
call_id: "call-1".to_string(),
|
||||
tool_name: ToolName::plain(crate::SEARCH_TOOL_NAME),
|
||||
tool_name: memory_tool_name(crate::SEARCH_TOOL_NAME),
|
||||
payload,
|
||||
})
|
||||
.await
|
||||
@@ -304,8 +304,13 @@ async fn search_tool_rejects_legacy_single_query() {
|
||||
}
|
||||
|
||||
fn memory_tool(memory_root: &Path, tool_name: &str) -> Arc<dyn ExtensionToolExecutor> {
|
||||
let expected_tool_name = memory_tool_name(tool_name);
|
||||
crate::tools::memory_tools(LocalMemoriesBackend::from_memory_root(memory_root))
|
||||
.into_iter()
|
||||
.find(|tool| tool.tool_name().to_string() == tool_name)
|
||||
.find(|tool| tool.tool_name() == expected_tool_name)
|
||||
.unwrap_or_else(|| panic!("{tool_name} tool should be registered"))
|
||||
}
|
||||
|
||||
fn memory_tool_name(tool_name: &str) -> ToolName {
|
||||
ToolName::namespaced(crate::MEMORY_TOOLS_NAMESPACE, tool_name)
|
||||
}
|
||||
@@ -17,7 +17,8 @@ use crate::backend::MemoriesBackend;
|
||||
|
||||
use super::backend_error_to_function_call;
|
||||
use super::clamp_max_results;
|
||||
use super::function_tool;
|
||||
use super::memory_function_tool;
|
||||
use super::memory_tool_name;
|
||||
use super::parse_args;
|
||||
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
@@ -39,11 +40,11 @@ where
|
||||
B: MemoriesBackend,
|
||||
{
|
||||
fn tool_name(&self) -> ToolName {
|
||||
ToolName::plain(LIST_TOOL_NAME)
|
||||
memory_tool_name(LIST_TOOL_NAME)
|
||||
}
|
||||
|
||||
fn spec(&self) -> Option<ToolSpec> {
|
||||
Some(function_tool::<ListArgs, ListMemoriesResponse>(
|
||||
Some(memory_function_tool::<ListArgs, ListMemoriesResponse>(
|
||||
LIST_TOOL_NAME,
|
||||
"List immediate files and directories under a path in the Codex memories store.",
|
||||
))
|
||||
|
||||
@@ -4,12 +4,17 @@ use codex_extension_api::ExtensionToolExecutor;
|
||||
use codex_extension_api::FunctionCallError;
|
||||
use codex_extension_api::ResponsesApiTool;
|
||||
use codex_extension_api::ToolCall;
|
||||
use codex_extension_api::ToolName;
|
||||
use codex_extension_api::ToolSpec;
|
||||
use codex_extension_api::parse_tool_input_schema;
|
||||
use codex_tools::ResponsesApiNamespace;
|
||||
use codex_tools::ResponsesApiNamespaceTool;
|
||||
use codex_tools::default_namespace_description;
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::MEMORY_TOOLS_NAMESPACE;
|
||||
use crate::backend::MemoriesBackend;
|
||||
use crate::backend::MemoriesBackendError;
|
||||
use crate::schema;
|
||||
@@ -33,8 +38,15 @@ where
|
||||
]
|
||||
}
|
||||
|
||||
fn function_tool<I: JsonSchema, O: JsonSchema>(name: &str, description: &str) -> ToolSpec {
|
||||
ToolSpec::Function(ResponsesApiTool {
|
||||
pub(super) fn memory_tool_name(name: &str) -> ToolName {
|
||||
ToolName::namespaced(MEMORY_TOOLS_NAMESPACE, name)
|
||||
}
|
||||
|
||||
pub(super) fn memory_function_tool<I: JsonSchema, O: JsonSchema>(
|
||||
name: &str,
|
||||
description: &str,
|
||||
) -> ToolSpec {
|
||||
let tool = ResponsesApiTool {
|
||||
name: name.to_string(),
|
||||
description: description.to_string(),
|
||||
strict: false,
|
||||
@@ -42,6 +54,12 @@ fn function_tool<I: JsonSchema, O: JsonSchema>(name: &str, description: &str) ->
|
||||
parameters: parse_tool_input_schema(&schema::input_schema_for::<I>())
|
||||
.unwrap_or_else(|err| panic!("generated input schema for {name} should parse: {err}")),
|
||||
output_schema: Some(schema::output_schema_for::<O>()),
|
||||
};
|
||||
|
||||
ToolSpec::Namespace(ResponsesApiNamespace {
|
||||
name: MEMORY_TOOLS_NAMESPACE.to_string(),
|
||||
description: default_namespace_description(MEMORY_TOOLS_NAMESPACE),
|
||||
tools: vec![ResponsesApiNamespaceTool::Function(tool)],
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@ use crate::backend::ReadMemoryRequest;
|
||||
use crate::backend::ReadMemoryResponse;
|
||||
|
||||
use super::backend_error_to_function_call;
|
||||
use super::function_tool;
|
||||
use super::memory_function_tool;
|
||||
use super::memory_tool_name;
|
||||
use super::parse_args;
|
||||
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
@@ -38,11 +39,11 @@ where
|
||||
B: MemoriesBackend,
|
||||
{
|
||||
fn tool_name(&self) -> ToolName {
|
||||
ToolName::plain(READ_TOOL_NAME)
|
||||
memory_tool_name(READ_TOOL_NAME)
|
||||
}
|
||||
|
||||
fn spec(&self) -> Option<ToolSpec> {
|
||||
Some(function_tool::<ReadArgs, ReadMemoryResponse>(
|
||||
Some(memory_function_tool::<ReadArgs, ReadMemoryResponse>(
|
||||
READ_TOOL_NAME,
|
||||
"Read a Codex memory file by relative path, optionally starting at a 1-indexed line offset and limiting the number of lines returned.",
|
||||
))
|
||||
|
||||
@@ -18,7 +18,8 @@ use crate::backend::SearchMemoriesResponse;
|
||||
|
||||
use super::backend_error_to_function_call;
|
||||
use super::clamp_max_results;
|
||||
use super::function_tool;
|
||||
use super::memory_function_tool;
|
||||
use super::memory_tool_name;
|
||||
use super::parse_args;
|
||||
|
||||
#[derive(Debug, Deserialize, JsonSchema)]
|
||||
@@ -47,11 +48,11 @@ where
|
||||
B: MemoriesBackend,
|
||||
{
|
||||
fn tool_name(&self) -> ToolName {
|
||||
ToolName::plain(SEARCH_TOOL_NAME)
|
||||
memory_tool_name(SEARCH_TOOL_NAME)
|
||||
}
|
||||
|
||||
fn spec(&self) -> Option<ToolSpec> {
|
||||
Some(function_tool::<SearchArgs, SearchMemoriesResponse>(
|
||||
Some(memory_function_tool::<SearchArgs, SearchMemoriesResponse>(
|
||||
SEARCH_TOOL_NAME,
|
||||
"Search Codex memory files for substring matches, optionally normalizing separators or requiring all query substrings on the same line or within a line window.",
|
||||
))
|
||||
|
||||
Reference in new issue
Block a user