Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions codex-rs/analytics/src/analytics_client_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,7 @@ fn sample_initialize_fact(connection_id: u64) -> AnalyticsFact {
experimental_api: false,
request_attestation: false,
opt_out_notification_methods: None,
mcp_server_openai_form_elicitation: false,
}),
},
product_client_id: DEFAULT_ORIGINATOR.to_string(),
Expand Down Expand Up @@ -1660,6 +1661,7 @@ async fn initialize_caches_client_and_thread_lifecycle_publishes_once_initialize
experimental_api: false,
request_attestation: false,
opt_out_notification_methods: None,
mcp_server_openai_form_elicitation: false,
}),
},
product_client_id: DEFAULT_ORIGINATOR.to_string(),
Expand Down Expand Up @@ -1809,6 +1811,7 @@ async fn compaction_event_ingests_custom_fact() {
experimental_api: false,
request_attestation: false,
opt_out_notification_methods: None,
mcp_server_openai_form_elicitation: false,
}),
},
product_client_id: DEFAULT_ORIGINATOR.to_string(),
Expand Down Expand Up @@ -1937,6 +1940,7 @@ async fn guardian_review_event_ingests_custom_fact_with_optional_target_item() {
experimental_api: false,
request_attestation: false,
opt_out_notification_methods: None,
mcp_server_openai_form_elicitation: false,
}),
},
product_client_id: DEFAULT_ORIGINATOR.to_string(),
Expand Down
32 changes: 31 additions & 1 deletion codex-rs/app-server-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,8 @@ pub struct InProcessClientStartArgs {
pub client_version: String,
/// Whether experimental APIs are requested at initialize time.
pub experimental_api: bool,
/// Whether MCP servers may send `openai/form` elicitation requests.
pub mcp_server_openai_form_elicitation: bool,
/// Notification methods this client opts out of receiving.
pub opt_out_notification_methods: Vec<String>,
/// Queue capacity for command/event channels (clamped to at least 1).
Expand All @@ -374,6 +376,7 @@ impl InProcessClientStartArgs {
} else {
Some(self.opt_out_notification_methods.clone())
},
mcp_server_openai_form_elicitation: self.mcp_server_openai_form_elicitation,
};

InitializeParams {
Expand Down Expand Up @@ -1044,6 +1047,7 @@ mod tests {
client_name: "codex-app-server-client-test".to_string(),
client_version: "0.0.0-test".to_string(),
experimental_api: true,
mcp_server_openai_form_elicitation: false,
opt_out_notification_methods: Vec::new(),
channel_capacity,
})
Expand Down Expand Up @@ -1237,11 +1241,25 @@ mod tests {
client_name: "codex-app-server-client-test".to_string(),
client_version: "0.0.0-test".to_string(),
experimental_api: true,
mcp_server_openai_form_elicitation: false,
opt_out_notification_methods: Vec::new(),
channel_capacity: 8,
}
}

#[test]
fn remote_initialize_params_forward_openai_form_capability() {
let mut args = test_remote_connect_args("ws://localhost/rpc".to_string());
args.mcp_server_openai_form_elicitation = true;

assert!(
args.initialize_params()
.capabilities
.expect("initialize capabilities")
.mcp_server_openai_form_elicitation
);
}

#[tokio::test]
async fn typed_request_roundtrip_works() {
let client = start_test_client(SessionSource::Exec).await;
Expand Down Expand Up @@ -1512,6 +1530,7 @@ mod tests {
client_name: "codex-app-server-client-test".to_string(),
client_version: "0.0.0-test".to_string(),
experimental_api: true,
mcp_server_openai_form_elicitation: false,
opt_out_notification_methods: Vec::new(),
channel_capacity: 8,
})
Expand Down Expand Up @@ -1600,6 +1619,7 @@ mod tests {
client_name: "codex-app-server-client-test".to_string(),
client_version: "0.0.0-test".to_string(),
experimental_api: true,
mcp_server_openai_form_elicitation: false,
opt_out_notification_methods: Vec::new(),
channel_capacity: 8,
})
Expand All @@ -1619,6 +1639,7 @@ mod tests {
client_name: "codex-app-server-client-test".to_string(),
client_version: "0.0.0-test".to_string(),
experimental_api: true,
mcp_server_openai_form_elicitation: false,
opt_out_notification_methods: Vec::new(),
channel_capacity: 8,
})
Expand Down Expand Up @@ -2189,7 +2210,7 @@ mod tests {
}

