extractSessionMemory method

Future<void> extractSessionMemory(
  1. List<SessionMessage> messages,
  2. String querySource
)

Extract session memory — the main hook entry point.

Implementation

Future<void> extractSessionMemory(
  List<SessionMessage> messages,
  String querySource,
) async {
  // Only run on main REPL thread.
  if (querySource != 'repl_main_thread') return;

  // Check gate lazily.
  if (!isGateEnabled()) {
    if (!_hasLoggedGateFailure) {
      _hasLoggedGateFailure = true;
      logEvent('tengu_session_memory_gate_disabled', {});
    }
    return;
  }

  _initConfigIfNeeded();

  if (!shouldExtractMemory(messages)) return;

  state.value.markExtractionStarted();

  try {
    final setup = await _setupFile();
    final prompt = await buildSessionMemoryUpdatePrompt(
      setup.currentMemory,
      setup.memoryPath,
      loadPrompt,
    );

    await runExtractionAgent(
      prompt: prompt,
      memoryPath: setup.memoryPath,
      contextMessages: messages,
    );

    final lastMessage = messages.isNotEmpty ? messages.last : null;
    logEvent('tengu_session_memory_extraction', {
      'input_tokens': lastMessage?.inputTokens,
      'output_tokens': lastMessage?.outputTokens,
      'cache_read_input_tokens': lastMessage?.cacheReadInputTokens,
      'cache_creation_input_tokens': lastMessage?.cacheCreationInputTokens,
      'config_min_message_tokens_to_init':
          state.value.config.minimumMessageTokensToInit,
      'config_min_tokens_between_update':
          state.value.config.minimumTokensBetweenUpdate,
      'config_tool_calls_between_updates':
          state.value.config.toolCallsBetweenUpdates,
    });

    state.value.recordExtractionTokenCount(
      tokenCountWithEstimation(messages),
    );

    _updateLastSummarizedMessageIdIfSafe(messages);
  } finally {
    state.value.markExtractionCompleted();
  }
}