mirror of
https://github.com/openai/codex.git
synced 2026-04-26 07:35:29 +00:00
core/tui: non-blocking MCP startup (#6334)
This makes MCP startup not block TUI startup. Messages sent while MCPs are booting will be queued. https://github.com/user-attachments/assets/96e1d234-5d8f-4932-a935-a675d35c05e0 Fixes #6317 --------- Co-authored-by: pakrym-oai <pakrym@openai.com>
This commit is contained in:
@@ -478,6 +478,12 @@ pub enum EventMsg {
|
||||
/// Ack the client's configure message.
|
||||
SessionConfigured(SessionConfiguredEvent),
|
||||
|
||||
/// Incremental MCP startup progress updates.
|
||||
McpStartupUpdate(McpStartupUpdateEvent),
|
||||
|
||||
/// Aggregate MCP startup completion summary.
|
||||
McpStartupComplete(McpStartupCompleteEvent),
|
||||
|
||||
McpToolCallBegin(McpToolCallBeginEvent),
|
||||
|
||||
McpToolCallEnd(McpToolCallEndEvent),
|
||||
@@ -1383,6 +1389,37 @@ pub struct McpListToolsResponseEvent {
|
||||
pub auth_statuses: std::collections::HashMap<String, McpAuthStatus>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||
pub struct McpStartupUpdateEvent {
|
||||
/// Server name being started.
|
||||
pub server: String,
|
||||
/// Current startup status.
|
||||
pub status: McpStartupStatus,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||
#[serde(rename_all = "snake_case", tag = "state")]
|
||||
#[ts(rename_all = "snake_case", tag = "state")]
|
||||
pub enum McpStartupStatus {
|
||||
Starting,
|
||||
Ready,
|
||||
Failed { error: String },
|
||||
Cancelled,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS, Default)]
|
||||
pub struct McpStartupCompleteEvent {
|
||||
pub ready: Vec<String>,
|
||||
pub failed: Vec<McpStartupFailure>,
|
||||
pub cancelled: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||
pub struct McpStartupFailure {
|
||||
pub server: String,
|
||||
pub error: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(rename_all = "snake_case")]
|
||||
@@ -1589,4 +1626,47 @@ mod tests {
|
||||
assert_eq!(deserialized, event);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_mcp_startup_update_event() -> Result<()> {
|
||||
let event = Event {
|
||||
id: "init".to_string(),
|
||||
msg: EventMsg::McpStartupUpdate(McpStartupUpdateEvent {
|
||||
server: "srv".to_string(),
|
||||
status: McpStartupStatus::Failed {
|
||||
error: "boom".to_string(),
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
let value = serde_json::to_value(&event)?;
|
||||
assert_eq!(value["msg"]["type"], "mcp_startup_update");
|
||||
assert_eq!(value["msg"]["server"], "srv");
|
||||
assert_eq!(value["msg"]["status"]["state"], "failed");
|
||||
assert_eq!(value["msg"]["status"]["error"], "boom");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_mcp_startup_complete_event() -> Result<()> {
|
||||
let event = Event {
|
||||
id: "init".to_string(),
|
||||
msg: EventMsg::McpStartupComplete(McpStartupCompleteEvent {
|
||||
ready: vec!["a".to_string()],
|
||||
failed: vec![McpStartupFailure {
|
||||
server: "b".to_string(),
|
||||
error: "bad".to_string(),
|
||||
}],
|
||||
cancelled: vec!["c".to_string()],
|
||||
}),
|
||||
};
|
||||
|
||||
let value = serde_json::to_value(&event)?;
|
||||
assert_eq!(value["msg"]["type"], "mcp_startup_complete");
|
||||
assert_eq!(value["msg"]["ready"][0], "a");
|
||||
assert_eq!(value["msg"]["failed"][0]["server"], "b");
|
||||
assert_eq!(value["msg"]["failed"][0]["error"], "bad");
|
||||
assert_eq!(value["msg"]["cancelled"][0], "c");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user