MCPcopy Create free account
hub / github.com/ChrisFeldmeier/OpenCodeRust / prune

Method prune

crates/opencode-session/src/compaction.rs:284–365  ·  view source on GitHub ↗

Prune old tool results to save context space. Mirrors TS `SessionCompaction.prune`. Walks backwards through messages, skipping the most recent 2 user turns, and erases output of tool parts whose cumulative token count exceeds `PRUNE_PROTECT`. Returns the IDs of pruned parts. The caller is responsible for persisting the updated parts via `SessionOps::update_part`.

(&self, messages: &mut [MessageForPrune])

Source from the content-addressed store, hash-verified

282 /// Returns the IDs of pruned parts. The caller is responsible for
283 /// persisting the updated parts via `SessionOps::update_part`.
284 pub fn prune(&self, messages: &mut [MessageForPrune]) -> Vec<String> {
285 // TS: if (config.compaction?.prune === false) return
286 if !self.config.prune {
287 return vec![];
288 }
289
290 if !messages.is_empty() && !Self::should_prune(messages) {
291 return vec![];
292 }
293
294 tracing::info!("pruning");
295
296 let mut total: u64 = 0;
297 let mut pruned: u64 = 0;
298 let mut to_prune: Vec<(usize, usize)> = Vec::new();
299 let mut turns = 0;
300
301 'outer: for msg_index in (0..messages.len()).rev() {
302 let msg = &messages[msg_index];
303 if msg.role == "user" {
304 turns += 1;
305 }
306 if turns < 2 {
307 continue;
308 }
309 // TS: if (msg.info.role === "assistant" && msg.info.summary) break loop
310 if msg.role == "assistant" && msg.summary {
311 break;
312 }
313
314 for part_index in (0..msg.parts.len()).rev() {
315 let part = &msg.parts[part_index];
316 // Skip non-tool parts
317 if part.tool.is_empty() {
318 continue;
319 }
320
321 // TS: if (part.state.status === "completed") { ... }
322 // Only prune completed tool parts
323 if part.status != ToolPartStatus::Completed {
324 continue;
325 }
326
327 if PRUNE_PROTECTED_TOOLS.contains(&part.tool.as_str()) {
328 continue;
329 }
330
331 // TS: if (part.state.time.compacted) break loop
332 if part.compacted.is_some() {
333 break 'outer;
334 }
335
336 let estimate = Self::estimate_tokens(&part.output);
337 total += estimate;
338 if total > PRUNE_PROTECT {
339 pruned += estimate;
340 to_prune.push((msg_index, part_index));
341 }

Callers 4

prune_after_loopMethod · 0.80
prune_sessionMethod · 0.80

Calls 5

newFunction · 0.85
is_emptyMethod · 0.80
containsMethod · 0.80
as_strMethod · 0.45
cloneMethod · 0.45