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]
109pub fn string_leaves(body: &[u8], budget: SurfaceBudget) -> ForwardedSurface {
110 let Ok(root) = serde_json::from_slice::<Value>(body) else {
111 return ForwardedSurface::default();
112 };
113 let mut surface = ForwardedSurface::default();
114 let mut total: usize = 0;
115 walk(&mut surface, &mut total, &root, budget);
116 surface
117}
118
119#[must_use]
126pub fn sse_string_leaves(frames: &[u8], budget: SurfaceBudget) -> ForwardedSurface {
127 let mut surface = ForwardedSurface::default();
128 let mut total: usize = 0;
129 let mut rest = frames;
130 while !rest.is_empty() {
131 let (frame, next) = rest.split_at(super::sse::frame_end(rest).unwrap_or(rest.len()));
132 if let Some(payload) = data_payload(frame)
133 && let Ok(root) = serde_json::from_slice::<Value>(&payload)
134 && !walk(&mut surface, &mut total, &root, budget)
135 {
136 return surface;
137 }
138 rest = next;
139 }
140 surface
141}
142
143fn data_payload(frame: &[u8]) -> Option<Vec<u8>> {
144 let mut out: Vec<u8> = Vec::new();
145 let mut found = false;
146 for line in frame.split(|b| *b == b'\n') {
147 let line = line.strip_suffix(b"\r").unwrap_or(line);
148 let Some(value) = line.strip_prefix(b"data:") else {
149 continue;
150 };
151 found = true;
152 out.extend_from_slice(value.strip_prefix(b" ").unwrap_or(value));
153 }
154 found.then_some(out)
155}
156
157fn walk(
160 surface: &mut ForwardedSurface,
161 total: &mut usize,
162 root: &Value,
163 budget: SurfaceBudget,
164) -> bool {
165 let mut stack: Vec<(&Value, String, usize)> = vec![(root, String::from("$"), 0)];
166
167 while let Some((value, path, depth)) = stack.pop() {
168 if depth > budget.depth {
169 surface.truncated = true;
170 continue;
171 }
172 match value {
173 Value::String(s) => {
174 if !push_leaf(surface, total, &budget, &path, s) {
175 return false;
176 }
177 },
178 Value::Array(items) => {
179 for (index, item) in items.iter().enumerate().rev() {
181 stack.push((item, format!("{path}[{index}]"), depth + 1));
182 }
183 },
184 Value::Object(map) => {
185 for (key, item) in map.iter().rev() {
186 if !push_leaf(surface, total, &budget, &format!("{path}.{key}.$key"), key) {
190 return false;
191 }
192 stack.push((item, format!("{path}.{key}"), depth + 1));
193 }
194 },
195 Value::Null | Value::Bool(_) | Value::Number(_) => {},
196 }
197 }
198 true
199}
200
201fn push_leaf(
204 surface: &mut ForwardedSurface,
205 total: &mut usize,
206 budget: &SurfaceBudget,
207 path: &str,
208 value: &str,
209) -> bool {
210 if value.is_empty() {
211 return true;
212 }
213 if surface.leaves.len() >= budget.leaves || *total >= budget.total_bytes {
214 surface.truncated = true;
215 return false;
216 }
217 let (value, clipped) = clip(value, budget.leaf_bytes);
218 if clipped {
219 surface.truncated = true;
220 }
221 *total += value.len();
222 surface.leaves.push(SurfaceLeaf {
223 path: path.to_owned(),
224 value,
225 });
226 true
227}
228
229fn clip(value: &str, limit: usize) -> (String, bool) {
232 if value.len() <= limit {
233 return (value.to_owned(), false);
234 }
235 let half = limit / 2;
236 let head_end = floor_boundary(value, half);
237 let tail_start = ceil_boundary(value, value.len() - half);
238 let mut out = String::with_capacity(limit + 1);
239 out.push_str(&value[..head_end]);
240 out.push('\n');
241 out.push_str(&value[tail_start..]);
242 (out, true)
243}
244
245const fn floor_boundary(s: &str, mut index: usize) -> usize {
246 while index > 0 && !s.is_char_boundary(index) {
247 index -= 1;
248 }
249 index
250}
251
252const fn ceil_boundary(s: &str, mut index: usize) -> usize {
253 while index < s.len() && !s.is_char_boundary(index) {
254 index += 1;
255 }
256 index
257}