add uuid to ubiquitously

This commit is contained in:
Roy Han
2026-03-19 18:16:18 -07:00
parent 678f52a33b
commit 0a8ad342d3
3 changed files with 210 additions and 23 deletions

View File

@@ -330,6 +330,7 @@ use codex_protocol::config_types::ServiceTier;
use codex_protocol::config_types::WindowsSandboxLevel;
use codex_protocol::models::ContentItem;
use codex_protocol::models::DeveloperInstructions;
use codex_protocol::models::ReviewDecisionMetadata;
use codex_protocol::models::ResponseInputItem;
use codex_protocol::models::ResponseItem;
use codex_protocol::models::ResponseItemMetadata;
@@ -1050,6 +1051,7 @@ fn session_source_to_metadata(session_source: &SessionSource) -> SessionSourceMe
SessionSource::VSCode => SessionSourceMetadata::Vscode,
SessionSource::Exec => SessionSourceMetadata::Exec,
SessionSource::Mcp => SessionSourceMetadata::Mcp,
SessionSource::Custom(_) => SessionSourceMetadata::Unknown,
SessionSource::SubAgent(SubAgentSource::Review) => SessionSourceMetadata::SubagentReview,
SessionSource::SubAgent(SubAgentSource::Compact) => SessionSourceMetadata::SubagentCompact,
SessionSource::SubAgent(SubAgentSource::MemoryConsolidation) => {

View File

@@ -5032,34 +5032,44 @@ async fn steer_input_returns_active_turn_id() {
}
#[tokio::test]
async fn record_into_history_generates_message_metadata_uuid_when_item_metadata_enabled() {
async fn record_into_history_generates_metadata_uuid_for_metadata_bearing_items_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,
};
let items = [
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,
},
ResponseItem::FunctionCallOutput {
call_id: "call_123".to_string(),
output: FunctionCallOutputPayload::from_text("ok".to_string()),
metadata: None,
},
];
sess.record_into_history(std::slice::from_ref(&item), &tc)
.await;
sess.record_into_history(&items, &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");
};
for item in history.raw_items() {
let metadata = match item {
ResponseItem::Message { metadata, .. }
| ResponseItem::FunctionCallOutput { metadata, .. } => metadata,
other => panic!("unexpected item in history: {other:?}"),
};
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");
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]

View File

@@ -363,7 +363,7 @@ impl ResponseItemMetadata {
}
impl ResponseItem {
/// Ensures message metadata includes a generated UUID.
/// Ensures metadata includes a generated UUID for any item variant that carries metadata.
pub fn with_generated_metadata_uuid(self) -> Self {
match self {
ResponseItem::Message {
@@ -384,6 +384,148 @@ impl ResponseItem {
phase,
}
}
ResponseItem::Reasoning {
id,
summary,
content,
encrypted_content,
metadata,
} => ResponseItem::Reasoning {
id,
summary,
content,
encrypted_content,
metadata: ensure_generated_metadata_uuid(metadata),
},
ResponseItem::LocalShellCall {
id,
call_id,
status,
action,
metadata,
} => ResponseItem::LocalShellCall {
id,
call_id,
status,
action,
metadata: ensure_generated_metadata_uuid(metadata),
},
ResponseItem::FunctionCall {
id,
name,
namespace,
arguments,
call_id,
metadata,
} => ResponseItem::FunctionCall {
id,
name,
namespace,
arguments,
call_id,
metadata: ensure_generated_metadata_uuid(metadata),
},
ResponseItem::ToolSearchCall {
id,
call_id,
status,
execution,
arguments,
metadata,
} => ResponseItem::ToolSearchCall {
id,
call_id,
status,
execution,
arguments,
metadata: ensure_generated_metadata_uuid(metadata),
},
ResponseItem::FunctionCallOutput {
call_id,
output,
metadata,
} => ResponseItem::FunctionCallOutput {
call_id,
output,
metadata: ensure_generated_metadata_uuid(metadata),
},
ResponseItem::CustomToolCall {
id,
status,
call_id,
name,
input,
metadata,
} => ResponseItem::CustomToolCall {
id,
status,
call_id,
name,
input,
metadata: ensure_generated_metadata_uuid(metadata),
},
ResponseItem::CustomToolCallOutput {
call_id,
name,
output,
metadata,
} => ResponseItem::CustomToolCallOutput {
call_id,
name,
output,
metadata: ensure_generated_metadata_uuid(metadata),
},
ResponseItem::ToolSearchOutput {
call_id,
status,
execution,
tools,
metadata,
} => ResponseItem::ToolSearchOutput {
call_id,
status,
execution,
tools,
metadata: ensure_generated_metadata_uuid(metadata),
},
ResponseItem::WebSearchCall {
id,
status,
action,
metadata,
} => ResponseItem::WebSearchCall {
id,
status,
action,
metadata: ensure_generated_metadata_uuid(metadata),
},
ResponseItem::ImageGenerationCall {
id,
status,
revised_prompt,
result,
metadata,
} => ResponseItem::ImageGenerationCall {
id,
status,
revised_prompt,
result,
metadata: ensure_generated_metadata_uuid(metadata),
},
ResponseItem::GhostSnapshot {
ghost_commit,
metadata,
} => ResponseItem::GhostSnapshot {
ghost_commit,
metadata: ensure_generated_metadata_uuid(metadata),
},
ResponseItem::Compaction {
encrypted_content,
metadata,
} => ResponseItem::Compaction {
encrypted_content,
metadata: ensure_generated_metadata_uuid(metadata),
},
other => other,
}
}
@@ -3155,7 +3297,7 @@ mod tests {
}
#[test]
fn generates_metadata_uuid_for_message_items() -> Result<()> {
fn generates_metadata_uuid_for_metadata_bearing_items() -> Result<()> {
let item = ResponseItem::Message {
id: Some("msg_123".to_string()),
role: "assistant".to_string(),
@@ -3202,6 +3344,39 @@ mod tests {
Ok(())
}
#[test]
fn generates_metadata_uuid_for_function_call_output_items() -> Result<()> {
let item = ResponseItem::FunctionCallOutput {
call_id: "call_123".to_string(),
output: FunctionCallOutputPayload::from_text("ok".to_string()),
metadata: None,
};
let surfaced = item.with_generated_metadata_uuid();
let serialized = serde_json::to_value(&surfaced)?;
let metadata = serialized
.get("metadata")
.and_then(serde_json::Value::as_object)
.expect("metadata should be present");
let uuid = metadata
.get("uuid")
.and_then(serde_json::Value::as_str)
.expect("uuid should be present");
uuid::Uuid::parse_str(uuid).expect("uuid should be valid");
assert_eq!(
serialized.get("type"),
Some(&serde_json::json!("function_call_output"))
);
assert_eq!(
serialized.get("call_id"),
Some(&serde_json::json!("call_123"))
);
Ok(())
}
#[test]
fn response_item_metadata_helpers_include_session_source() {
let mut metadata = ResponseItemMetadata::default();