1use crate::config::CacheSettings;
4use crate::types::{CacheControl, Message, Role};
5
6pub fn apply_cache_control(messages: &[Message], settings: &CacheSettings) -> Vec<Message> {
14 if !settings.is_enabled() {
15 return messages.to_vec();
16 }
17
18 let cache_control = if settings.is_long_retention() {
19 CacheControl::ephemeral_long()
20 } else {
21 CacheControl::ephemeral()
22 };
23
24 let mut result = messages.to_vec();
25 let len = result.len();
26
27 if len > 0 && result[0].role == Role::System {
29 result[0].cache_control = Some(cache_control.clone());
30 }
31
32 for i in (0..len).rev() {
34 if result[i].role == Role::User {
35 result[i].cache_control = Some(cache_control.clone());
36 break;
37 }
38 }
39
40 result
41}
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46
47 #[test]
48 fn test_no_caching_when_disabled() {
49 let settings = CacheSettings {
50 retention: "none".to_string(),
51 };
52 let messages = vec![Message {
53 role: Role::User,
54 content: Some(crate::MessageContent::text("Hello")),
55 tool_calls: None,
56 tool_call_id: None,
57 cache_control: None,
58 }];
59
60 let result = apply_cache_control(&messages, &settings);
61 assert!(result[0].cache_control.is_none());
62 }
63
64 #[test]
65 fn test_cache_applied_to_user_message() {
66 let settings = CacheSettings {
67 retention: "short".to_string(),
68 };
69 let messages = vec![Message {
70 role: Role::User,
71 content: Some(crate::MessageContent::text("Hello")),
72 tool_calls: None,
73 tool_call_id: None,
74 cache_control: None,
75 }];
76
77 let result = apply_cache_control(&messages, &settings);
78 assert!(result[0].cache_control.is_some());
79 }
80
81 #[test]
82 fn test_cache_applied_to_system_and_last_user() {
83 let settings = CacheSettings {
84 retention: "short".to_string(),
85 };
86 let messages = vec![
87 Message {
88 role: Role::System,
89 content: Some(crate::MessageContent::text("System prompt")),
90 tool_calls: None,
91 tool_call_id: None,
92 cache_control: None,
93 },
94 Message {
95 role: Role::User,
96 content: Some(crate::MessageContent::text("Hello")),
97 tool_calls: None,
98 tool_call_id: None,
99 cache_control: None,
100 },
101 Message {
102 role: Role::Assistant,
103 content: Some(crate::MessageContent::text("Hi!")),
104 tool_calls: None,
105 tool_call_id: None,
106 cache_control: None,
107 },
108 Message {
109 role: Role::User,
110 content: Some(crate::MessageContent::text("How are you?")),
111 tool_calls: None,
112 tool_call_id: None,
113 cache_control: None,
114 },
115 ];
116
117 let result = apply_cache_control(&messages, &settings);
118
119 assert!(result[0].cache_control.is_some());
121 assert!(result[1].cache_control.is_none());
123 assert!(result[2].cache_control.is_none());
125 assert!(result[3].cache_control.is_some());
127 }
128
129 #[test]
130 fn test_long_retention_ttl() {
131 let settings = CacheSettings {
132 retention: "long".to_string(),
133 };
134 let messages = vec![Message {
135 role: Role::User,
136 content: Some(crate::MessageContent::text("Hello")),
137 tool_calls: None,
138 tool_call_id: None,
139 cache_control: None,
140 }];
141
142 let result = apply_cache_control(&messages, &settings);
143 let cc = result[0].cache_control.as_ref().unwrap();
144 assert_eq!(cc.ttl, Some("1h".to_string()));
145 }
146}