Merge branch 'rhan/surface-updates' into rhan/emittance

This commit is contained in:
rhan-oai
2026-03-19 15:24:02 -07:00
committed by GitHub
6 changed files with 101 additions and 16 deletions
+1 -6
View File
@@ -46,12 +46,7 @@ pub struct Prompt {
impl Prompt {
pub(crate) fn get_formatted_input(&self) -> Vec<ResponseItem> {
let mut input: Vec<ResponseItem> = self
.input
.clone()
.into_iter()
.map(ResponseItem::with_generated_metadata_uuid)
.collect();
let mut input = self.input.clone();
// when using the *Freeform* apply_patch tool specifically, tool outputs
// should be structured text, not json. Do NOT reserialize when using
+37 -3
View File
@@ -202,7 +202,7 @@ fn reserializes_shell_outputs_for_function_and_custom_tool_calls() {
}
#[test]
fn formatted_input_generates_message_metadata_uuid() {
fn formatted_input_does_not_generate_message_metadata_uuid_when_disabled() {
let prompt = Prompt {
input: vec![ResponseItem::Message {
id: Some("msg_123".to_string()),
@@ -227,8 +227,42 @@ fn formatted_input_generates_message_metadata_uuid() {
ResponseItem::Message { metadata, .. } => {
let metadata = metadata.as_ref().expect("metadata should be present");
assert_eq!(metadata.user_message_type, Some(UserMessageType::Prompt));
let uuid = metadata.uuid.as_deref().expect("uuid should be present");
uuid::Uuid::parse_str(uuid).expect("uuid should be valid");
assert_eq!(metadata.uuid, None);
}
other => panic!("expected message item, got {other:?}"),
}
}
#[test]
fn formatted_input_preserves_existing_message_metadata_uuid() {
let prompt = Prompt {
input: vec![ResponseItem::Message {
id: Some("msg_123".to_string()),
role: "user".to_string(),
content: vec![ContentItem::InputText {
text: "hello".to_string(),
}],
metadata: Some(ResponseItemMetadata {
user_message_type: Some(UserMessageType::Prompt),
uuid: Some("2585a800-7d93-4f52-8648-d9cb39f413d2".to_string()),
}),
end_turn: None,
phase: None,
}],
..Default::default()
};
let formatted = prompt.get_formatted_input();
assert_eq!(formatted.len(), 1);
match &formatted[0] {
ResponseItem::Message { metadata, .. } => {
let metadata = metadata.as_ref().expect("metadata should be present");
assert_eq!(metadata.user_message_type, Some(UserMessageType::Prompt));
assert_eq!(
metadata.uuid.as_deref(),
Some("2585a800-7d93-4f52-8648-d9cb39f413d2")
);
}
other => panic!("expected message item, got {other:?}"),
}
+25 -6
View File
@@ -3272,12 +3272,9 @@ impl Session {
turn_context: &TurnContext,
items: &[ResponseItem],
) {
let items: Vec<ResponseItem> = items
.iter()
.cloned()
.map(ResponseItem::with_generated_metadata_uuid)
.collect();
self.record_into_history(&items, turn_context).await;
let items = self.prepare_history_items(items);
self.record_into_history_prepared(&items, turn_context)
.await;
self.persist_rollout_response_items(&items).await;
self.send_raw_response_items(turn_context, &items).await;
}
@@ -3287,6 +3284,28 @@ impl Session {
&self,
items: &[ResponseItem],
turn_context: &TurnContext,
) {
let items = self.prepare_history_items(items);
self.record_into_history_prepared(&items, turn_context)
.await;
}
fn prepare_history_items(&self, items: &[ResponseItem]) -> Vec<ResponseItem> {
if self.enabled(Feature::ItemMetadata) {
items
.iter()
.cloned()
.map(ResponseItem::with_generated_metadata_uuid)
.collect()
} else {
items.to_vec()
}
}
async fn record_into_history_prepared(
&self,
items: &[ResponseItem],
turn_context: &TurnContext,
) {
let mut state = self.state.lock().await;
state.record_items(items.iter(), turn_context.truncation_policy);
+31
View File
@@ -4479,6 +4479,37 @@ async fn steer_input_returns_active_turn_id() {
);
}
#[tokio::test]
async fn record_into_history_generates_message_metadata_uuid_when_item_metadata_enabled() {
let (mut sess, tc) = make_session_and_context().await;
let _ = sess.features.enable(crate::features::Feature::ItemMetadata);
let item = ResponseItem::Message {
id: Some("msg_123".to_string()),
role: "user".to_string(),
content: vec![ContentItem::InputText {
text: "hello".to_string(),
}],
metadata: None,
end_turn: None,
phase: None,
};
sess.record_into_history(std::slice::from_ref(&item), &tc)
.await;
let history = sess.state.lock().await.clone_history();
let [ResponseItem::Message { metadata, .. }] = history.raw_items() else {
panic!("expected a single message item in history");
};
let uuid = metadata
.as_ref()
.and_then(|metadata| metadata.uuid.as_deref())
.expect("uuid should be generated when item metadata is enabled");
uuid::Uuid::parse_str(uuid).expect("uuid should be valid");
}
#[tokio::test]
async fn prepend_pending_input_keeps_older_tail_ahead_of_newer_input() {
let (sess, tc, _rx) = make_session_and_context_with_rx().await;
+1 -1
View File
@@ -172,7 +172,7 @@ pub enum Feature {
ToolCallMcpElicitation,
/// Enable personality selection in the TUI.
Personality,
/// Emit item-level metadata on request/response items.
/// Emit item-level metadata on request/response items and generated UUIDs.
ItemMetadata,
/// Enable native artifact tools.
Artifact,
+6
View File
@@ -136,6 +136,12 @@ fn image_detail_original_feature_is_under_development() {
assert_eq!(Feature::ImageDetailOriginal.default_enabled(), false);
}
#[test]
fn item_metadata_is_under_development_and_disabled_by_default() {
assert_eq!(Feature::ItemMetadata.stage(), Stage::UnderDevelopment);
assert_eq!(Feature::ItemMetadata.default_enabled(), false);
}
#[test]
fn collab_is_legacy_alias_for_multi_agent() {
assert_eq!(feature_for_key("multi_agent"), Some(Feature::Collab));