mirror of
https://github.com/openai/codex.git
synced 2026-11-09 20:50:33 +00:00
Negotiate MCP extensions per app-server session (#36910)
## Why App-server clients need to advertise structured MCP extension settings, including supported MCP App UI MIME types, rather than only opting into OpenAI form elicitation with a boolean. ## What changed - Add an `extensions` map to initialize capabilities and preserve `mcpServerOpenaiFormElicitation` as a legacy alias for `openai/form`. - Capture the declared extension profile when a thread is started, resumed, or forked, propagate it to subagents, and advertise it to downstream MCP servers during initialization. - Keep the profile stable for the lifetime of the loaded session instead of changing it on later turns or direct tool calls. ## Testing - Cover extension conversion, downstream MCP initialization, session isolation, legacy form support, and subagent inheritance. GitOrigin-RevId: fbcedbb74ce788e574b0f884a4c45c4cedb9de54
This commit is contained in:
committed by
copyberry
parent
bab7c2dcc1
commit
ee46c5ba0e
@@ -558,26 +558,6 @@ impl Session {
|
||||
.await
|
||||
}
|
||||
|
||||
pub(crate) async fn set_openai_form_elicitation_support(
|
||||
&self,
|
||||
supported: bool,
|
||||
) -> anyhow::Result<()> {
|
||||
if self
|
||||
.services
|
||||
.supports_openai_form_elicitation
|
||||
.load(std::sync::atomic::Ordering::Relaxed)
|
||||
== supported
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
self.services
|
||||
.supports_openai_form_elicitation
|
||||
.store(supported, std::sync::atomic::Ordering::Relaxed);
|
||||
self.request_mcp_runtime_refresh();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn refresh_mcp_servers_now(
|
||||
&self,
|
||||
turn_context: &TurnContext,
|
||||
|
||||
@@ -138,10 +138,6 @@ impl Session {
|
||||
elicitation_reviewer: Option<ElicitationReviewerHandle>,
|
||||
) -> McpRuntimeInput {
|
||||
let auth = desired.auth.clone();
|
||||
let supports_openai_form_elicitation = self
|
||||
.services
|
||||
.supports_openai_form_elicitation
|
||||
.load(std::sync::atomic::Ordering::Acquire);
|
||||
let McpRuntimeProjection {
|
||||
mut config,
|
||||
plugins_available,
|
||||
@@ -186,7 +182,7 @@ impl Session {
|
||||
codex_apps_tools_cache: self.services.mcp_manager.codex_apps_tools_cache(),
|
||||
tool_catalog_cache: self.services.mcp_manager.tool_catalog_cache(),
|
||||
codex_apps_tools_cache_key: connector_runtime_context_key(auth.as_ref()),
|
||||
supports_openai_form_elicitation,
|
||||
client_mcp_extensions: self.services.client_mcp_extensions.clone(),
|
||||
auth,
|
||||
codex_apps_auth_manager,
|
||||
elicitation_reviewer,
|
||||
|
||||
@@ -340,6 +340,7 @@ use codex_protocol::config_types::CollaborationMode;
|
||||
use codex_protocol::config_types::Personality;
|
||||
use codex_protocol::config_types::ReasoningSummary as ReasoningSummaryConfig;
|
||||
use codex_protocol::config_types::WindowsSandboxLevel;
|
||||
use codex_protocol::mcp::ClientMcpExtensions;
|
||||
use codex_protocol::models::LocalImagePreparation;
|
||||
use codex_protocol::models::ResponseInputItem;
|
||||
use codex_protocol::models::ResponseItem;
|
||||
@@ -448,7 +449,7 @@ pub(crate) struct SessionSpawnArgs {
|
||||
pub(crate) parent_trace: Option<W3cTraceContext>,
|
||||
pub(crate) environment_selections: Vec<TurnEnvironmentSelection>,
|
||||
pub(crate) thread_extension_init: ExtensionDataInit,
|
||||
pub(crate) supports_openai_form_elicitation: bool,
|
||||
pub(crate) client_mcp_extensions: ClientMcpExtensions,
|
||||
pub(crate) analytics_events_client: Option<AnalyticsEventsClient>,
|
||||
pub(crate) thread_store: Arc<dyn ThreadStore>,
|
||||
pub(crate) attestation_provider: Option<Arc<dyn AttestationProvider>>,
|
||||
@@ -540,7 +541,7 @@ impl Session {
|
||||
parent_trace: _,
|
||||
environment_selections,
|
||||
thread_extension_init,
|
||||
supports_openai_form_elicitation,
|
||||
client_mcp_extensions,
|
||||
analytics_events_client,
|
||||
thread_store,
|
||||
attestation_provider,
|
||||
@@ -731,7 +732,7 @@ impl Session {
|
||||
code_mode_session_provider,
|
||||
extensions,
|
||||
thread_extension_init,
|
||||
supports_openai_form_elicitation,
|
||||
client_mcp_extensions,
|
||||
agent_control,
|
||||
environment_manager,
|
||||
inherited_environments,
|
||||
|
||||
@@ -17,6 +17,7 @@ use codex_protocol::SessionId;
|
||||
use codex_protocol::capabilities::SelectedCapabilityRoot;
|
||||
use codex_protocol::config_types::SERVICE_TIER_DEFAULT_REQUEST_VALUE;
|
||||
use codex_protocol::config_types::ServiceTier;
|
||||
use codex_protocol::mcp::ClientMcpExtensions;
|
||||
use codex_protocol::permissions::FileSystemPath;
|
||||
use codex_protocol::permissions::FileSystemSpecialPath;
|
||||
use codex_protocol::protocol::MultiAgentVersion;
|
||||
@@ -515,7 +516,7 @@ impl Session {
|
||||
code_mode_session_provider: Arc<dyn codex_code_mode::CodeModeSessionProvider>,
|
||||
extensions: Arc<codex_extension_api::ExtensionRegistry<crate::config::Config>>,
|
||||
mut thread_extension_init: ExtensionDataInit,
|
||||
supports_openai_form_elicitation: bool,
|
||||
client_mcp_extensions: ClientMcpExtensions,
|
||||
agent_control: AgentControl,
|
||||
environment_manager: Arc<EnvironmentManager>,
|
||||
inherited_environments: Option<TurnEnvironmentSnapshot>,
|
||||
@@ -1126,9 +1127,7 @@ impl Session {
|
||||
thread_extension_data,
|
||||
selected_capability_roots,
|
||||
mcp_thread_init,
|
||||
supports_openai_form_elicitation: std::sync::atomic::AtomicBool::new(
|
||||
supports_openai_form_elicitation,
|
||||
),
|
||||
client_mcp_extensions,
|
||||
agent_control,
|
||||
network_proxy: arc_swap::ArcSwapOption::from(network_proxy.map(Arc::new)),
|
||||
network_proxy_audit_metadata,
|
||||
|
||||
@@ -5546,7 +5546,7 @@ async fn session_new_fails_when_zsh_fork_enabled_without_packaged_zsh() {
|
||||
Arc::new(codex_code_mode::DisabledCodeModeSessionProvider),
|
||||
Arc::new(codex_extension_api::ExtensionRegistryBuilder::new().build()),
|
||||
codex_extension_api::ExtensionDataInit::default(),
|
||||
/*supports_openai_form_elicitation*/ false,
|
||||
ClientMcpExtensions::default(),
|
||||
AgentControl::default(),
|
||||
environment_manager,
|
||||
/*inherited_environments*/ None,
|
||||
@@ -5742,7 +5742,7 @@ pub(crate) async fn make_session_and_context() -> (Session, TurnContext) {
|
||||
thread_extension_data: codex_extension_api::ExtensionData::new(thread_id.to_string()),
|
||||
selected_capability_roots: Vec::new(),
|
||||
mcp_thread_init: codex_extension_api::ExtensionDataInit::default(),
|
||||
supports_openai_form_elicitation: std::sync::atomic::AtomicBool::new(false),
|
||||
client_mcp_extensions: ClientMcpExtensions::default(),
|
||||
agent_control,
|
||||
network_proxy: arc_swap::ArcSwapOption::from(None),
|
||||
network_proxy_audit_metadata: crate::config::NetworkProxyAuditMetadata::default(),
|
||||
@@ -5956,7 +5956,7 @@ async fn make_session_with_config_and_rx(
|
||||
Arc::new(codex_code_mode::DisabledCodeModeSessionProvider),
|
||||
Arc::new(codex_extension_api::ExtensionRegistryBuilder::new().build()),
|
||||
codex_extension_api::ExtensionDataInit::default(),
|
||||
/*supports_openai_form_elicitation*/ false,
|
||||
ClientMcpExtensions::default(),
|
||||
AgentControl::default(),
|
||||
environment_manager,
|
||||
/*inherited_environments*/ None,
|
||||
@@ -6066,7 +6066,7 @@ async fn make_session_with_history_source_and_agent_control_and_rx(
|
||||
Arc::new(codex_code_mode::DisabledCodeModeSessionProvider),
|
||||
Arc::new(codex_extension_api::ExtensionRegistryBuilder::new().build()),
|
||||
codex_extension_api::ExtensionDataInit::default(),
|
||||
/*supports_openai_form_elicitation*/ false,
|
||||
ClientMcpExtensions::default(),
|
||||
agent_control,
|
||||
environment_manager,
|
||||
/*inherited_environments*/ None,
|
||||
@@ -7936,7 +7936,7 @@ where
|
||||
thread_extension_data: codex_extension_api::ExtensionData::new(thread_id.to_string()),
|
||||
selected_capability_roots: Vec::new(),
|
||||
mcp_thread_init: codex_extension_api::ExtensionDataInit::default(),
|
||||
supports_openai_form_elicitation: std::sync::atomic::AtomicBool::new(false),
|
||||
client_mcp_extensions: ClientMcpExtensions::default(),
|
||||
agent_control,
|
||||
network_proxy: arc_swap::ArcSwapOption::from(None),
|
||||
network_proxy_audit_metadata: crate::config::NetworkProxyAuditMetadata::default(),
|
||||
|
||||
@@ -765,7 +765,7 @@ async fn guardian_subagent_does_not_inherit_parent_exec_policy_rules() {
|
||||
parent_trace: None,
|
||||
environment_selections: Vec::new(),
|
||||
thread_extension_init: codex_extension_api::ExtensionDataInit::default(),
|
||||
supports_openai_form_elicitation: false,
|
||||
client_mcp_extensions: ClientMcpExtensions::default(),
|
||||
analytics_events_client: None,
|
||||
thread_store,
|
||||
attestation_provider: None,
|
||||
|
||||
Reference in New Issue
Block a user