mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
[codex] Forward Codex Apps tool call IDs to backend metadata (#19207)
## Summary - include the outer tool `call_id` in Codex Apps MCP request metadata under `_meta._codex_apps.call_id` - preserve existing Codex Apps metadata like `resource_uri` and `contains_mcp_source` - add request metadata coverage for both the existing-metadata and no-existing-metadata cases ## Why The paired backend change in [openai/openai#850796](https://github.com/openai/openai/pull/850796) updates MCP compliance logging to prefer `_meta._codex_apps.call_id` instead of the JSON-RPC request id. This client change sends that outer tool call id so the backend can record the model/tool call identifier when it is available. This is wire-compatible with older backends because `_meta._codex_apps` is already reserved backend-only metadata. Backends that do not read `call_id` will ignore the extra field. ## Testing - `cargo test -p codex-core request_meta` - `just fmt` - `just fix -p codex-core`
This commit is contained in:
committed by
GitHub
Unverified
parent
1e560f33e1
commit
219c65dc2f
@@ -159,8 +159,12 @@ pub(crate) async fn handle_mcp_tool_call(
|
||||
.unwrap_or_else(|| JsonValue::Object(serde_json::Map::new())),
|
||||
};
|
||||
}
|
||||
let request_meta =
|
||||
build_mcp_tool_call_request_meta(turn_context.as_ref(), &server, metadata.as_ref());
|
||||
let request_meta = build_mcp_tool_call_request_meta(
|
||||
turn_context.as_ref(),
|
||||
&server,
|
||||
&call_id,
|
||||
metadata.as_ref(),
|
||||
);
|
||||
let connector_id = metadata
|
||||
.as_ref()
|
||||
.and_then(|metadata| metadata.connector_id.clone());
|
||||
@@ -694,6 +698,7 @@ fn custom_mcp_tool_approval_mode(
|
||||
fn build_mcp_tool_call_request_meta(
|
||||
turn_context: &TurnContext,
|
||||
server: &str,
|
||||
call_id: &str,
|
||||
metadata: Option<&McpToolApprovalMetadata>,
|
||||
) -> Option<serde_json::Value> {
|
||||
let mut request_meta = serde_json::Map::new();
|
||||
@@ -705,10 +710,14 @@ fn build_mcp_tool_call_request_meta(
|
||||
);
|
||||
}
|
||||
|
||||
if server == CODEX_APPS_MCP_SERVER_NAME
|
||||
&& let Some(codex_apps_meta) =
|
||||
metadata.and_then(|metadata| metadata.codex_apps_meta.clone())
|
||||
{
|
||||
if server == CODEX_APPS_MCP_SERVER_NAME {
|
||||
let mut codex_apps_meta = metadata
|
||||
.and_then(|metadata| metadata.codex_apps_meta.clone())
|
||||
.unwrap_or_default();
|
||||
codex_apps_meta.insert(
|
||||
"call_id".to_string(),
|
||||
serde_json::Value::String(call_id.to_string()),
|
||||
);
|
||||
request_meta.insert(
|
||||
MCP_TOOL_CODEX_APPS_META_KEY.to_string(),
|
||||
serde_json::Value::Object(codex_apps_meta),
|
||||
|
||||
@@ -669,9 +669,13 @@ async fn mcp_tool_call_request_meta_includes_turn_metadata_for_custom_server() {
|
||||
)
|
||||
.expect("turn metadata json");
|
||||
|
||||
let meta =
|
||||
build_mcp_tool_call_request_meta(&turn_context, "custom_server", /*metadata*/ None)
|
||||
.expect("custom servers should receive turn metadata");
|
||||
let meta = build_mcp_tool_call_request_meta(
|
||||
&turn_context,
|
||||
"custom_server",
|
||||
"call-custom",
|
||||
/*metadata*/ None,
|
||||
)
|
||||
.expect("custom servers should receive turn metadata");
|
||||
|
||||
assert_eq!(
|
||||
meta,
|
||||
@@ -716,11 +720,13 @@ async fn codex_apps_tool_call_request_meta_includes_turn_metadata_and_codex_apps
|
||||
build_mcp_tool_call_request_meta(
|
||||
&turn_context,
|
||||
CODEX_APPS_MCP_SERVER_NAME,
|
||||
"call_abc123xyz789",
|
||||
Some(&metadata),
|
||||
),
|
||||
Some(serde_json::json!({
|
||||
crate::X_CODEX_TURN_METADATA_HEADER: expected_turn_metadata,
|
||||
MCP_TOOL_CODEX_APPS_META_KEY: {
|
||||
"call_id": "call_abc123xyz789",
|
||||
"resource_uri": "connector://calendar/tools/calendar_create_event",
|
||||
"contains_mcp_source": true,
|
||||
"connector_id": "calendar",
|
||||
@@ -729,6 +735,33 @@ async fn codex_apps_tool_call_request_meta_includes_turn_metadata_and_codex_apps
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn codex_apps_tool_call_request_meta_includes_call_id_without_existing_codex_apps_meta() {
|
||||
let (_, turn_context) = make_session_and_context().await;
|
||||
let expected_turn_metadata = serde_json::from_str::<serde_json::Value>(
|
||||
&turn_context
|
||||
.turn_metadata_state
|
||||
.current_header_value()
|
||||
.expect("turn metadata header"),
|
||||
)
|
||||
.expect("turn metadata json");
|
||||
|
||||
assert_eq!(
|
||||
build_mcp_tool_call_request_meta(
|
||||
&turn_context,
|
||||
CODEX_APPS_MCP_SERVER_NAME,
|
||||
"call_abc123xyz789",
|
||||
/*metadata*/ None,
|
||||
),
|
||||
Some(serde_json::json!({
|
||||
crate::X_CODEX_TURN_METADATA_HEADER: expected_turn_metadata,
|
||||
MCP_TOOL_CODEX_APPS_META_KEY: {
|
||||
"call_id": "call_abc123xyz789",
|
||||
},
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mcp_tool_call_thread_id_meta_is_added_to_request_meta() {
|
||||
assert_eq!(
|
||||
|
||||
@@ -222,6 +222,7 @@ async fn codex_apps_file_params_upload_local_paths_before_mcp_tool_call() -> Res
|
||||
assert_eq!(
|
||||
apps_tool_call.pointer("/params/_meta/_codex_apps"),
|
||||
Some(&json!({
|
||||
"call_id": "extract-call-1",
|
||||
"resource_uri": DOCUMENT_EXTRACT_TEXT_RESOURCE_URI,
|
||||
"contains_mcp_source": true,
|
||||
"connector_id": "calendar",
|
||||
|
||||
@@ -555,6 +555,7 @@ async fn tool_search_returns_deferred_tools_without_follow_up_tool_injection() -
|
||||
.structured_content,
|
||||
Some(json!({
|
||||
"_codex_apps": {
|
||||
"call_id": "calendar-call-1",
|
||||
"resource_uri": CALENDAR_CREATE_EVENT_RESOURCE_URI,
|
||||
"contains_mcp_source": true,
|
||||
"connector_id": "calendar",
|
||||
@@ -586,6 +587,7 @@ async fn tool_search_returns_deferred_tools_without_follow_up_tool_injection() -
|
||||
assert_eq!(
|
||||
apps_tool_call.pointer("/params/_meta/_codex_apps"),
|
||||
Some(&json!({
|
||||
"call_id": "calendar-call-1",
|
||||
"resource_uri": CALENDAR_CREATE_EVENT_RESOURCE_URI,
|
||||
"contains_mcp_source": true,
|
||||
"connector_id": "calendar",
|
||||
|
||||
Reference in New Issue
Block a user