chore: keep request_user_input tool to persist cache on multi-agents (#17009)

This commit is contained in:
jif-oai
2026-04-07 17:53:31 +02:00
committed by GitHub
Unverified
parent 413c1e1fdf
commit 4cc6818996
6 changed files with 93 additions and 21 deletions
@@ -5,6 +5,7 @@ use crate::tools::context::ToolPayload;
use crate::tools::handlers::parse_arguments;
use crate::tools::registry::ToolHandler;
use crate::tools::registry::ToolKind;
use codex_protocol::protocol::SessionSource;
use codex_protocol::request_user_input::RequestUserInputArgs;
use codex_tools::REQUEST_USER_INPUT_TOOL_NAME;
use codex_tools::normalize_request_user_input_args;
@@ -39,6 +40,12 @@ impl ToolHandler for RequestUserInputHandler {
}
};
if matches!(turn.session_source, SessionSource::SubAgent(_)) {
return Err(FunctionCallError::RespondToModel(
"request_user_input can only be used by the root thread".to_string(),
));
}
let mode = session.collaboration_mode().await.mode;
if let Some(message) =
request_user_input_unavailable_message(mode, self.default_mode_request_user_input)
@@ -67,3 +74,7 @@ impl ToolHandler for RequestUserInputHandler {
Ok(FunctionToolOutput::from_text(content, Some(true)))
}
}
#[cfg(test)]
#[path = "request_user_input_tests.rs"]
mod tests;
@@ -0,0 +1,66 @@
use super::*;
use crate::codex::make_session_and_context;
use crate::tools::context::ToolInvocation;
use crate::tools::context::ToolPayload;
use crate::turn_diff_tracker::TurnDiffTracker;
use codex_protocol::ThreadId;
use codex_protocol::protocol::SubAgentSource;
use pretty_assertions::assert_eq;
use serde_json::json;
use std::sync::Arc;
use tokio::sync::Mutex;
#[tokio::test]
async fn multi_agent_v2_request_user_input_rejects_subagent_threads() {
let (session, mut turn) = make_session_and_context().await;
turn.session_source = SessionSource::SubAgent(SubAgentSource::ThreadSpawn {
parent_thread_id: ThreadId::new(),
depth: 1,
agent_path: None,
agent_nickname: None,
agent_role: None,
});
let result = RequestUserInputHandler {
default_mode_request_user_input: true,
}
.handle(ToolInvocation {
session: Arc::new(session),
turn: Arc::new(turn),
tracker: Arc::new(Mutex::new(TurnDiffTracker::default())),
call_id: "call-1".to_string(),
tool_name: REQUEST_USER_INPUT_TOOL_NAME.to_string(),
tool_namespace: None,
payload: ToolPayload::Function {
arguments: json!({
"questions": [{
"header": "Hdr",
"question": "Pick one",
"id": "pick_one",
"options": [
{
"label": "A",
"description": "A"
},
{
"label": "B",
"description": "B"
}
]
}]
})
.to_string(),
},
})
.await;
let Err(err) = result else {
panic!("sub-agent request_user_input should fail");
};
assert_eq!(
err,
FunctionCallError::RespondToModel(
"request_user_input can only be used by the root thread".to_string(),
)
);
}