mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
feat: tasks can't be assigned to root agent (#16424)
This commit is contained in:
committed by
GitHub
Unverified
parent
3152d1a557
commit
0c776c433b
@@ -709,6 +709,86 @@ async fn multi_agent_v2_send_message_accepts_root_target_from_child() {
|
||||
}));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn multi_agent_v2_assign_task_rejects_root_target_from_child() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
let manager = thread_manager();
|
||||
let root = manager
|
||||
.start_thread((*turn.config).clone())
|
||||
.await
|
||||
.expect("root thread should start");
|
||||
session.services.agent_control = manager.agent_control();
|
||||
session.conversation_id = root.thread_id;
|
||||
let mut config = (*turn.config).clone();
|
||||
config
|
||||
.features
|
||||
.enable(Feature::MultiAgentV2)
|
||||
.expect("test config should allow feature update");
|
||||
turn.config = Arc::new(config);
|
||||
|
||||
let child_path = AgentPath::try_from("/root/worker").expect("agent path");
|
||||
let child_thread_id = session
|
||||
.services
|
||||
.agent_control
|
||||
.spawn_agent_with_metadata(
|
||||
(*turn.config).clone(),
|
||||
vec![UserInput::Text {
|
||||
text: "inspect this repo".to_string(),
|
||||
text_elements: Vec::new(),
|
||||
}]
|
||||
.into(),
|
||||
Some(SessionSource::SubAgent(SubAgentSource::ThreadSpawn {
|
||||
parent_thread_id: root.thread_id,
|
||||
depth: 1,
|
||||
agent_path: Some(child_path.clone()),
|
||||
agent_nickname: None,
|
||||
agent_role: None,
|
||||
})),
|
||||
crate::agent::control::SpawnAgentOptions::default(),
|
||||
)
|
||||
.await
|
||||
.expect("worker spawn should succeed")
|
||||
.thread_id;
|
||||
session.conversation_id = child_thread_id;
|
||||
turn.session_source = SessionSource::SubAgent(SubAgentSource::ThreadSpawn {
|
||||
parent_thread_id: root.thread_id,
|
||||
depth: 1,
|
||||
agent_path: Some(child_path),
|
||||
agent_nickname: None,
|
||||
agent_role: None,
|
||||
});
|
||||
|
||||
let err = AssignTaskHandlerV2
|
||||
.handle(invocation(
|
||||
Arc::new(session),
|
||||
Arc::new(turn),
|
||||
"assign_task",
|
||||
function_payload(json!({
|
||||
"target": "/root",
|
||||
"message": "run this",
|
||||
"interrupt": true
|
||||
})),
|
||||
))
|
||||
.await
|
||||
.expect_err("assign_task should reject the root target");
|
||||
|
||||
assert_eq!(
|
||||
err,
|
||||
FunctionCallError::RespondToModel("Tasks can't be assigned to the root agent".to_string())
|
||||
);
|
||||
let root_ops = manager
|
||||
.captured_ops()
|
||||
.into_iter()
|
||||
.filter_map(|(id, op)| (id == root.thread_id).then_some(op))
|
||||
.collect::<Vec<_>>();
|
||||
assert!(!root_ops.iter().any(|op| matches!(op, Op::Interrupt)));
|
||||
assert!(
|
||||
!root_ops
|
||||
.iter()
|
||||
.any(|op| matches!(op, Op::InterAgentCommunication { .. }))
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn multi_agent_v2_list_agents_returns_completed_status_and_last_task_message() {
|
||||
let (mut session, mut turn) = make_session_and_context().await;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
use super::*;
|
||||
use codex_protocol::protocol::InterAgentCommunication;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub(crate) enum MessageDeliveryMode {
|
||||
QueueOnly,
|
||||
TriggerTurn,
|
||||
@@ -118,6 +118,16 @@ async fn handle_message_submission(
|
||||
.agent_control
|
||||
.get_agent_metadata(receiver_thread_id)
|
||||
.unwrap_or_default();
|
||||
if mode == MessageDeliveryMode::TriggerTurn
|
||||
&& receiver_agent
|
||||
.agent_path
|
||||
.as_ref()
|
||||
.is_some_and(AgentPath::is_root)
|
||||
{
|
||||
return Err(FunctionCallError::RespondToModel(
|
||||
"Tasks can't be assigned to the root agent".to_string(),
|
||||
));
|
||||
}
|
||||
if interrupt {
|
||||
session
|
||||
.services
|
||||
|
||||
@@ -179,7 +179,7 @@ pub fn create_assign_task_tool() -> ToolSpec {
|
||||
|
||||
ToolSpec::Function(ResponsesApiTool {
|
||||
name: "assign_task".to_string(),
|
||||
description: "Add a message to an existing agent and trigger a turn in the target. Use interrupt=true to redirect work immediately. In MultiAgentV2, this tool currently supports text content only."
|
||||
description: "Add a message to an existing non-root agent and trigger a turn in the target. Use interrupt=true to redirect work immediately. In MultiAgentV2, this tool currently supports text content only."
|
||||
.to_string(),
|
||||
strict: false,
|
||||
defer_loading: None,
|
||||
|
||||
Reference in New Issue
Block a user