mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
[codex] Move pending input into input queue (#22728)
## Why Pending model input was split across `Session`, `TurnState`, and the agent mailbox. That made it easy for new paths to manage queued user input or mailbox delivery outside the intended ownership boundary. This PR consolidates the model-facing input lifecycle behind the session input queue so turn-local pending input, next-turn queued items, and mailbox delivery coordination are owned in one place. ## What Changed - Added `session/input_queue.rs` to own pending input queues and mailbox delivery coordination. - Removed the standalone `agent/mailbox.rs` channel wrapper and store mailbox items directly in the input queue. - Moved pending-input mutations off `TurnState`; `TurnState` now exposes the queue-owned storage directly for now. - Routed abort cleanup, mailbox delivery phase changes, next-turn queued items, and active-turn pending input through `InputQueue`. - Boxed stack-heavy agent resume/fork startup futures that the refactor pushed over the default test stack. - Updated session, task, goal, stream-event, and multi-agent call sites and tests to use the new queue ownership. ## Verification - `cargo test -p codex-core --lib agent::control::tests` - `cargo test -p codex-core --lib agent::control::tests::resume_closed_child_reopens_open_descendants -- --exact` - `cargo test -p codex-core --lib agent::control::tests::spawn_agent_fork_last_n_turns_keeps_only_recent_turns -- --exact` - `cargo test -p codex-core --lib agent::control::tests::resume_thread_subagent_restores_stored_nickname_and_role -- --exact` - `cargo test -p codex-core` was also run; it completed with 1814 passed, 4 ignored, and one timeout in `agent::control::tests::resume_thread_subagent_restores_stored_nickname_and_role`, which passed when rerun in isolation.
This commit is contained in:
committed by
GitHub
Unverified
parent
a66e0e9c4b
commit
afa0101ae2
@@ -2791,13 +2791,16 @@ async fn multi_agent_v2_wait_agent_accepts_timeout_only_argument() {
|
||||
});
|
||||
tokio::task::yield_now().await;
|
||||
|
||||
session.enqueue_mailbox_communication(InterAgentCommunication::new(
|
||||
worker_path,
|
||||
AgentPath::root(),
|
||||
Vec::new(),
|
||||
"hello from worker".to_string(),
|
||||
/*trigger_turn*/ false,
|
||||
));
|
||||
session
|
||||
.input_queue
|
||||
.enqueue_mailbox_communication(InterAgentCommunication::new(
|
||||
worker_path,
|
||||
AgentPath::root(),
|
||||
Vec::new(),
|
||||
"hello from worker".to_string(),
|
||||
/*trigger_turn*/ false,
|
||||
))
|
||||
.await;
|
||||
|
||||
let output = wait_task
|
||||
.await
|
||||
@@ -3276,13 +3279,16 @@ async fn multi_agent_v2_wait_agent_returns_summary_for_mailbox_activity() {
|
||||
});
|
||||
tokio::task::yield_now().await;
|
||||
|
||||
session.enqueue_mailbox_communication(InterAgentCommunication::new(
|
||||
worker_path,
|
||||
AgentPath::root(),
|
||||
Vec::new(),
|
||||
"completed".to_string(),
|
||||
/*trigger_turn*/ false,
|
||||
));
|
||||
session
|
||||
.input_queue
|
||||
.enqueue_mailbox_communication(InterAgentCommunication::new(
|
||||
worker_path,
|
||||
AgentPath::root(),
|
||||
Vec::new(),
|
||||
"completed".to_string(),
|
||||
/*trigger_turn*/ false,
|
||||
))
|
||||
.await;
|
||||
|
||||
let wait_output = wait_task
|
||||
.await
|
||||
@@ -3346,13 +3352,16 @@ async fn multi_agent_v2_wait_agent_returns_for_already_queued_mail() {
|
||||
.agent_path
|
||||
.expect("worker path");
|
||||
|
||||
session.enqueue_mailbox_communication(InterAgentCommunication::new(
|
||||
worker_path,
|
||||
AgentPath::root(),
|
||||
Vec::new(),
|
||||
"already queued".to_string(),
|
||||
/*trigger_turn*/ false,
|
||||
));
|
||||
session
|
||||
.input_queue
|
||||
.enqueue_mailbox_communication(InterAgentCommunication::new(
|
||||
worker_path,
|
||||
AgentPath::root(),
|
||||
Vec::new(),
|
||||
"already queued".to_string(),
|
||||
/*trigger_turn*/ false,
|
||||
))
|
||||
.await;
|
||||
|
||||
let output = timeout(
|
||||
Duration::from_millis(500),
|
||||
@@ -3442,13 +3451,16 @@ async fn multi_agent_v2_wait_agent_wakes_on_any_mailbox_notification() {
|
||||
});
|
||||
tokio::task::yield_now().await;
|
||||
|
||||
session.enqueue_mailbox_communication(InterAgentCommunication::new(
|
||||
worker_b_path,
|
||||
AgentPath::root(),
|
||||
Vec::new(),
|
||||
"from worker b".to_string(),
|
||||
/*trigger_turn*/ false,
|
||||
));
|
||||
session
|
||||
.input_queue
|
||||
.enqueue_mailbox_communication(InterAgentCommunication::new(
|
||||
worker_b_path,
|
||||
AgentPath::root(),
|
||||
Vec::new(),
|
||||
"from worker b".to_string(),
|
||||
/*trigger_turn*/ false,
|
||||
))
|
||||
.await;
|
||||
|
||||
let output = wait_task
|
||||
.await
|
||||
@@ -3527,13 +3539,16 @@ async fn multi_agent_v2_wait_agent_does_not_return_completed_content() {
|
||||
});
|
||||
tokio::task::yield_now().await;
|
||||
|
||||
session.enqueue_mailbox_communication(InterAgentCommunication::new(
|
||||
worker_path,
|
||||
AgentPath::root(),
|
||||
Vec::new(),
|
||||
"sensitive child output".to_string(),
|
||||
/*trigger_turn*/ false,
|
||||
));
|
||||
session
|
||||
.input_queue
|
||||
.enqueue_mailbox_communication(InterAgentCommunication::new(
|
||||
worker_path,
|
||||
AgentPath::root(),
|
||||
Vec::new(),
|
||||
"sensitive child output".to_string(),
|
||||
/*trigger_turn*/ false,
|
||||
))
|
||||
.await;
|
||||
|
||||
let output = wait_task
|
||||
.await
|
||||
|
||||
@@ -60,7 +60,7 @@ impl ToolExecutor<ToolInvocation> for Handler {
|
||||
None => default_timeout_ms,
|
||||
};
|
||||
|
||||
let mut mailbox_seq_rx = session.subscribe_mailbox_seq();
|
||||
let mut mailbox_rx = session.input_queue.subscribe_mailbox().await;
|
||||
|
||||
session
|
||||
.send_event(
|
||||
@@ -76,12 +76,8 @@ impl ToolExecutor<ToolInvocation> for Handler {
|
||||
)
|
||||
.await;
|
||||
|
||||
let timed_out = if session.has_pending_mailbox_items().await {
|
||||
false
|
||||
} else {
|
||||
let deadline = Instant::now() + Duration::from_millis(timeout_ms as u64);
|
||||
!wait_for_mailbox_change(&mut mailbox_seq_rx, deadline).await
|
||||
};
|
||||
let deadline = Instant::now() + Duration::from_millis(timeout_ms as u64);
|
||||
let timed_out = !wait_for_mailbox_change(&mut mailbox_rx, deadline).await;
|
||||
let result = WaitAgentResult::from_timed_out(timed_out);
|
||||
|
||||
session
|
||||
@@ -153,10 +149,10 @@ impl ToolOutput for WaitAgentResult {
|
||||
}
|
||||
|
||||
async fn wait_for_mailbox_change(
|
||||
mailbox_seq_rx: &mut tokio::sync::watch::Receiver<u64>,
|
||||
mailbox_rx: &mut tokio::sync::watch::Receiver<()>,
|
||||
deadline: Instant,
|
||||
) -> bool {
|
||||
match timeout_at(deadline, mailbox_seq_rx.changed()).await {
|
||||
match timeout_at(deadline, mailbox_rx.changed()).await {
|
||||
Ok(Ok(())) => true,
|
||||
Ok(Err(_)) | Err(_) => false,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user