fit method
- List<
AiChatMessage> messages
Trims messages to fit, dropping the oldest turns first.
Order is preserved and the newest messages are always kept, because a conversation without its most recent turn is useless. Returns the input unchanged when it already fits.
Implementation
List<AiChatMessage> fit(List<AiChatMessage> messages) {
if (messages.isEmpty) return const [];
if (fits(messages)) return List.of(messages);
final system = <AiChatMessage>[
if (keepSystemMessages)
for (final m in messages)
if (m.role == AiRole.system) m,
];
final rest = [
for (final m in messages)
if (!(keepSystemMessages && m.role == AiRole.system)) m,
];
final systemCost = estimateConversationTokens(system);
var budget = availableTokens - systemCost;
// Walk backwards from the newest message, keeping whatever fits.
final kept = <AiChatMessage>[];
for (var i = rest.length - 1; i >= 0; i--) {
final cost = estimateMessageTokens(rest[i]);
final isProtected = kept.length < minimumRecentMessages;
if (cost <= budget || isProtected) {
kept.insert(0, rest[i]);
budget -= cost;
} else {
// Everything older than this is dropped.
break;
}
}
return [...system, ...kept];
}