systemprompt_models/wire/
inspect.rs1use serde_json::Value;
29
30#[derive(Debug, Clone, PartialEq, Eq)]
31pub struct SurfaceLeaf {
32 pub path: String,
33 pub value: String,
34}
35
36#[derive(Debug, Clone, Default, PartialEq, Eq)]
40pub struct ForwardedSurface {
41 leaves: Vec<SurfaceLeaf>,
42 truncated: bool,
43}
44
45impl ForwardedSurface {
46 #[must_use]
47 pub fn leaves(&self) -> &[SurfaceLeaf] {
48 &self.leaves
49 }
50
51 #[must_use]
52 pub const fn truncated(&self) -> bool {
53 self.truncated
54 }
55
56 #[must_use]
57 pub const fn is_empty(&self) -> bool {
58 self.leaves.is_empty()
59 }
60
61 #[must_use]
62 pub const fn len(&self) -> usize {
63 self.leaves.len()
64 }
65
66 #[must_use]
67 pub fn joined(&self) -> String {
68 let mut out = String::new();
69 for leaf in &self.leaves {
70 if !out.is_empty() {
71 out.push('\n');
72 }
73 out.push_str(&leaf.value);
74 }
75 out
76 }
77}
78
79#[derive(Debug, Clone, Copy)]
82pub struct SurfaceBudget {
83 pub depth: usize,
84 pub leaves: usize,
85 pub total_bytes: usize,
86 pub leaf_bytes: usize,
87}
88
89impl Default for SurfaceBudget {
90 fn default() -> Self {
91 Self {
92 depth: 64,
95 leaves: 50_000,
96 total_bytes: 2 * 1024 * 1024,
97 leaf_bytes: 64 * 1024,
98 }
99 }
100}
101
102#[must_use]
103pub fn string_leaves(body: &[u8], budget: SurfaceBudget) -> ForwardedSurface {
104 let Ok(root) = serde_json::from_slice::<Value>(body) else {
105 return ForwardedSurface::default();
106 };
107 let mut surface = ForwardedSurface::default();
108 let mut total: usize = 0;
109 walk(&mut surface, &mut total, &root, budget);
110 surface
111}
112
113#[must_use]
114pub fn sse_string_leaves(frames: &[u8], budget: SurfaceBudget) -> ForwardedSurface {
115 let mut surface = ForwardedSurface::default();
116 let mut total: usize = 0;
117 let mut rest = frames;
118 while !rest.is_empty() {
119 let (frame, next) = rest.split_at(super::sse::frame_end(rest).unwrap_or(rest.len()));
120 if let Some(payload) = data_payload(frame)
121 && let Ok(root) = serde_json::from_slice::<Value>(&payload)
122 && !walk(&mut surface, &mut total, &root, budget)
123 {
124 return surface;
125 }
126 rest = next;
127 }
128 surface
129}
130
131fn data_payload(frame: &[u8]) -> Option<Vec<u8>> {
132 let mut out: Vec<u8> = Vec::new();
133 let mut found = false;
134 for line in frame.split(|b| *b == b'\n') {
135 let line = line.strip_suffix(b"\r").unwrap_or(line);
136 let Some(value) = line.strip_prefix(b"data:") else {
137 continue;
138 };
139 found = true;
140 out.extend_from_slice(value.strip_prefix(b" ").unwrap_or(value));
141 }
142 found.then_some(out)
143}
144
145fn walk(
148 surface: &mut ForwardedSurface,
149 total: &mut usize,
150 root: &Value,
151 budget: SurfaceBudget,
152) -> bool {
153 let mut stack: Vec<(&Value, String, usize)> = vec![(root, String::from("$"), 0)];
154
155 while let Some((value, path, depth)) = stack.pop() {
156 if depth > budget.depth {
157 surface.truncated = true;
158 continue;
159 }
160 match value {
161 Value::String(s) => {
162 if !push_leaf(surface, total, &budget, &path, s) {
163 return false;
164 }
165 },
166 Value::Array(items) => {
167 for (index, item) in items.iter().enumerate().rev() {
169 stack.push((item, format!("{path}[{index}]"), depth + 1));
170 }
171 },
172 Value::Object(map) => {
173 for (key, item) in map.iter().rev() {
174 if !push_leaf(surface, total, &budget, &format!("{path}.{key}.$key"), key) {
178 return false;
179 }
180 stack.push((item, format!("{path}.{key}"), depth + 1));
181 }
182 },
183 Value::Null | Value::Bool(_) | Value::Number(_) => {},
184 }
185 }
186 true
187}
188
189fn push_leaf(
192 surface: &mut ForwardedSurface,
193 total: &mut usize,
194 budget: &SurfaceBudget,
195 path: &str,
196 value: &str,
197) -> bool {
198 if value.is_empty() {
199 return true;
200 }
201 if surface.leaves.len() >= budget.leaves || *total >= budget.total_bytes {
202 surface.truncated = true;
203 return false;
204 }
205 let (value, clipped) = clip(value, budget.leaf_bytes);
206 if clipped {
207 surface.truncated = true;
208 }
209 *total += value.len();
210 surface.leaves.push(SurfaceLeaf {
211 path: path.to_owned(),
212 value,
213 });
214 true
215}
216
217fn clip(value: &str, limit: usize) -> (String, bool) {
220 if value.len() <= limit {
221 return (value.to_owned(), false);
222 }
223 let half = limit / 2;
224 let head_end = floor_boundary(value, half);
225 let tail_start = ceil_boundary(value, value.len() - half);
226 let mut out = String::with_capacity(limit + 1);
227 out.push_str(&value[..head_end]);
228 out.push('\n');
229 out.push_str(&value[tail_start..]);
230 (out, true)
231}
232
233const fn floor_boundary(s: &str, mut index: usize) -> usize {
234 while index > 0 && !s.is_char_boundary(index) {
235 index -= 1;
236 }
237 index
238}
239
240const fn ceil_boundary(s: &str, mut index: usize) -> usize {
241 while index < s.len() && !s.is_char_boundary(index) {
242 index += 1;
243 }
244 index
245}