Record realtime close marker on replacement (#13058)

## Summary
- record a realtime close developer message when a new realtime session
replaces an active one
- assert the replacement marker through the mocked responses request
path

---------

Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Charles Cunningham <ccunningham@openai.com>
This commit is contained in:
Ahmed Ibrahim
2026-03-01 13:54:12 -08:00
committed by GitHub
parent c9cef6ba9e
commit 0aeb55bf08
27 changed files with 1292 additions and 214 deletions

View File

@@ -214,11 +214,14 @@ pub fn format_labeled_items_snapshot(
fn format_snapshot_text(text: &str, options: &ContextSnapshotOptions) -> String {
match options.render_mode {
ContextSnapshotRenderMode::RedactedText => {
canonicalize_snapshot_text(text).replace('\n', "\\n")
normalize_snapshot_line_endings(&canonicalize_snapshot_text(text)).replace('\n', "\\n")
}
ContextSnapshotRenderMode::FullText => {
normalize_snapshot_line_endings(text).replace('\n', "\\n")
}
ContextSnapshotRenderMode::FullText => text.replace('\n', "\\n"),
ContextSnapshotRenderMode::KindWithTextPrefix { max_chars } => {
let normalized = canonicalize_snapshot_text(text).replace('\n', "\\n");
let normalized = normalize_snapshot_line_endings(&canonicalize_snapshot_text(text))
.replace('\n', "\\n");
if normalized.chars().count() <= max_chars {
normalized
} else {
@@ -230,6 +233,10 @@ fn format_snapshot_text(text: &str, options: &ContextSnapshotOptions) -> String
}
}
fn normalize_snapshot_line_endings(text: &str) -> String {
text.replace("\r\n", "\n").replace('\r', "\n")
}
fn canonicalize_snapshot_text(text: &str) -> String {
if text.starts_with("<permissions instructions>") {
return "<PERMISSIONS_INSTRUCTIONS>".to_string();
@@ -308,6 +315,25 @@ mod tests {
);
}
#[test]
fn full_text_mode_normalizes_crlf_line_endings() {
let items = vec![json!({
"type": "message",
"role": "user",
"content": [{
"type": "input_text",
"text": "line one\r\n\r\nline two"
}]
})];
let rendered = format_response_items_snapshot(
&items,
&ContextSnapshotOptions::default().render_mode(ContextSnapshotRenderMode::FullText),
);
assert_eq!(rendered, r"00:message/user:line one\n\nline two");
}
#[test]
fn redacted_text_mode_keeps_canonical_placeholders() {
let items = vec![json!({
@@ -349,6 +375,29 @@ mod tests {
);
}
#[test]
fn kind_with_text_prefix_mode_normalizes_crlf_line_endings() {
let items = vec![json!({
"type": "message",
"role": "developer",
"content": [{
"type": "input_text",
"text": "<realtime_conversation>\r\nRealtime conversation started.\r\n\r\nYou are..."
}]
})];
let rendered = format_response_items_snapshot(
&items,
&ContextSnapshotOptions::default()
.render_mode(ContextSnapshotRenderMode::KindWithTextPrefix { max_chars: 64 }),
);
assert_eq!(
rendered,
r"00:message/developer:<realtime_conversation>\nRealtime conversation started.\n\nYou a..."
);
}
#[test]
fn image_only_message_is_rendered_as_non_text_span() {
let items = vec![json!({