artificial_types/fragments/current_date.rs
1//! A small **prompt fragment** that injects the current date and time into a
2//! `GenericMessage`.
3//!
4//! Many tasks benefit from temporal context—think “remind me in three days” or
5//! “schedule for next Wednesday”. Hard-coding the timestamp at call-site is
6//! brittle and violates DRY, so this helper does the job for you.
7//!
8//! # What it adds
9//!
10//! ```markdown
11//! **Current ISO Timestamp**: 2025-04-20T12:34:56Z
12//! **Current Date and Time**: 2025-04-20 12:34:56
13//! **Current Weekday**: Sunday
14//! **Timezone**: UTC
15//!
16//! You are currently reasoning in the context of Sunday, 2025-04-20, 12:34:56, UTC
17//!
18//! Use this information when interpreting natural language expressions like
19//! 'next week' or 'in 3 days'.
20//! ```
21//!
22//! # Example
23//!
24//! ```rust
25//! use artificial_types::fragments::CurrentDateFragment;
26//! use artificial_prompt::chain::PromptChain;
27//!
28//! let messages = PromptChain::new()
29//! .with(CurrentDateFragment::new())
30//! .build();
31//!
32//! assert_eq!(messages[0].role.to_string(), "system");
33//! ```
34//!
35//! The fragment is fully **stateless**—you can create and reuse it as often as
36//! needed without side effects.
37
38use artificial_core::{
39 generic::{GenericMessage, GenericRole},
40 template::IntoPrompt,
41};
42use artificial_prompt::builder::PromptBuilder;
43use chrono::Datelike as _;
44
45/// Injects the current UTC timestamp/date/weekday as a system message.
46#[derive(Default)]
47pub struct CurrentDateFragment;
48
49impl CurrentDateFragment {
50 /// Convenience constructor (equivalent to `Self::default()`).
51 pub fn new() -> Self {
52 Self
53 }
54}
55
56impl IntoPrompt for CurrentDateFragment {
57 type Message = GenericMessage;
58
59 fn into_prompt(self) -> Vec<Self::Message> {
60 let now = chrono::Utc::now();
61
62 let builder = PromptBuilder::new()
63 .add_key_value("Current ISO Timestamp", now.to_rfc3339())
64 .add_key_value("Current Date and Time", now.format("%Y-%m-%d %H:%M:%S"))
65 .add_key_value("Current Weekday", now.weekday().to_string())
66 .add_key_value("Timezone", "UTC")
67 .add_line(format!(
68 "You are currently reasoning in the context of {}, {}, {}, {}",
69 now.weekday(),
70 now.format("%Y-%m-%d"),
71 now.format("%H:%M:%S"),
72 now.timezone()
73 ))
74 .add_blank_line()
75 .add_line(
76 "Use this information when interpreting natural language \
77 expressions like 'next week' or 'in 3 days'.",
78 );
79
80 vec![Self::Message {
81 role: GenericRole::System,
82 message: builder.finalize(),
83 }]
84 }
85}