#[tokio::test]
async fn runtime_start_args_forward_environment_manager() {
async fn runtime_start_args_forward_environment_manager_and_openai_form_capability() {
let config = Arc::new(build_test_config().await);
let environment_manager = Arc::new(
EnvironmentManager::create_for_tests(
Expand Down Expand Up @@ -2222,12 +2243,20 @@ mod tests {
client_name: "codex-app-server-client-test".to_string(),
client_version: "0.0.0-test".to_string(),
experimental_api: true,
mcp_server_openai_form_elicitation: true,
opt_out_notification_methods: Vec::new(),
channel_capacity: DEFAULT_IN_PROCESS_CHANNEL_CAPACITY,
}
.into_runtime_start_args();

assert_eq!(runtime_args.config, config);
assert!(
runtime_args
.initialize
.capabilities
.expect("initialize capabilities")
.mcp_server_openai_form_elicitation
);
assert!(Arc::ptr_eq(
&runtime_args.environment_manager,
&environment_manager
Expand Down Expand Up @@ -2263,6 +2292,7 @@ mod tests {
client_name: "codex-app-server-client-test".to_string(),
client_version: "0.0.0-test".to_string(),
experimental_api: true,
mcp_server_openai_form_elicitation: false,
opt_out_notification_methods: Vec::new(),
channel_capacity: DEFAULT_IN_PROCESS_CHANNEL_CAPACITY,
}
Expand Down
4 changes: 3 additions & 1 deletion codex-rs/app-server-client/src/remote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,12 @@ pub struct RemoteAppServerConnectArgs {
pub client_name: String,
pub client_version: String,
pub experimental_api: bool,
pub mcp_server_openai_form_elicitation: bool,
pub opt_out_notification_methods: Vec<String>,
pub channel_capacity: usize,
}
impl RemoteAppServerConnectArgs {
fn initialize_params(&self) -> InitializeParams {
pub(crate) fn initialize_params(&self) -> InitializeParams {
let capabilities = InitializeCapabilities {
experimental_api: self.experimental_api,
request_attestation: false,
Expand All @@ -99,6 +100,7 @@ impl RemoteAppServerConnectArgs {
} else {
Some(self.opt_out_notification_methods.clone())
},
mcp_server_openai_form_elicitation: self.mcp_server_openai_form_elicitation,
};

InitializeParams {
Expand Down
4 changes: 4 additions & 0 deletions codex-rs/app-server-protocol/schema/json/ClientRequest.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions codex-rs/app-server-protocol/schema/json/ServerRequest.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions codex-rs/app-server-protocol/src/protocol/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2150,7 +2150,7 @@ mod tests {
}

#[test]
fn serialize_initialize_with_opt_out_notification_methods() -> Result<()> {
fn serialize_initialize_capabilities() -> Result<()> {
let request = ClientRequest::Initialize {
request_id: RequestId::Integer(42),
params: v1::InitializeParams {
Expand All @@ -2162,6 +2162,7 @@ mod tests {
capabilities: Some(v1::InitializeCapabilities {
experimental_api: true,
request_attestation: true,
mcp_server_openai_form_elicitation: true,
opt_out_notification_methods: Some(vec![
"thread/started".to_string(),
"item/agentMessage/delta".to_string(),
Expand All @@ -2183,6 +2184,7 @@ mod tests {
"capabilities": {
"experimentalApi": true,
"requestAttestation": true,
"mcpServerOpenaiFormElicitation": true,
"optOutNotificationMethods": [
"thread/started",
"item/agentMessage/delta"
Expand All @@ -2196,7 +2198,7 @@ mod tests {
}

#[test]
fn deserialize_initialize_with_opt_out_notification_methods() -> Result<()> {
fn deserialize_initialize_capabilities() -> Result<()> {
let request: ClientRequest = serde_json::from_value(json!({
"method": "initialize",
"id": 42,
Expand All @@ -2209,6 +2211,7 @@ mod tests {
"capabilities": {
"experimentalApi": true,
"requestAttestation": true,
"mcpServerOpenaiFormElicitation": true,
"optOutNotificationMethods": [
"thread/started",
"item/agentMessage/delta"
Expand All @@ -2230,6 +2233,7 @@ mod tests {
capabilities: Some(v1::InitializeCapabilities {
experimental_api: true,
request_attestation: true,
mcp_server_openai_form_elicitation: true,
opt_out_notification_methods: Some(vec![
"thread/started".to_string(),
"item/agentMessage/delta".to_string(),
Expand Down
3 changes: 3 additions & 0 deletions codex-rs/app-server-protocol/src/protocol/v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ pub struct InitializeCapabilities {
/// Opt into `attestation/generate` requests for upstream `x-oai-attestation`.
#[serde(default)]
pub request_attestation: bool,
/// Allow downstream MCP servers to request OpenAI extended form elicitations.
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub mcp_server_openai_form_elicitation: bool,
Comment thread
gpeal marked this conversation as resolved.
/// Exact notification method names that should be suppressed for this
/// connection (for example `thread/started`).
#[ts(optional = nullable)]
Expand Down
Loading
Loading