| 47 | // calls. then erases output of previous tool calls. idea is to throw away old |
| 48 | // tool calls that are no longer relevant. |
| 49 | export async function prune(input: { sessionID: string }) { |
| 50 | if (Flag.ARCTIC_DISABLE_PRUNE) return |
| 51 | log.info("pruning") |
| 52 | const msgs = await Session.messages({ sessionID: input.sessionID }) |
| 53 | let total = 0 |
| 54 | let pruned = 0 |
| 55 | const toPrune = [] |
| 56 | let turns = 0 |
| 57 | |
| 58 | loop: for (let msgIndex = msgs.length - 1; msgIndex >= 0; msgIndex--) { |
| 59 | const msg = msgs[msgIndex] |
| 60 | if (msg.info.role === "user") turns++ |
| 61 | if (turns < 2) continue |
| 62 | if (msg.info.role === "assistant" && msg.info.summary) break loop |
| 63 | for (let partIndex = msg.parts.length - 1; partIndex >= 0; partIndex--) { |
| 64 | const part = msg.parts[partIndex] |
| 65 | if (part.type === "tool") |
| 66 | if (part.state.status === "completed") { |
| 67 | if (part.state.time.compacted) break loop |
| 68 | const estimate = Token.estimate(part.state.output) |
| 69 | total += estimate |
| 70 | if (total > PRUNE_PROTECT) { |
| 71 | pruned += estimate |
| 72 | toPrune.push(part) |
| 73 | } |
| 74 | } |
| 75 | } |
| 76 | } |
| 77 | log.info("found", { pruned, total }) |
| 78 | if (pruned > PRUNE_MINIMUM) { |
| 79 | for (const part of toPrune) { |
| 80 | if (part.state.status === "completed") { |
| 81 | part.state.time.compacted = Date.now() |
| 82 | await Session.updatePart(part) |
| 83 | } |
| 84 | } |
| 85 | log.info("pruned", { count: toPrune.length }) |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | export async function process(input: { |
| 90 | parentID: string |