From ba6678ca9a3475a59fc4b8124d037deb85c4a78d Mon Sep 17 00:00:00 2001 From: jif-oai Date: Thu, 28 May 2026 14:06:21 +0200 Subject: [PATCH] Fix memories namespace for Responses API tools (#24898) ## Why Dedicated memories tools are exposed through a Responses API namespace tool. The namespace itself has to be a valid tool identifier, so `memories/` can fail validation before the model ever gets a chance to call the memory tools. ## What changed - Changed `MEMORY_TOOLS_NAMESPACE` from `memories/` to `memories`. - Added `memory_tool_namespace_matches_responses_api_identifier` so the namespace stays non-empty and limited to Responses-safe identifier characters. ## Verification - Added unit coverage for the namespace identifier shape in `codex-rs/ext/memories/src/tests.rs`. --- codex-rs/ext/memories/src/lib.rs | 2 +- codex-rs/ext/memories/src/metrics.rs | 2 +- codex-rs/ext/memories/src/tests.rs | 10 ++++++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/codex-rs/ext/memories/src/lib.rs b/codex-rs/ext/memories/src/lib.rs index d17c4c495..25120c7a3 100644 --- a/codex-rs/ext/memories/src/lib.rs +++ b/codex-rs/ext/memories/src/lib.rs @@ -15,7 +15,7 @@ pub(crate) const MAX_SEARCH_RESULTS: usize = 200; pub(crate) const DEFAULT_READ_MAX_TOKENS: usize = 20_000; pub(crate) const MEMORY_TOOL_DEVELOPER_INSTRUCTIONS_SUMMARY_TOKEN_LIMIT: usize = 2_500; -pub(crate) const MEMORY_TOOLS_NAMESPACE: &str = "memories/"; +pub(crate) const MEMORY_TOOLS_NAMESPACE: &str = "memories"; pub(crate) const ADD_AD_HOC_NOTE_TOOL_NAME: &str = "add_ad_hoc_note"; pub(crate) const LIST_TOOL_NAME: &str = "list"; pub(crate) const READ_TOOL_NAME: &str = "read"; diff --git a/codex-rs/ext/memories/src/metrics.rs b/codex-rs/ext/memories/src/metrics.rs index 610a3cb9e..443156b72 100644 --- a/codex-rs/ext/memories/src/metrics.rs +++ b/codex-rs/ext/memories/src/metrics.rs @@ -15,7 +15,7 @@ pub(crate) fn record_tool_call( return; }; - let tool = format!("{MEMORY_TOOLS_NAMESPACE}{operation}"); + let tool = format!("{MEMORY_TOOLS_NAMESPACE}/{operation}"); let _ = metrics_client.counter( MEMORIES_TOOL_CALL_METRIC, /*inc*/ 1, diff --git a/codex-rs/ext/memories/src/tests.rs b/codex-rs/ext/memories/src/tests.rs index fbb23bd7a..b70c5f802 100644 --- a/codex-rs/ext/memories/src/tests.rs +++ b/codex-rs/ext/memories/src/tests.rs @@ -22,6 +22,16 @@ use crate::extension::MemoriesExtension; use crate::extension::MemoriesExtensionConfig; use crate::local::LocalMemoriesBackend; +#[test] +fn memory_tool_namespace_matches_responses_api_identifier() { + assert!(!crate::MEMORY_TOOLS_NAMESPACE.is_empty()); + assert!( + crate::MEMORY_TOOLS_NAMESPACE + .bytes() + .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'_' | b'-')) + ); +} + #[test] fn tools_are_not_contributed_without_thread_config() { let extension = MemoriesExtension::default();