fix(prompt): make prompt timestamps timezone-explicit (#10209)

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Douwe M Osinga <douwe@sidewalklabs.com>
This commit is contained in:
Ellen Blaine
2026-07-13 10:43:10 -04:00
committed by GitHub
parent bb769fcf61
commit 0b98172aca
2 changed files with 30 additions and 3 deletions
+17 -1
View File
@@ -142,7 +142,7 @@ fn compose_moim(
max_turns: u32,
extension_parts: Vec<String>,
) -> String {
let timestamp = chrono::Local::now().format("%Y-%m-%d %H:%M:00");
let timestamp = chrono::Local::now().format("%Y-%m-%d %H:%M:00 %:z");
let mut lines = vec![
open_tag(TURN_CONTEXT_TAG),
tag(CURRENT_TIME_TAG, &timestamp.to_string()),
@@ -437,5 +437,21 @@ mod tests {
match: the detector's shape checks are what discriminate the injected block"
);
}
#[test]
fn current_time_is_timezone_aware() {
let block = moim(None, None, 0, 0, vec![]);
let time_line = block
.lines()
.find(|line| line.starts_with(&format!("<{CURRENT_TIME_TAG}>")))
.expect("turn-context block should contain a current-time line");
let value = time_line
.trim_start_matches(&format!("<{CURRENT_TIME_TAG}>"))
.trim_end_matches(&format!("</{CURRENT_TIME_TAG}>"));
chrono::DateTime::parse_from_str(value, "%Y-%m-%d %H:%M:%S %:z")
.expect("current-time should include a numeric UTC offset");
}
}
}
+13 -2
View File
@@ -206,7 +206,7 @@ impl PromptManager {
system_prompt_extras: IndexMap::new(),
// Use the fixed current date time so that prompt cache can be used.
// Filtering to an hour to balance user time accuracy and multi session prompt cache hits.
current_date_timestamp: Utc::now().format("%Y-%m-%d %H:00").to_string(),
current_date_timestamp: Utc::now().format("%Y-%m-%d %H:00 %:z").to_string(),
subdirectory_hint_tracker: SubdirectoryHintTracker::new(),
}
}
@@ -216,7 +216,7 @@ impl PromptManager {
PromptManager {
system_prompt_override: None,
system_prompt_extras: IndexMap::new(),
current_date_timestamp: dt.format("%Y-%m-%d %H:%M:%S").to_string(),
current_date_timestamp: dt.format("%Y-%m-%d %H:%M:%S %:z").to_string(),
subdirectory_hint_tracker: SubdirectoryHintTracker::new(),
}
}
@@ -300,6 +300,17 @@ mod tests {
assert!(result.contains("with hidden text"));
}
#[test]
fn test_current_date_time_includes_timezone() {
let mut manager =
PromptManager::with_timestamp(DateTime::<Utc>::from_timestamp(0, 0).unwrap());
manager.set_system_prompt_override("It is currently {{current_date_time}}".to_string());
let result = manager.builder().build();
assert_eq!(result, "It is currently 1970-01-01 00:00:00 +00:00");
}
#[test]
fn test_build_system_prompt_sanitizes_extras() {
let mut manager = PromptManager::new();