systemprompt_models/wire/canonical/
safety.rs1use super::CanonicalRequest;
7use super::request::flatten_part;
8
9impl CanonicalRequest {
10 pub fn safety_parts(&self, history: bool) -> Vec<(String, String)> {
11 let leaves = self.forwarded_surface.leaves();
12 if !leaves.is_empty() {
13 let newest = leaves
14 .iter()
15 .filter_map(|leaf| message_index(&leaf.path))
16 .max();
17 return leaves
18 .iter()
19 .filter(|leaf| {
20 let historical =
21 message_index(&leaf.path).is_some_and(|index| Some(index) != newest);
22 historical == history
23 })
24 .map(|leaf| (leaf.path.clone(), leaf.value.clone()))
25 .collect();
26 }
27 let mut parts = Vec::new();
28 if !history && let Some(system) = self.system_text() {
29 parts.push(("system".to_owned(), system));
30 }
31 for (index, message) in self.messages.iter().enumerate() {
32 if (index + 1 < self.messages.len()) != history {
33 continue;
34 }
35 let mut text = String::new();
36 for part in &message.content {
37 flatten_part(&mut text, part);
38 }
39 if !text.is_empty() {
40 parts.push((format!("messages[{index}]"), text));
41 }
42 }
43 parts
44 }
45}
46
47fn message_index(path: &str) -> Option<usize> {
48 ["$.messages[", "$.contents[", "$.input["]
49 .iter()
50 .find_map(|prefix| path.strip_prefix(prefix))?
51 .split_once(']')?
52 .0
53 .parse()
54 .ok()
55}