use chrono::{DateTime, Utc};
use crate::message::{RuntimeMessage, RuntimeMessageRole};
pub(super) fn supports_clear_at(provider: &everruns_contracts::DriverId, model: &str) -> bool {
provider == &everruns_contracts::DriverId::Anthropic
&& everruns_contracts::get_model_profile(provider, model).is_some_and(|profile| {
profile.supports_parameter(everruns_contracts::model::MID_CONVERSATION_SYSTEM_PARAMETER)
&& profile.supports_parameter(everruns_contracts::model::CLEAR_AT_PARAMETER)
})
}
pub(super) fn mark_turn_scoped(
target: &mut everruns_contracts::driver_registry::Message,
source: &RuntimeMessage,
supported: bool,
) {
if supported && source.is_turn_scoped_reminder() {
target.mark_turn_scoped_system();
}
}
pub(super) fn interleave_facts(
messages: Vec<RuntimeMessage>,
render: impl Fn(DateTime<Utc>) -> Option<String>,
turn_scoped_system: bool,
) -> (Vec<RuntimeMessage>, usize) {
let fact_message = |block| {
if turn_scoped_system {
RuntimeMessage::turn_scoped_system(block)
} else {
RuntimeMessage::user(block)
}
};
let answered =
|next: Option<&RuntimeMessageRole>| matches!(next, None | Some(RuntimeMessageRole::Agent));
let roles: Vec<RuntimeMessageRole> = messages.iter().map(|m| m.role.clone()).collect();
let ends_on_answer = matches!(
roles
.iter()
.rev()
.find(|r| **r != RuntimeMessageRole::System),
Some(RuntimeMessageRole::Agent)
);
let mut placed = Vec::with_capacity(messages.len() + 1);
for (index, message) in messages.into_iter().enumerate() {
let input_at = matches!(
message.role,
RuntimeMessageRole::User | RuntimeMessageRole::ToolResult
)
.then_some(message.created_at);
placed.push(message);
let next = roles[index + 1..]
.iter()
.find(|r| **r != RuntimeMessageRole::System);
if let Some(at) = input_at
&& answered(next)
&& let Some(block) = render(at)
{
placed.push(fact_message(block));
}
}
if ends_on_answer && let Some(block) = render(Utc::now()) {
placed.push(fact_message(block));
return (placed, 1);
}
(placed, 0)
}
#[cfg(test)]
mod tests {
use super::*;
use chrono::TimeZone;
fn at(minute: u32) -> DateTime<Utc> {
Utc.with_ymd_and_hms(2026, 9, 23, 10, minute, 0).unwrap()
}
fn message(role: RuntimeMessageRole, text: &str, minute: u32) -> RuntimeMessage {
let mut message = match role {
RuntimeMessageRole::User => RuntimeMessage::user(text),
RuntimeMessageRole::Agent => RuntimeMessage::assistant(text),
RuntimeMessageRole::System => RuntimeMessage::system(text),
RuntimeMessageRole::ToolResult => RuntimeMessage::user(text),
};
message.role = role;
message.created_at = at(minute);
message
}
fn render(moment: DateTime<Utc>) -> Option<String> {
Some(format!("<facts>{}</facts>", moment.format("%H:%M")))
}
fn texts(messages: &[RuntimeMessage]) -> Vec<String> {
messages
.iter()
.map(|m| m.text().unwrap_or_default().to_string())
.collect()
}
#[test]
fn a_block_follows_every_answered_input_as_of_that_input() {
use RuntimeMessageRole::*;
let history = vec![
message(User, "task", 0),
message(Agent, "call tools", 1),
message(ToolResult, "result a", 2),
message(ToolResult, "result b", 3),
message(System, "loop warning", 4),
message(Agent, "done", 5),
message(User, "next", 6),
];
let (placed, volatile) = interleave_facts(history, render, false);
assert_eq!(
texts(&placed),
[
"task",
"<facts>10:00</facts>",
"call tools",
"result a",
"result b",
"<facts>10:03</facts>",
"loop warning",
"done",
"next",
"<facts>10:06</facts>",
]
);
assert_eq!(volatile, 0);
}
#[test]
fn the_next_request_only_appends() {
use RuntimeMessageRole::*;
let turn_one = vec![message(User, "task", 0)];
let mut turn_two = turn_one.clone();
turn_two.extend([
message(Agent, "call tool", 1),
message(ToolResult, "result", 2),
]);
let (one, _) = interleave_facts(turn_one, render, false);
let (two, _) = interleave_facts(turn_two, render, false);
assert_eq!(texts(&two)[..one.len()], texts(&one)[..]);
assert_eq!(texts(&two).len(), one.len() + 3);
}
#[test]
fn a_continuation_gets_a_trailing_block_marked_volatile() {
use RuntimeMessageRole::*;
let history = vec![message(User, "task", 0), message(Agent, "partial", 1)];
let (placed, volatile) = interleave_facts(history, render, false);
assert_eq!(
texts(&placed)[..3],
["task", "<facts>10:00</facts>", "partial"]
);
assert_eq!(placed.len(), 4);
assert_eq!(volatile, 1);
}
#[test]
fn no_dynamic_facts_leaves_the_messages_alone() {
use RuntimeMessageRole::*;
let history = vec![message(User, "task", 0), message(Agent, "answer", 1)];
let (placed, volatile) = interleave_facts(history, |_| None, false);
assert_eq!(texts(&placed), ["task", "answer"]);
assert_eq!(volatile, 0);
}
#[test]
fn clear_at_capable_models_get_turn_scoped_system_facts() {
use RuntimeMessageRole::*;
let history = vec![message(User, "task", 0)];
let (placed, volatile) = interleave_facts(history, render, true);
assert_eq!(placed[1].role, System);
assert!(placed[1].is_turn_scoped_reminder());
assert_eq!(placed[1].text(), Some("<facts>10:00</facts>"));
assert_eq!(volatile, 0);
}
}