findCutPoint function
CutPointResult
findCutPoint(
- List<
SessionRecord> entries, - int startIndex,
- int endIndex,
- int keepRecentTokens,
Find the compaction cut point that keeps approximately keepRecentTokens
recent tokens.
Ported from pi's findCutPoint: walks entries backwards accumulating
estimated tokens until the budget is exhausted, then snaps the cut forward
to the next valid cut point (never a tool result) and backwards over
non-message records so configuration entries stay with the kept region.
Implementation
CutPointResult findCutPoint(
List<SessionRecord> entries,
int startIndex,
int endIndex,
int keepRecentTokens,
) {
final cutPoints = _findValidCutPoints(entries, startIndex, endIndex);
if (cutPoints.isEmpty) {
return CutPointResult(
firstKeptEntryIndex: startIndex,
turnStartIndex: -1,
isSplitTurn: false,
);
}
var accumulatedTokens = 0;
var cutIndex = cutPoints.first;
for (var i = endIndex - 1; i >= startIndex; i--) {
final entry = entries[i];
if (entry is! MessageRecord) continue;
accumulatedTokens += estimateTokens(entry.message);
if (accumulatedTokens >= keepRecentTokens) {
for (final cutPoint in cutPoints) {
if (cutPoint >= i) {
cutIndex = cutPoint;
break;
}
}
break;
}
}
while (cutIndex > startIndex) {
final prevEntry = entries[cutIndex - 1];
if (prevEntry is CompactionRecord || prevEntry is MessageRecord) break;
cutIndex--;
}
final cutEntry = entries[cutIndex];
final isUserMessage =
cutEntry is MessageRecord && cutEntry.message.role == 'user';
final turnStartIndex = isUserMessage
? -1
: findTurnStartIndex(entries, cutIndex, startIndex);
return CutPointResult(
firstKeptEntryIndex: cutIndex,
turnStartIndex: turnStartIndex,
isSplitTurn: !isUserMessage && turnStartIndex != -1,
);
}