mirror of
https://github.com/openai/codex.git
synced 2026-11-07 20:30:33 +00:00
## Summary - sanitize Claude-derived fallback titles without changing explicit custom or generated source titles - recognize known leading control wrappers, including `ide_opened_file`, `ide_selection`, `local-command-stdout`, and `local-command-stderr` - skip separate control-only user records and use the next meaningful user message as the fallback title - use `Imported session` only when every user record is control-only - preserve raw imported messages, previews, and transcript provenance unchanged ## Why Sessions without an explicit source title fall back to user-message content. Claude metadata can arrive as separate leading user records, so stripping only the first record still exposed raw control markup or produced an unhelpful fallback. ## Impact Imported chats now receive readable fallback titles such as `Fix auth flow`, while the original wrapper-bearing messages remain visible in the imported transcript. ## Validation - `just test -p codex-external-agent-sessions` — 37 tests passed - `just test -p codex-app-server external_agent_config_import_creates_session_rollouts` — focused integration test passed - `just fix -p codex-external-agent-sessions` - `just fix -p codex-app-server` - `just bazel-lock-check` - `just fmt`
124 lines
3.6 KiB
Rust
124 lines
3.6 KiB
Rust
use super::*;
|
|
|
|
#[test]
|
|
fn preserves_valid_custom_title_unchanged() {
|
|
let custom_title = "<system-reminder>Keep this custom title</system-reminder>";
|
|
|
|
assert_eq!(
|
|
SessionTitleCandidates {
|
|
custom_title: Some(custom_title.to_string()),
|
|
ai_title: Some("AI title".to_string()),
|
|
fallback_title: Some("fallback title".to_string()),
|
|
}
|
|
.select(),
|
|
Some(custom_title.to_string())
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn preserves_valid_ai_title_unchanged_without_custom_title() {
|
|
let ai_title = "<command-message>Keep this AI title</command-message>";
|
|
|
|
assert_eq!(
|
|
SessionTitleCandidates {
|
|
custom_title: None,
|
|
ai_title: Some(ai_title.to_string()),
|
|
fallback_title: Some("fallback title".to_string()),
|
|
}
|
|
.select(),
|
|
Some(ai_title.to_string())
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn strips_nested_repeated_and_multiline_leading_control_wrappers() {
|
|
let message = "\
|
|
<system-reminder>\n\
|
|
outer context\n\
|
|
<command-message>\n\
|
|
nested context\n\
|
|
</command-message>\n\
|
|
</system-reminder>\n\
|
|
<ide_opened_file>\n\
|
|
src/auth.rs\n\
|
|
</ide_opened_file>\n\
|
|
\n\
|
|
Fix auth flow\n\
|
|
Additional details";
|
|
|
|
assert_eq!(
|
|
fallback_title_from_user_message(message),
|
|
Some("Fix auth flow".to_string())
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn strips_observed_external_agent_control_wrapper_families() {
|
|
let cases = [
|
|
"<task-notification>\n\
|
|
<task-id>abc123</task-id>\n\
|
|
<status>completed</status>\n\
|
|
</task-notification>\n\
|
|
Fix auth flow",
|
|
"<command-message>review</command-message>\n\
|
|
<command-name>/review</command-name>\n\
|
|
<command-args>src/auth.rs</command-args>\n\
|
|
Fix auth flow",
|
|
"<local-command-caveat>Command output follows</local-command-caveat>\n\
|
|
<local-command-stdout>tests passed</local-command-stdout>\n\
|
|
Fix auth flow",
|
|
"<local-command-stderr>tests failed</local-command-stderr>\n\
|
|
Fix auth flow",
|
|
"<ide_selection>src/auth.rs:1-5</ide_selection>\n\
|
|
Fix auth flow",
|
|
];
|
|
|
|
for message in cases {
|
|
assert_eq!(
|
|
fallback_title_from_user_message(message),
|
|
Some("Fix auth flow".to_string())
|
|
);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn returns_no_candidate_for_empty_or_control_only_messages() {
|
|
assert_eq!(fallback_title_from_user_message(""), None);
|
|
assert_eq!(
|
|
fallback_title_from_user_message(
|
|
"<command-message>review</command-message>\n\
|
|
<system-reminder>context</system-reminder>"
|
|
),
|
|
None
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn uses_first_meaningful_line_from_ordinary_messages() {
|
|
assert_eq!(
|
|
fallback_title_from_user_message("\n \n Fix auth flow \nAdditional details"),
|
|
Some("Fix auth flow".to_string())
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn preserves_unknown_and_user_authored_angle_bracket_text() {
|
|
assert_eq!(
|
|
fallback_title_from_user_message("<user-note>Keep this text</user-note> Fix auth flow"),
|
|
Some("<user-note>Keep this text</user-note> Fix auth flow".to_string())
|
|
);
|
|
assert_eq!(
|
|
fallback_title_from_user_message("Explain <system-reminder> tags"),
|
|
Some("Explain <system-reminder> tags".to_string())
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn bounds_fallback_titles_to_120_characters() {
|
|
let message = "x".repeat(121);
|
|
let title = fallback_title_from_user_message(&message).expect("title");
|
|
|
|
assert_eq!(title.chars().count(), SESSION_TITLE_MAX_LEN);
|
|
assert_eq!(title, format!("{}...", "x".repeat(117)));
|
|
}
|