Merge 001a24460d into sapling-pr-archive-bolinfest

This commit is contained in:
Michael Bolin
2025-05-13 20:08:52 -07:00
committed by GitHub
9 changed files with 253 additions and 184 deletions

View File

@@ -55,12 +55,24 @@ use crate::models::ResponseInputItem;
use crate::models::ResponseItem;
use crate::models::ShellToolCallParams;
use crate::project_doc::create_full_instructions;
use crate::protocol::AgentMessageEvent;
use crate::protocol::AgentReasoningEvent;
use crate::protocol::ApplyPatchApprovalRequestEvent;
use crate::protocol::AskForApproval;
use crate::protocol::BackgroundEventEvent;
use crate::protocol::ErrorEvent;
use crate::protocol::Event;
use crate::protocol::EventMsg;
use crate::protocol::ExecApprovalRequestEvent;
use crate::protocol::ExecCommandBeginEvent;
use crate::protocol::ExecCommandEndEvent;
use crate::protocol::FileChange;
use crate::protocol::InputItem;
use crate::protocol::McpToolCallBeginEvent;
use crate::protocol::McpToolCallEndEvent;
use crate::protocol::Op;
use crate::protocol::PatchApplyBeginEvent;
use crate::protocol::PatchApplyEndEvent;
use crate::protocol::ReviewDecision;
use crate::protocol::SandboxPolicy;
use crate::protocol::SessionConfiguredEvent;
@@ -227,11 +239,11 @@ impl Session {
let (tx_approve, rx_approve) = oneshot::channel();
let event = Event {
id: sub_id.clone(),
msg: EventMsg::ExecApprovalRequest {
msg: EventMsg::ExecApprovalRequest(ExecApprovalRequestEvent {
command,
cwd,
reason,
},
}),
};
let _ = self.tx_event.send(event).await;
{
@@ -251,11 +263,11 @@ impl Session {
let (tx_approve, rx_approve) = oneshot::channel();
let event = Event {
id: sub_id.clone(),
msg: EventMsg::ApplyPatchApprovalRequest {
msg: EventMsg::ApplyPatchApprovalRequest(ApplyPatchApprovalRequestEvent {
changes: convert_apply_patch_to_protocol(action),
reason,
grant_root,
},
}),
};
let _ = self.tx_event.send(event).await;
{
@@ -297,11 +309,11 @@ impl Session {
async fn notify_exec_command_begin(&self, sub_id: &str, call_id: &str, params: &ExecParams) {
let event = Event {
id: sub_id.to_string(),
msg: EventMsg::ExecCommandBegin {
msg: EventMsg::ExecCommandBegin(ExecCommandBeginEvent {
call_id: call_id.to_string(),
command: params.command.clone(),
cwd: params.cwd.clone(),
},
}),
};
let _ = self.tx_event.send(event).await;
}
@@ -319,12 +331,12 @@ impl Session {
id: sub_id.to_string(),
// Because stdout and stderr could each be up to 100 KiB, we send
// truncated versions.
msg: EventMsg::ExecCommandEnd {
msg: EventMsg::ExecCommandEnd(ExecCommandEndEvent {
call_id: call_id.to_string(),
stdout: stdout.chars().take(MAX_STREAM_OUTPUT).collect(),
stderr: stderr.chars().take(MAX_STREAM_OUTPUT).collect(),
exit_code,
},
}),
};
let _ = self.tx_event.send(event).await;
}
@@ -335,9 +347,9 @@ impl Session {
async fn notify_background_event(&self, sub_id: &str, message: impl Into<String>) {
let event = Event {
id: sub_id.to_string(),
msg: EventMsg::BackgroundEvent {
msg: EventMsg::BackgroundEvent(BackgroundEventEvent {
message: message.into(),
},
}),
};
let _ = self.tx_event.send(event).await;
}
@@ -460,9 +472,9 @@ impl AgentTask {
self.handle.abort();
let event = Event {
id: self.sub_id,
msg: EventMsg::Error {
msg: EventMsg::Error(ErrorEvent {
message: "Turn interrupted".to_string(),
},
}),
};
let tx_event = self.sess.tx_event.clone();
tokio::spawn(async move {
@@ -483,10 +495,10 @@ async fn submission_loop(
let send_no_session_event = |sub_id: String| async {
let event = Event {
id: sub_id,
msg: EventMsg::Error {
msg: EventMsg::Error(ErrorEvent {
message: "No session initialized, expected 'ConfigureSession' as first Op"
.to_string(),
},
}),
};
tx_event.send(event).await.ok();
};
@@ -534,7 +546,7 @@ async fn submission_loop(
error!(message);
let event = Event {
id: sub.id,
msg: EventMsg::Error { message },
msg: EventMsg::Error(ErrorEvent { message }),
};
if let Err(e) = tx_event.send(event).await {
error!("failed to send error message: {e:?}");
@@ -577,7 +589,7 @@ async fn submission_loop(
error!("{message}");
mcp_connection_errors.push(Event {
id: sub.id.clone(),
msg: EventMsg::Error { message },
msg: EventMsg::Error(ErrorEvent { message }),
});
(McpConnectionManager::default(), Default::default())
}
@@ -591,7 +603,7 @@ async fn submission_loop(
error!("{message}");
mcp_connection_errors.push(Event {
id: sub.id.clone(),
msg: EventMsg::Error { message },
msg: EventMsg::Error(ErrorEvent { message }),
});
}
}
@@ -792,9 +804,9 @@ async fn run_task(sess: Arc<Session>, sub_id: String, input: Vec<InputItem>) {
info!("Turn error: {e:#}");
let event = Event {
id: sub_id.clone(),
msg: EventMsg::Error {
msg: EventMsg::Error(ErrorEvent {
message: e.to_string(),
},
}),
};
sess.tx_event.send(event).await.ok();
return;
@@ -933,7 +945,7 @@ async fn handle_response_item(
if let ContentItem::OutputText { text } = item {
let event = Event {
id: sub_id.to_string(),
msg: EventMsg::AgentMessage { message: text },
msg: EventMsg::AgentMessage(AgentMessageEvent { message: text }),
};
sess.tx_event.send(event).await.ok();
}
@@ -946,7 +958,7 @@ async fn handle_response_item(
};
let event = Event {
id: sub_id.to_string(),
msg: EventMsg::AgentReasoning { text },
msg: EventMsg::AgentReasoning(AgentReasoningEvent { text }),
};
sess.tx_event.send(event).await.ok();
}
@@ -1346,11 +1358,11 @@ async fn apply_patch(
.tx_event
.send(Event {
id: sub_id.clone(),
msg: EventMsg::PatchApplyBegin {
msg: EventMsg::PatchApplyBegin(PatchApplyBeginEvent {
call_id: call_id.clone(),
auto_approved,
changes: convert_apply_patch_to_protocol(&action),
},
}),
})
.await;
@@ -1435,12 +1447,12 @@ async fn apply_patch(
.tx_event
.send(Event {
id: sub_id.clone(),
msg: EventMsg::PatchApplyEnd {
msg: EventMsg::PatchApplyEnd(PatchApplyEndEvent {
call_id: call_id.clone(),
stdout: String::from_utf8_lossy(&stdout).to_string(),
stderr: String::from_utf8_lossy(&stderr).to_string(),
success: success_flag,
},
}),
})
.await;

View File

@@ -24,7 +24,7 @@ pub async fn init_codex(config: Config) -> anyhow::Result<(Codex, Event, Arc<Not
&event,
Event {
id: _id,
msg: EventMsg::SessionConfigured { .. },
msg: EventMsg::SessionConfigured(_),
}
)
{

View File

@@ -7,6 +7,8 @@ use crate::models::FunctionCallOutputPayload;
use crate::models::ResponseInputItem;
use crate::protocol::Event;
use crate::protocol::EventMsg;
use crate::protocol::McpToolCallBeginEvent;
use crate::protocol::McpToolCallEndEvent;
/// Handles the specified tool call dispatches the appropriate
/// `McpToolCallBegin` and `McpToolCallEnd` events to the `Session`.
@@ -39,12 +41,12 @@ pub(crate) async fn handle_mcp_tool_call(
}
};
let tool_call_begin_event = EventMsg::McpToolCallBegin {
let tool_call_begin_event = EventMsg::McpToolCallBegin(McpToolCallBeginEvent {
call_id: call_id.clone(),
server: server.clone(),
tool: tool_name.clone(),
arguments: arguments_value.clone(),
};
});
notify_mcp_tool_call_event(sess, sub_id, tool_call_begin_event).await;
// Perform the tool call.
@@ -53,29 +55,29 @@ pub(crate) async fn handle_mcp_tool_call(
.await
{
Ok(result) => (
EventMsg::McpToolCallEnd {
EventMsg::McpToolCallEnd(McpToolCallEndEvent {
call_id,
success: !result.is_error.unwrap_or(false),
result: Some(result),
},
}),
None,
),
Err(e) => (
EventMsg::McpToolCallEnd {
EventMsg::McpToolCallEnd(McpToolCallEndEvent {
call_id,
success: false,
result: None,
},
}),
Some(e),
),
};
notify_mcp_tool_call_event(sess, sub_id, tool_call_end_event.clone()).await;
let EventMsg::McpToolCallEnd {
let EventMsg::McpToolCallEnd(McpToolCallEndEvent {
call_id,
success,
result,
} = tool_call_end_event
}) = tool_call_end_event
else {
unimplemented!("unexpected event type");
};

View File

@@ -303,9 +303,7 @@ pub struct Event {
#[serde(tag = "type", rename_all = "snake_case")]
pub enum EventMsg {
/// Error while executing a submission
Error {
message: String,
},
Error(ErrorEvent),
/// Agent has started a task
TaskStarted,
@@ -314,117 +312,154 @@ pub enum EventMsg {
TaskComplete,
/// Agent text output message
AgentMessage {
message: String,
},
AgentMessage(AgentMessageEvent),
/// Reasoning event from agent.
AgentReasoning {
text: String,
},
AgentReasoning(AgentReasoningEvent),
/// Ack the client's configure message.
SessionConfigured(SessionConfiguredEvent),
McpToolCallBegin {
/// Identifier so this can be paired with the McpToolCallEnd event.
call_id: String,
McpToolCallBegin(McpToolCallBeginEvent),
/// Name of the MCP server as defined in the config.
server: String,
/// Name of the tool as given by the MCP server.
tool: String,
/// Arguments to the tool call.
arguments: Option<serde_json::Value>,
},
McpToolCallEnd {
/// Identifier for the McpToolCallBegin that finished.
call_id: String,
/// Whether the tool call was successful. If `false`, `result` might
/// not be present.
success: bool,
/// Result of the tool call. Note this could be an error.
result: Option<CallToolResult>,
},
McpToolCallEnd(McpToolCallEndEvent),
/// Notification that the server is about to execute a command.
ExecCommandBegin {
/// Identifier so this can be paired with the ExecCommandEnd event.
call_id: String,
/// The command to be executed.
command: Vec<String>,
/// The command's working directory if not the default cwd for the
/// agent.
cwd: PathBuf,
},
ExecCommandBegin(ExecCommandBeginEvent),
ExecCommandEnd {
/// Identifier for the ExecCommandBegin that finished.
call_id: String,
/// Captured stdout
stdout: String,
/// Captured stderr
stderr: String,
/// The command's exit code.
exit_code: i32,
},
ExecCommandEnd(ExecCommandEndEvent),
ExecApprovalRequest {
/// The command to be executed.
command: Vec<String>,
/// The command's working directory.
cwd: PathBuf,
/// Optional humanreadable reason for the approval (e.g. retry without
/// sandbox).
#[serde(skip_serializing_if = "Option::is_none")]
reason: Option<String>,
},
ExecApprovalRequest(ExecApprovalRequestEvent),
ApplyPatchApprovalRequest {
changes: HashMap<PathBuf, FileChange>,
/// Optional explanatory reason (e.g. request for extra write access).
#[serde(skip_serializing_if = "Option::is_none")]
reason: Option<String>,
ApplyPatchApprovalRequest(ApplyPatchApprovalRequestEvent),
/// When set, the agent is asking the user to allow writes under this
/// root for the remainder of the session.
#[serde(skip_serializing_if = "Option::is_none")]
grant_root: Option<PathBuf>,
},
BackgroundEvent {
message: String,
},
BackgroundEvent(BackgroundEventEvent),
/// Notification that the agent is about to apply a code patch. Mirrors
/// `ExecCommandBegin` so frontends can show progress indicators.
PatchApplyBegin {
/// Identifier so this can be paired with the PatchApplyEnd event.
call_id: String,
/// If true, there was no ApplyPatchApprovalRequest for this patch.
auto_approved: bool,
/// The changes to be applied.
changes: HashMap<PathBuf, FileChange>,
},
PatchApplyBegin(PatchApplyBeginEvent),
/// Notification that a patch application has finished.
PatchApplyEnd {
/// Identifier for the PatchApplyBegin that finished.
call_id: String,
/// Captured stdout (summary printed by apply_patch).
stdout: String,
/// Captured stderr (parser errors, IO failures, etc.).
stderr: String,
/// Whether the patch was applied successfully.
success: bool,
},
PatchApplyEnd(PatchApplyEndEvent),
}
// Individual event payload types matching each `EventMsg` variant.
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ErrorEvent {
pub message: String,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct AgentMessageEvent {
pub message: String,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct AgentReasoningEvent {
pub text: String,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct McpToolCallBeginEvent {
/// Identifier so this can be paired with the McpToolCallEnd event.
pub call_id: String,
/// Name of the MCP server as defined in the config.
pub server: String,
/// Name of the tool as given by the MCP server.
pub tool: String,
/// Arguments to the tool call.
pub arguments: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct McpToolCallEndEvent {
/// Identifier for the corresponding McpToolCallBegin that finished.
pub call_id: String,
/// Whether the tool call was successful. If `false`, `result` might not be present.
pub success: bool,
/// Result of the tool call. Note this could be an error.
pub result: Option<CallToolResult>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ExecCommandBeginEvent {
/// Identifier so this can be paired with the ExecCommandEnd event.
pub call_id: String,
/// The command to be executed.
pub command: Vec<String>,
/// The command's working directory if not the default cwd for the agent.
pub cwd: PathBuf,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ExecCommandEndEvent {
/// Identifier for the ExecCommandBegin that finished.
pub call_id: String,
/// Captured stdout
pub stdout: String,
/// Captured stderr
pub stderr: String,
/// The command's exit code.
pub exit_code: i32,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ExecApprovalRequestEvent {
/// The command to be executed.
pub command: Vec<String>,
/// The command's working directory.
pub cwd: PathBuf,
/// Optional human-readable reason for the approval (e.g. retry without sandbox).
#[serde(skip_serializing_if = "Option::is_none")]
pub reason: Option<String>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ApplyPatchApprovalRequestEvent {
pub changes: HashMap<PathBuf, FileChange>,
/// Optional explanatory reason (e.g. request for extra write access).
#[serde(skip_serializing_if = "Option::is_none")]
pub reason: Option<String>,
/// When set, the agent is asking the user to allow writes under this root for the remainder of the session.
#[serde(skip_serializing_if = "Option::is_none")]
pub grant_root: Option<PathBuf>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct BackgroundEventEvent {
pub message: String,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct PatchApplyBeginEvent {
/// Identifier so this can be paired with the PatchApplyEnd event.
pub call_id: String,
/// If true, there was no ApplyPatchApprovalRequest for this patch.
pub auto_approved: bool,
/// The changes to be applied.
pub changes: HashMap<PathBuf, FileChange>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct PatchApplyEndEvent {
/// Identifier for the PatchApplyBegin that finished.
pub call_id: String,
/// Captured stdout (summary printed by apply_patch).
pub stdout: String,
/// Captured stderr (parser errors, IO failures, etc.).
pub stderr: String,
/// Whether the patch was applied successfully.
pub success: bool,
}
#[derive(Debug, Default, Clone, Deserialize, Serialize)]
pub struct SessionConfiguredEvent {
/// Unique id for this session.
pub session_id: Uuid,
/// Tell the client what model is being queried.
pub model: String,
}
#[derive(Debug, Default, Clone, Deserialize, Serialize)]

View File

@@ -92,9 +92,11 @@ async fn live_streaming_and_prev_id_reset() {
.expect("agent closed");
match ev.msg {
EventMsg::AgentMessage { .. } => saw_message_before_complete = true,
EventMsg::AgentMessage(_) => saw_message_before_complete = true,
EventMsg::TaskComplete => break,
EventMsg::Error { message } => panic!("agent reported error in task1: {message}"),
EventMsg::Error(codex_core::protocol::ErrorEvent { message }) => {
panic!("agent reported error in task1: {message}")
}
_ => (),
}
}
@@ -122,11 +124,15 @@ async fn live_streaming_and_prev_id_reset() {
.expect("agent closed");
match &ev.msg {
EventMsg::AgentMessage { message } if message.contains("second turn succeeded") => {
EventMsg::AgentMessage(codex_core::protocol::AgentMessageEvent { message })
if message.contains("second turn succeeded") =>
{
got_expected = true;
}
EventMsg::TaskComplete => break,
EventMsg::Error { message } => panic!("agent reported error in task2: {message}"),
EventMsg::Error(codex_core::protocol::ErrorEvent { message }) => {
panic!("agent reported error in task2: {message}")
}
_ => (),
}
}
@@ -171,19 +177,28 @@ async fn live_shell_function_call() {
.expect("agent closed");
match ev.msg {
EventMsg::ExecCommandBegin { command, .. } => {
EventMsg::ExecCommandBegin(codex_core::protocol::ExecCommandBeginEvent {
command,
call_id: _,
cwd: _,
}) => {
assert_eq!(command, vec!["echo", MARKER]);
saw_begin = true;
}
EventMsg::ExecCommandEnd {
stdout, exit_code, ..
} => {
EventMsg::ExecCommandEnd(codex_core::protocol::ExecCommandEndEvent {
stdout,
exit_code,
call_id: _,
stderr: _,
}) => {
assert_eq!(exit_code, 0, "echo returned nonzero exit code");
assert!(stdout.contains(MARKER));
saw_end_with_output = true;
}
EventMsg::TaskComplete => break,
EventMsg::Error { message } => panic!("agent error during shell test: {message}"),
EventMsg::Error(codex_core::protocol::ErrorEvent { message }) => {
panic!("agent error during shell test: {message}")
}
_ => (),
}
}

View File

@@ -150,7 +150,7 @@ async fn keeps_previous_response_id_between_tasks() {
.unwrap();
match ev.msg {
codex_core::protocol::EventMsg::TaskComplete => break,
codex_core::protocol::EventMsg::Error { message } => {
codex_core::protocol::EventMsg::Error(codex_core::protocol::ErrorEvent { message }) => {
panic!("unexpected error: {message}")
}
_ => (),

View File

@@ -95,11 +95,11 @@ impl EventProcessor {
pub(crate) fn process_event(&mut self, event: Event) {
let Event { id, msg } = event;
match msg {
EventMsg::Error { message } => {
EventMsg::Error(codex_core::protocol::ErrorEvent { message }) => {
let prefix = "ERROR:".style(self.red);
ts_println!("{prefix} {message}");
}
EventMsg::BackgroundEvent { message } => {
EventMsg::BackgroundEvent(codex_core::protocol::BackgroundEventEvent { message }) => {
ts_println!("{}", message.style(self.dimmed));
}
EventMsg::TaskStarted => {
@@ -110,15 +110,15 @@ impl EventProcessor {
let msg = format!("Task complete: {id}");
ts_println!("{}", msg.style(self.bold));
}
EventMsg::AgentMessage { message } => {
EventMsg::AgentMessage(codex_core::protocol::AgentMessageEvent { message }) => {
let prefix = "Agent message:".style(self.bold);
ts_println!("{prefix} {message}");
}
EventMsg::ExecCommandBegin {
EventMsg::ExecCommandBegin(codex_core::protocol::ExecCommandBeginEvent {
call_id,
command,
cwd,
} => {
}) => {
self.call_id_to_command.insert(
call_id.clone(),
ExecCommandBegin {
@@ -133,12 +133,12 @@ impl EventProcessor {
cwd.to_string_lossy(),
);
}
EventMsg::ExecCommandEnd {
EventMsg::ExecCommandEnd(codex_core::protocol::ExecCommandEndEvent {
call_id,
stdout,
stderr,
exit_code,
} => {
}) => {
let exec_command = self.call_id_to_command.remove(&call_id);
let (duration, call) = if let Some(ExecCommandBegin {
command,
@@ -173,19 +173,21 @@ impl EventProcessor {
}
// Handle MCP tool calls (e.g. calling external functions via MCP).
EventMsg::McpToolCallBegin {
EventMsg::McpToolCallBegin(codex_core::protocol::McpToolCallBeginEvent {
call_id,
server,
tool,
arguments,
} => {
}) => {
// Build fully-qualified tool name: server.tool
let fq_tool_name = format!("{server}.{tool}");
// Format arguments as compact JSON so they fit on one line.
let args_str = arguments
.as_ref()
.map(|v| serde_json::to_string(v).unwrap_or_else(|_| v.to_string()))
.map(|v: &serde_json::Value| {
serde_json::to_string(v).unwrap_or_else(|_| v.to_string())
})
.unwrap_or_default();
let invocation = if args_str.is_empty() {
@@ -208,11 +210,11 @@ impl EventProcessor {
invocation.style(self.bold),
);
}
EventMsg::McpToolCallEnd {
EventMsg::McpToolCallEnd(codex_core::protocol::McpToolCallEndEvent {
call_id,
success,
result,
} => {
}) => {
// Retrieve start time and invocation for duration calculation and labeling.
let info = self.call_id_to_tool_call.remove(&call_id);
@@ -243,11 +245,11 @@ impl EventProcessor {
}
}
}
EventMsg::PatchApplyBegin {
EventMsg::PatchApplyBegin(codex_core::protocol::PatchApplyBeginEvent {
call_id,
auto_approved,
changes,
} => {
}) => {
// Store metadata so we can calculate duration later when we
// receive the corresponding PatchApplyEnd event.
self.call_id_to_patch.insert(
@@ -321,12 +323,12 @@ impl EventProcessor {
}
}
}
EventMsg::PatchApplyEnd {
EventMsg::PatchApplyEnd(codex_core::protocol::PatchApplyEndEvent {
call_id,
stdout,
stderr,
success,
} => {
}) => {
let patch_begin = self.call_id_to_patch.remove(&call_id);
// Compute duration and summary label similar to exec commands.
@@ -355,10 +357,10 @@ impl EventProcessor {
println!("{}", line.style(self.dimmed));
}
}
EventMsg::ExecApprovalRequest { .. } => {
EventMsg::ExecApprovalRequest(_) => {
// Should we exit?
}
EventMsg::ApplyPatchApprovalRequest { .. } => {
EventMsg::ApplyPatchApprovalRequest(_) => {
// Should we exit?
}
_ => {

View File

@@ -85,10 +85,10 @@ pub async fn run_codex_tool_session(
let _ = outgoing.send(codex_event_to_notification(&event)).await;
match &event.msg {
EventMsg::AgentMessage { message } => {
EventMsg::AgentMessage(codex_core::protocol::AgentMessageEvent { message }) => {
last_agent_message = Some(message.clone());
}
EventMsg::ExecApprovalRequest { .. } => {
EventMsg::ExecApprovalRequest(_) => {
let result = CallToolResult {
content: vec![CallToolResultContent::TextContent(TextContent {
r#type: "text".to_string(),
@@ -106,7 +106,7 @@ pub async fn run_codex_tool_session(
.await;
break;
}
EventMsg::ApplyPatchApprovalRequest { .. } => {
EventMsg::ApplyPatchApprovalRequest(_) => {
let result = CallToolResult {
content: vec![CallToolResultContent::TextContent(TextContent {
r#type: "text".to_string(),
@@ -153,7 +153,7 @@ pub async fn run_codex_tool_session(
.await;
break;
}
EventMsg::SessionConfigured { .. } => {
EventMsg::SessionConfigured(_) => {
tracing::error!("unexpected SessionConfigured event");
}
_ => {}

View File

@@ -213,11 +213,11 @@ impl ChatWidget<'_> {
.add_session_info(&self.config, event);
self.request_redraw()?;
}
EventMsg::AgentMessage { message } => {
EventMsg::AgentMessage(codex_core::protocol::AgentMessageEvent { message }) => {
self.conversation_history.add_agent_message(message);
self.request_redraw()?;
}
EventMsg::AgentReasoning { text } => {
EventMsg::AgentReasoning(codex_core::protocol::AgentReasoningEvent { text }) => {
self.conversation_history.add_agent_reasoning(text);
self.request_redraw()?;
}
@@ -229,15 +229,15 @@ impl ChatWidget<'_> {
self.bottom_pane.set_task_running(false)?;
self.request_redraw()?;
}
EventMsg::Error { message } => {
EventMsg::Error(codex_core::protocol::ErrorEvent { message }) => {
self.conversation_history.add_error(message);
self.bottom_pane.set_task_running(false)?;
}
EventMsg::ExecApprovalRequest {
EventMsg::ExecApprovalRequest(codex_core::protocol::ExecApprovalRequestEvent {
command,
cwd,
reason,
} => {
}) => {
let request = ApprovalRequest::Exec {
id,
command,
@@ -246,11 +246,13 @@ impl ChatWidget<'_> {
};
self.bottom_pane.push_approval_request(request)?;
}
EventMsg::ApplyPatchApprovalRequest {
changes,
reason,
grant_root,
} => {
EventMsg::ApplyPatchApprovalRequest(
codex_core::protocol::ApplyPatchApprovalRequestEvent {
changes,
reason,
grant_root,
},
) => {
// ------------------------------------------------------------------
// Before we even prompt the user for approval we surface the patch
// summary in the main conversation so that the dialog appears in a
@@ -276,18 +278,20 @@ impl ChatWidget<'_> {
self.bottom_pane.push_approval_request(request)?;
self.request_redraw()?;
}
EventMsg::ExecCommandBegin {
call_id, command, ..
} => {
EventMsg::ExecCommandBegin(codex_core::protocol::ExecCommandBeginEvent {
call_id,
command,
cwd: _,
}) => {
self.conversation_history
.add_active_exec_command(call_id, command);
self.request_redraw()?;
}
EventMsg::PatchApplyBegin {
EventMsg::PatchApplyBegin(codex_core::protocol::PatchApplyBeginEvent {
call_id: _,
auto_approved,
changes,
} => {
}) => {
// Even when a patch is autoapproved we still display the
// summary so the user can follow along.
self.conversation_history
@@ -297,32 +301,31 @@ impl ChatWidget<'_> {
}
self.request_redraw()?;
}
EventMsg::ExecCommandEnd {
EventMsg::ExecCommandEnd(codex_core::protocol::ExecCommandEndEvent {
call_id,
exit_code,
stdout,
stderr,
..
} => {
}) => {
self.conversation_history
.record_completed_exec_command(call_id, stdout, stderr, exit_code);
self.request_redraw()?;
}
EventMsg::McpToolCallBegin {
EventMsg::McpToolCallBegin(codex_core::protocol::McpToolCallBeginEvent {
call_id,
server,
tool,
arguments,
} => {
}) => {
self.conversation_history
.add_active_mcp_tool_call(call_id, server, tool, arguments);
self.request_redraw()?;
}
EventMsg::McpToolCallEnd {
EventMsg::McpToolCallEnd(codex_core::protocol::McpToolCallEndEvent {
call_id,
success,
result,
} => {
}) => {
self.conversation_history
.record_completed_mcp_tool_call(call_id, success, result);
self.request_redraw()?;