truncateHeadForPTLRetry function
Drops the oldest API-round groups from messages until tokenGap is covered. Returns null when nothing can be dropped without leaving an empty summarize set.
Implementation
List<CompactMessage>? truncateHeadForPTLRetry(
List<CompactMessage> messages,
int? tokenGap,
) {
// Strip our own synthetic marker from a previous retry before grouping.
final input =
(messages.isNotEmpty &&
messages.first.type == MessageRole.user &&
messages.first.isMeta &&
messages.first.contentBlocks.length == 1 &&
messages.first.contentBlocks.first.text == _ptlRetryMarker)
? messages.sublist(1)
: messages;
final groups = groupMessagesByApiRound(input);
if (groups.length < 2) return null;
int dropCount;
if (tokenGap != null) {
int acc = 0;
dropCount = 0;
for (final g in groups) {
acc += roughTokenCountEstimationForMessages(g);
dropCount++;
if (acc >= tokenGap) break;
}
} else {
dropCount = max(1, (groups.length * 0.2).floor());
}
// Keep at least one group so there's something to summarize.
dropCount = min(dropCount, groups.length - 1);
if (dropCount < 1) return null;
final sliced = groups.sublist(dropCount).expand((g) => g).toList();
// Prepend synthetic user marker if first message is assistant.
if (sliced.isNotEmpty && sliced.first.type == MessageRole.assistant) {
return [
CompactMessage(
uuid: _generateUuid(),
type: MessageRole.user,
timestamp: DateTime.now(),
isMeta: true,
contentBlocks: [
const ContentBlock(
type: ContentBlockType.text,
text: _ptlRetryMarker,
),
],
),
...sliced,
];
}
return sliced;
}