Merge b491a22a8e into sapling-pr-archive-bolinfest

This commit is contained in:
Michael Bolin
2026-06-23 17:39:27 -07:00
committed by GitHub
3 changed files with 79 additions and 1 deletions
+1
View File
@@ -2828,6 +2828,7 @@ impl Session {
std::slice::from_ref(&response_item),
);
let items = items.as_ref();
communication.id = items.first().and_then(ResponseItem::id).map(str::to_string);
{
let mut state = self.state.lock().await;
state.record_items(
+69
View File
@@ -1776,6 +1776,75 @@ async fn record_inter_agent_communication_sets_turn_id_in_rollout_and_resume() {
);
}
#[tokio::test]
async fn record_inter_agent_communication_preserves_item_id_in_rollout_and_resume() {
let (mut session, turn_context, _rx) = make_session_and_context_with_auth_and_config_and_rx(
CodexAuth::from_api_key("Test API Key"),
Vec::new(),
|config| {
let _ = config.features.enable(Feature::ItemIds);
},
)
.await;
let rollout_path =
attach_thread_persistence(Arc::get_mut(&mut session).expect("unique session")).await;
let communication = InterAgentCommunication::new(
AgentPath::root().join("worker").expect("worker path"),
AgentPath::root(),
Vec::new(),
"child done".to_string(),
/*trigger_turn*/ false,
);
session
.record_inter_agent_communication(&turn_context, communication)
.await;
let live_history = session.clone_history().await;
let [live_item] = live_history.raw_items() else {
panic!("expected exactly one live history item");
};
let live_item_id = live_item
.id()
.expect("live agent message should have an item id")
.to_string();
assert!(live_item_id.starts_with("amsg_"));
session.flush_rollout().await.expect("rollout should flush");
let InitialHistory::Resumed(resumed) = RolloutRecorder::get_rollout_history(&rollout_path)
.await
.expect("read rollout history")
else {
panic!("expected resumed rollout history");
};
let persisted_communication = resumed.history.iter().find_map(|item| match item {
RolloutItem::InterAgentCommunication(communication) => Some(communication),
_ => None,
});
assert_eq!(
persisted_communication.and_then(|communication| communication.id.as_deref()),
Some(live_item_id.as_str())
);
let (resumed_session, _resumed_turn_context, _rx) =
make_session_and_context_with_auth_and_config_and_rx(
CodexAuth::from_api_key("Test API Key"),
Vec::new(),
|config| {
let _ = config.features.enable(Feature::ItemIds);
},
)
.await;
resumed_session
.record_initial_history(InitialHistory::Resumed(resumed))
.await;
let resumed_history = resumed_session.clone_history().await;
let [resumed_item] = resumed_history.raw_items() else {
panic!("expected exactly one resumed history item");
};
assert_eq!(resumed_item.id(), Some(live_item_id.as_str()));
}
#[tokio::test]
async fn prepares_image_failures_before_history_insertion() {
let (session, turn_context, _rx) = make_session_and_context_with_auth_and_config_and_rx(
+9 -1
View File
@@ -692,6 +692,9 @@ impl From<Vec<UserInput>> for Op {
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, JsonSchema, TS)]
pub struct InterAgentCommunication {
#[serde(default, skip_serializing_if = "Option::is_none")]
#[ts(optional)]
pub id: Option<String>,
pub author: AgentPath,
pub recipient: AgentPath,
#[serde(default)]
@@ -715,6 +718,7 @@ impl InterAgentCommunication {
trigger_turn: bool,
) -> Self {
Self {
id: None,
author,
recipient,
other_recipients,
@@ -733,6 +737,7 @@ impl InterAgentCommunication {
trigger_turn: bool,
) -> Self {
Self {
id: None,
author,
recipient,
other_recipients,
@@ -752,6 +757,7 @@ impl InterAgentCommunication {
pub fn to_response_input_item(&self) -> ResponseInputItem {
let mut communication = self.clone();
communication.id = None;
communication.internal_chat_message_metadata_passthrough = None;
ResponseInputItem::Message {
role: "assistant".to_string(),
@@ -787,7 +793,7 @@ impl InterAgentCommunication {
}],
};
ResponseItem::AgentMessage {
id: None,
id: self.id.clone(),
author: self.author.to_string(),
recipient: self.recipient.to_string(),
content,
@@ -4374,6 +4380,7 @@ mod tests {
#[test]
fn inter_agent_communication_response_input_item_preserves_commentary_phase() {
let mut communication = InterAgentCommunication {
id: Some("amsg_1".to_string()),
author: AgentPath::root(),
recipient: AgentPath::root().join("reviewer").expect("recipient path"),
other_recipients: vec![AgentPath::root().join("worker").expect("recipient path")],
@@ -4384,6 +4391,7 @@ mod tests {
};
communication.set_turn_id_if_missing("turn-1");
let mut serialized_communication = communication.clone();
serialized_communication.id = None;
serialized_communication.internal_chat_message_metadata_passthrough = None;
assert_eq!(