mirror of
https://github.com/openai/codex.git
synced 2026-11-13 06:45:07 +00:00
Fix empty tool descriptions (#17946)
## Summary
- Ensure direct namespaced MCP tool groups are emitted with a non-empty
namespace description even when namespace metadata is missing or blank.
- Add regression coverage for missing MCP namespace descriptions.
## Cause
Latest `main` can serialize a direct namespaced MCP tool group with an
empty top-level `description`. The namespace description path used
`unwrap_or_default()` when `tool_namespaces` did not include metadata
for that namespace, so the outbound Responses API payload could contain
a tool like `{"type":"namespace","description":""}`. The Responses API
rejects that because namespace tool descriptions must be a non-empty
string.
## Fix
- Add a fallback namespace description: `Tools in the <namespace>
namespace.`
- Preserve provided namespace descriptions after trimming, but treat
blank descriptions as missing.
### Issue I am seeing
This is what I am seeing on the local build.
<img width="1593" height="488" alt="Screenshot 2026-04-15 at 10 55 55
AM"
src="https://github.com/user-attachments/assets/bab668ba-bf17-4c71-be4e-b102202fce57"
/>
---------
Co-authored-by: Sayan Sisodiya <sayan@openai.com>
This commit is contained in:
1 parent
aca781b3a7
commit
78ce61c78e
6 files changed
+67
-14
No files matched your search
@@ -5,6 +5,7 @@ use crate::ResponsesApiTool;
|
||||
use crate::ToolName;
|
||||
use crate::ToolSearchOutputTool;
|
||||
use crate::ToolSpec;
|
||||
use crate::default_namespace_description;
|
||||
use crate::mcp_tool_to_deferred_responses_api_tool;
|
||||
use codex_app_server_protocol::AppInfo;
|
||||
use serde::Deserialize;
|
||||
@@ -225,6 +226,8 @@ pub fn collect_tool_search_output_tools<'a>(
|
||||
|
||||
let description = first_tool
|
||||
.connector_description
|
||||
.map(str::trim)
|
||||
.filter(|description| !description.is_empty())
|
||||
.map(str::to_string)
|
||||
.or_else(|| {
|
||||
first_tool
|
||||
@@ -232,12 +235,6 @@ pub fn collect_tool_search_output_tools<'a>(
|
||||
.map(str::trim)
|
||||
.filter(|connector_name| !connector_name.is_empty())
|
||||
.map(|connector_name| format!("Tools for working with {connector_name}."))
|
||||
})
|
||||
.or_else(|| {
|
||||
Some(format!(
|
||||
"Tools from the {} MCP server.",
|
||||
first_tool.server_name
|
||||
))
|
||||
});
|
||||
|
||||
let tools = tools
|
||||
@@ -251,7 +248,8 @@ pub fn collect_tool_search_output_tools<'a>(
|
||||
|
||||
results.push(ToolSearchOutputTool::Namespace(ResponsesApiNamespace {
|
||||
name: tool_namespace.to_string(),
|
||||
description: description.unwrap_or_default(),
|
||||
description: description
|
||||
.unwrap_or_else(|| default_namespace_description(tool_namespace)),
|
||||
tools,
|
||||
}));
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user