mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
mcp: keep elicitation requests below app wire types (#29724)
## Why Core and tools need to request MCP elicitation without constructing app-server wire payloads. The request should remain a neutral protocol concept until app-server serializes it for a client. ## What changed - Switched core and tools to `codex_protocol::approvals::ElicitationRequest`. - Derived turn and server context inside core instead of carrying app-server request types through lower layers. - Kept the app-server payload unchanged through an explicit boundary conversion. - Removed the remaining production app-server-protocol dependency from tools. ## Stack This is PR 5 of 6, stacked on [PR #29723](https://github.com/openai/codex/pull/29723). Review only the delta from `codex/split-connector-metadata-types`. Next: [PR #29725](https://github.com/openai/codex/pull/29725). ## Validation - `codex-core` MCP coverage passed: 87 tests. - Tools elicitation and app-server round-trip coverage passed.
This commit is contained in:
committed by
GitHub
Unverified
parent
a33ad93996
commit
df1ee09ec5
@@ -99,8 +99,9 @@ impl Session {
|
||||
pub async fn request_mcp_server_elicitation(
|
||||
&self,
|
||||
turn_context: &TurnContext,
|
||||
server_name: String,
|
||||
request_id: RequestId,
|
||||
params: McpServerElicitationRequestParams,
|
||||
request: ElicitationRequest,
|
||||
) -> McpServerElicitationOutcome {
|
||||
if self
|
||||
.services
|
||||
@@ -118,53 +119,6 @@ impl Session {
|
||||
};
|
||||
}
|
||||
|
||||
let server_name = params.server_name.clone();
|
||||
let request = match params.request {
|
||||
McpServerElicitationRequest::Form {
|
||||
meta,
|
||||
message,
|
||||
requested_schema,
|
||||
} => {
|
||||
let requested_schema = match serde_json::to_value(requested_schema) {
|
||||
Ok(requested_schema) => requested_schema,
|
||||
Err(err) => {
|
||||
warn!(
|
||||
"failed to serialize MCP elicitation schema for server_name: {server_name}, request_id: {request_id}: {err:#}"
|
||||
);
|
||||
return McpServerElicitationOutcome {
|
||||
response: None,
|
||||
sent: false,
|
||||
};
|
||||
}
|
||||
};
|
||||
codex_protocol::approvals::ElicitationRequest::Form {
|
||||
meta,
|
||||
message,
|
||||
requested_schema,
|
||||
}
|
||||
}
|
||||
McpServerElicitationRequest::OpenAiForm {
|
||||
meta,
|
||||
message,
|
||||
requested_schema,
|
||||
} => codex_protocol::approvals::ElicitationRequest::OpenAiForm {
|
||||
meta,
|
||||
message,
|
||||
requested_schema,
|
||||
},
|
||||
McpServerElicitationRequest::Url {
|
||||
meta,
|
||||
message,
|
||||
url,
|
||||
elicitation_id,
|
||||
} => codex_protocol::approvals::ElicitationRequest::Url {
|
||||
meta,
|
||||
message,
|
||||
url,
|
||||
elicitation_id,
|
||||
},
|
||||
};
|
||||
|
||||
let (tx_response, rx_response) = oneshot::channel();
|
||||
let prev_entry = {
|
||||
let mut active = self.active_turn.lock().await;
|
||||
@@ -194,7 +148,7 @@ impl Session {
|
||||
}
|
||||
};
|
||||
let event = EventMsg::ElicitationRequest(ElicitationRequestEvent {
|
||||
turn_id: params.turn_id,
|
||||
turn_id: Some(turn_context.sub_id.clone()),
|
||||
server_name,
|
||||
id,
|
||||
request,
|
||||
|
||||
@@ -54,8 +54,6 @@ use chrono::Utc;
|
||||
use codex_analytics::AnalyticsEventsClient;
|
||||
use codex_analytics::SubAgentThreadStartedInput;
|
||||
use codex_analytics::TurnCodexErrorFact;
|
||||
use codex_app_server_protocol::McpServerElicitationRequest;
|
||||
use codex_app_server_protocol::McpServerElicitationRequestParams;
|
||||
use codex_config::types::AuthKeyringBackendKind;
|
||||
use codex_config::types::OAuthCredentialsStoreMode;
|
||||
use codex_exec_server::Environment;
|
||||
@@ -87,6 +85,7 @@ use codex_otel::current_span_w3c_trace_context;
|
||||
use codex_otel::set_parent_from_w3c_trace_context;
|
||||
use codex_protocol::SessionId;
|
||||
use codex_protocol::ThreadId;
|
||||
use codex_protocol::approvals::ElicitationRequest;
|
||||
use codex_protocol::approvals::ElicitationRequestEvent;
|
||||
use codex_protocol::approvals::ExecPolicyAmendment;
|
||||
use codex_protocol::approvals::NetworkPolicyAmendment;
|
||||
|
||||
@@ -84,7 +84,6 @@ use crate::tools::handlers::ShellCommandHandler;
|
||||
use crate::tools::registry::ToolExecutor;
|
||||
use crate::tools::router::ToolCallSource;
|
||||
use crate::turn_diff_tracker::TurnDiffTracker;
|
||||
use codex_app_server_protocol::McpElicitationSchema;
|
||||
use codex_config::config_toml::ConfigToml;
|
||||
use codex_config::config_toml::ProjectConfig;
|
||||
use codex_config::permissions_toml::FilesystemPermissionToml;
|
||||
@@ -377,24 +376,18 @@ async fn request_mcp_server_elicitation_auto_accepts_when_auto_deny_is_enabled()
|
||||
.load_full()
|
||||
.set_elicitations_auto_deny(/*auto_deny*/ true);
|
||||
|
||||
let requested_schema: McpElicitationSchema = serde_json::from_value(json!({
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
}))
|
||||
.expect("schema should deserialize");
|
||||
let response = session
|
||||
.request_mcp_server_elicitation(
|
||||
turn_context.as_ref(),
|
||||
"codex_apps".to_string(),
|
||||
RequestId::String("request-1".into()),
|
||||
McpServerElicitationRequestParams {
|
||||
thread_id: session.thread_id.to_string(),
|
||||
turn_id: Some(turn_context.sub_id.clone()),
|
||||
server_name: "codex_apps".to_string(),
|
||||
request: McpServerElicitationRequest::Form {
|
||||
meta: None,
|
||||
message: "Allow this request?".to_string(),
|
||||
requested_schema,
|
||||
},
|
||||
ElicitationRequest::Form {
|
||||
meta: None,
|
||||
message: "Allow this request?".to_string(),
|
||||
requested_schema: json!({
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
}),
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
||||
Reference in New Issue
Block a user