Skip to main content

vtcode_core/prompts/
temporal.rs

1use chrono::{DateTime, Local, Utc};
2
3/// Generate temporal context string for system prompt
4///
5/// Adds current date and time to help the LLM understand temporal context
6/// for time-sensitive tasks like log analysis, scheduling, or date calculations.
7///
8/// # Arguments
9/// * `use_utc` - If true, use UTC time; if false, use local system time
10///
11/// # Returns
12/// Formatted string with current date/time
13///
14/// # Examples
15/// ```
16/// use vtcode_core::prompts::temporal::generate_temporal_context;
17///
18/// // Local time
19/// let context = generate_temporal_context(false);
20/// assert!(context.contains("Current date and time:"));
21///
22/// // UTC time
23/// let context = generate_temporal_context(true);
24/// assert!(context.contains("UTC"));
25/// ```
26pub fn generate_temporal_context(use_utc: bool) -> String {
27    if use_utc {
28        let now: DateTime<Utc> = Utc::now();
29        format!(
30            "\n\nCurrent date and time (UTC): {}",
31            now.to_rfc3339_opts(chrono::SecondsFormat::Secs, true)
32        )
33    } else {
34        let now: DateTime<Local> = Local::now();
35        format!(
36            "\n\nCurrent date and time: {}",
37            now.format("%A, %B %d, %Y at %I:%M:%S %p %Z")
38        )
39    }
40}
41
42#[cfg(test)]
43mod tests {
44    use super::*;
45
46    #[test]
47    fn test_temporal_context_utc_format() {
48        let context = generate_temporal_context(true);
49        assert!(
50            context.contains("Current date and time (UTC):"),
51            "Should include UTC label"
52        );
53        assert!(
54            context.contains("T"),
55            "Should use RFC3339 format with T separator"
56        );
57        assert!(context.contains("Z"), "Should include Z timezone indicator");
58    }
59
60    #[test]
61    fn test_temporal_context_local_format() {
62        let context = generate_temporal_context(false);
63        assert!(
64            context.contains("Current date and time:"),
65            "Should include date/time label"
66        );
67        assert!(context.contains(" at "), "Should include 'at' separator");
68        // Check for day of week (will be one of the weekdays)
69        let has_weekday = context.contains("Monday")
70            || context.contains("Tuesday")
71            || context.contains("Wednesday")
72            || context.contains("Thursday")
73            || context.contains("Friday")
74            || context.contains("Saturday")
75            || context.contains("Sunday");
76        assert!(has_weekday, "Should include day of week");
77    }
78
79    #[test]
80    fn test_temporal_context_non_empty() {
81        let utc = generate_temporal_context(true);
82        let local = generate_temporal_context(false);
83
84        assert!(!utc.is_empty(), "UTC context should not be empty");
85        assert!(!local.is_empty(), "Local context should not be empty");
86        assert!(utc.len() > 30, "UTC context should have reasonable length");
87        assert!(
88            local.len() > 40,
89            "Local context should have reasonable length"
90        );
91    }
92
93    #[test]
94    fn test_temporal_context_starts_with_newlines() {
95        let utc = generate_temporal_context(true);
96        let local = generate_temporal_context(false);
97
98        assert!(
99            utc.starts_with("\n\n"),
100            "Should start with double newline for spacing"
101        );
102        assert!(
103            local.starts_with("\n\n"),
104            "Should start with double newline for spacing"
105        );
106    }
107}