Limit collab completion metadata to spawn and resume

This commit is contained in:
Ahmed Ibrahim
2026-03-11 21:04:12 -07:00
parent cfb3b3e56c
commit 271b723b44
4 changed files with 61 additions and 30 deletions
@@ -729,8 +729,8 @@ impl ThreadHistoryBuilder {
sender_thread_id: payload.sender_thread_id.to_string(),
receiver_thread_ids: vec![receiver_id],
prompt: None,
model: payload.model.clone(),
reasoning_effort: payload.reasoning_effort,
model: None,
reasoning_effort: None,
agents_states,
});
}
@@ -2419,6 +2419,60 @@ mod tests {
);
}
#[test]
fn reconstructs_collab_close_end_item_without_model_metadata() {
let sender_thread_id = ThreadId::try_from("00000000-0000-0000-0000-000000000001")
.expect("valid sender thread id");
let receiver_thread_id = ThreadId::try_from("00000000-0000-0000-0000-000000000002")
.expect("valid receiver thread id");
let events = vec![
EventMsg::UserMessage(UserMessageEvent {
message: "close agent".into(),
images: None,
text_elements: Vec::new(),
local_images: Vec::new(),
}),
EventMsg::CollabCloseEnd(codex_protocol::protocol::CollabCloseEndEvent {
call_id: "close-1".into(),
sender_thread_id,
receiver_thread_id,
receiver_agent_nickname: Some("Scout".into()),
receiver_agent_role: Some("explorer".into()),
status: AgentStatus::Completed(None),
}),
];
let items = events
.into_iter()
.map(RolloutItem::EventMsg)
.collect::<Vec<_>>();
let turns = build_turns_from_rollout_items(&items);
assert_eq!(turns.len(), 1);
assert_eq!(turns[0].items.len(), 2);
assert_eq!(
turns[0].items[1],
ThreadItem::CollabAgentToolCall {
id: "close-1".into(),
tool: CollabAgentTool::CloseAgent,
status: CollabAgentToolCallStatus::Completed,
sender_thread_id: "00000000-0000-0000-0000-000000000001".into(),
receiver_thread_ids: vec!["00000000-0000-0000-0000-000000000002".into()],
prompt: None,
model: None,
reasoning_effort: None,
agents_states: [(
"00000000-0000-0000-0000-000000000002".into(),
CollabAgentState {
status: crate::protocol::v2::CollabAgentStatus::Completed,
message: None,
},
)]
.into_iter()
.collect(),
}
);
}
#[test]
fn rollback_failed_error_does_not_mark_turn_failed() {
let events = vec![
@@ -1078,8 +1078,8 @@ pub(crate) async fn apply_bespoke_event_handling(
sender_thread_id: end_event.sender_thread_id.to_string(),
receiver_thread_ids: vec![receiver_id],
prompt: None,
model: end_event.model,
reasoning_effort: end_event.reasoning_effort,
model: None,
reasoning_effort: None,
agents_states,
};
let notification = ItemCompletedNotification {
@@ -745,25 +745,12 @@ pub mod close_agent {
) -> Result<FunctionToolOutput, FunctionCallError> {
let args: CloseAgentArgs = parse_arguments(&arguments)?;
let agent_id = agent_id(&args.id)?;
let (
receiver_agent_nickname,
receiver_agent_role,
receiver_model,
receiver_reasoning_effort,
) = session
let (receiver_agent_nickname, receiver_agent_role) = session
.services
.agent_control
.get_agent_metadata(agent_id)
.get_agent_nickname_and_role(agent_id)
.await
.map(|metadata| {
(
metadata.nickname,
metadata.role,
Some(metadata.model),
metadata.reasoning_effort,
)
})
.unwrap_or((None, None, None, None));
.unwrap_or((None, None));
session
.send_event(
&turn,
@@ -793,8 +780,6 @@ pub mod close_agent {
receiver_thread_id: agent_id,
receiver_agent_nickname: receiver_agent_nickname.clone(),
receiver_agent_role: receiver_agent_role.clone(),
model: receiver_model.clone(),
reasoning_effort: receiver_reasoning_effort,
status,
}
.into(),
@@ -823,8 +808,6 @@ pub mod close_agent {
receiver_thread_id: agent_id,
receiver_agent_nickname,
receiver_agent_role,
model: receiver_model,
reasoning_effort: receiver_reasoning_effort,
status: status.clone(),
}
.into(),
-6
View File
@@ -3269,12 +3269,6 @@ pub struct CollabCloseEndEvent {
/// Optional role assigned to the receiver agent.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub receiver_agent_role: Option<String>,
/// Model configured for the receiver agent when available.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub model: Option<String>,
/// Reasoning effort configured for the receiver agent when available.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub reasoning_effort: Option<ReasoningEffortConfig>,
/// Last known status of the receiver agent reported to the sender agent before
/// the close.
pub status: AgentStatus,