compactConversation method

Future<CompactionResult> compactConversation({
  1. required List<Message> messages,
  2. required String systemPrompt,
  3. int contextWindow = 200000,
  4. bool isAutoCompact = false,
  5. String? customInstructions,
  6. bool suppressFollowUpQuestions = false,
  7. OnCompactProgress? onProgress,
})

Run full conversation compaction via summarization.

Sends the conversation transcript to the LLM for summarization, then replaces messages with a compact summary message. Resets the failure counter on success; increments on failure.

Implementation

Future<CompactionResult> compactConversation({
  required List<Message> messages,
  required String systemPrompt,
  int contextWindow = 200000,
  bool isAutoCompact = false,
  String? customInstructions,
  bool suppressFollowUpQuestions = false,
  OnCompactProgress? onProgress,
}) async {
  if (messages.isEmpty) {
    throw CompactionException(errorNotEnoughMessages);
  }

  final preTokenCount = estimateTokenCount(messages);
  final strategy =
      isAutoCompact ? CompactionStrategy.auto : CompactionStrategy.manual;

  onProgress?.call(
    const CompactProgressEvent(
      type: CompactProgressType.hooksStart,
      hookType: CompactHookType.preCompact,
    ),
  );

  onProgress?.call(
    const CompactProgressEvent(type: CompactProgressType.compactStart),
  );

  try {
    // Strip images from messages before summarization — images are not
    // needed for generating a summary and can cause prompt-too-long errors.
    final stripped = stripImagesFromMessages(messages);

    final summary = await _generateSummary(
      messages: stripped,
      systemPrompt: systemPrompt,
      customInstructions: customInstructions,
    );

    if (summary.isEmpty) {
      throw CompactionException(
        'Failed to generate conversation summary — response did not '
        'contain valid text content',
      );
    }

    final compactedMessages = [
      Message.user(
        _formatCompactSummary(summary, suppressFollowUpQuestions),
      ),
    ];

    _consecutiveFailures = 0;

    onProgress?.call(
      const CompactProgressEvent(
        type: CompactProgressType.hooksStart,
        hookType: CompactHookType.postCompact,
      ),
    );

    return CompactionResult(
      compactedMessages: compactedMessages,
      summary: summary,
      preCompactTokenCount: preTokenCount,
      postCompactTokenCount: estimateTokenCount(compactedMessages),
      strategy: strategy,
    );
  } catch (e) {
    _consecutiveFailures++;
    rethrow;
  } finally {
    onProgress?.call(
      const CompactProgressEvent(type: CompactProgressType.compactEnd),
    );
  }
}