mirror of
https://github.com/openai/codex.git
synced 2026-11-13 14:46:14 +00:00
Support openai/form extended form elicitations (#27500)
# Summary Allow App Server clients to opt into `openai/form` MCP elicitations.
This commit is contained in:
1 parent
32a696dbac
commit
21a599fa56
67 files changed
+1486
-328
No files matched your search
@@ -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 {
|
||||
@@ -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(),
|
||||
@@ -2183,6 +2184,7 @@ mod tests {
|
||||
"capabilities": {
|
||||
"experimentalApi": true,
|
||||
"requestAttestation": true,
|
||||
"mcpServerOpenaiFormElicitation": true,
|
||||
"optOutNotificationMethods": [
|
||||
"thread/started",
|
||||
"item/agentMessage/delta"
|
||||
@@ -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,
|
||||
@@ -2209,6 +2211,7 @@ mod tests {
|
||||
"capabilities": {
|
||||
"experimentalApi": true,
|
||||
"requestAttestation": true,
|
||||
"mcpServerOpenaiFormElicitation": true,
|
||||
"optOutNotificationMethods": [
|
||||
"thread/started",
|
||||
"item/agentMessage/delta"
|
||||
@@ -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(),
|
||||
|
||||
@@ -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,
|
||||
/// Exact notification method names that should be suppressed for this
|
||||
/// connection (for example `thread/started`).
|
||||
#[ts(optional = nullable)]
|
||||
|
||||
@@ -632,6 +632,15 @@ pub enum McpServerElicitationRequest {
|
||||
message: String,
|
||||
requested_schema: McpElicitationSchema,
|
||||
},
|
||||
#[serde(rename = "openai/form", rename_all = "camelCase")]
|
||||
#[ts(rename = "openai/form", rename_all = "camelCase")]
|
||||
OpenAiForm {
|
||||
#[serde(rename = "_meta")]
|
||||
#[ts(rename = "_meta")]
|
||||
meta: Option<JsonValue>,
|
||||
message: String,
|
||||
requested_schema: JsonValue,
|
||||
},
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(rename_all = "camelCase")]
|
||||
Url {
|
||||
@@ -658,6 +667,15 @@ impl TryFrom<CoreElicitationRequest> for McpServerElicitationRequest {
|
||||
message,
|
||||
requested_schema: serde_json::from_value(requested_schema)?,
|
||||
}),
|
||||
CoreElicitationRequest::OpenAiForm {
|
||||
meta,
|
||||
message,
|
||||
requested_schema,
|
||||
} => Ok(Self::OpenAiForm {
|
||||
meta,
|
||||
message,
|
||||
requested_schema,
|
||||
}),
|
||||
CoreElicitationRequest::Url {
|
||||
meta,
|
||||
message,
|
||||
|
||||
@@ -1901,6 +1901,40 @@ fn mcp_server_elicitation_request_from_core_form_request() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mcp_server_elicitation_request_from_core_openai_form_request() {
|
||||
let requested_schema = json!({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"template": {
|
||||
"type": "openai/imagePicker",
|
||||
"title": "Template",
|
||||
"items": [{
|
||||
"id": "monthly-review",
|
||||
"title": "Monthly review",
|
||||
"image": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciLz4=",
|
||||
}],
|
||||
},
|
||||
},
|
||||
"required": ["template"],
|
||||
});
|
||||
let request = McpServerElicitationRequest::try_from(CoreElicitationRequest::OpenAiForm {
|
||||
meta: None,
|
||||
message: "Choose a report".to_string(),
|
||||
requested_schema: requested_schema.clone(),
|
||||
})
|
||||
.expect("OpenAI form request should convert");
|
||||
|
||||
assert_eq!(
|
||||
request,
|
||||
McpServerElicitationRequest::OpenAiForm {
|
||||
meta: None,
|
||||
message: "Choose a report".to_string(),
|
||||
requested_schema,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mcp_elicitation_schema_matches_mcp_2025_11_25_primitives() {
|
||||
let schema: McpElicitationSchema = serde_json::from_value(json!({
|
||||
|
||||
Reference in new issue
Block a user