userRequestCandidateLines function

List<String> userRequestCandidateLines(
  1. List<Message> messages, {
  2. List<String?>? recordIds,
})

Extracts open-user-request candidate lines from messages: EVERY user-role text, oldest first — the summarizer LLM itself judges which are open asks, so no message is lost to a detection gate (issue #86). Only structural non-user content is skipped: <system-notice> envelopes, agent mail, and projected branch summaries. recordIds, when given, runs parallel to messages and lands in the line pointer; null/empty entries fall back to a date-only pointer.

Implementation

List<String> userRequestCandidateLines(
  List<Message> messages, {
  List<String?>? recordIds,
}) {
  final lines = <String>[];
  for (var i = 0; i < messages.length; i++) {
    final message = messages[i];
    if (message is! UserMessage) continue;
    final text = userMessageText(message.content);
    if (text.isEmpty || isSyntheticUserText(text)) {
      continue;
    }
    final id = (recordIds != null && i < recordIds.length)
        ? recordIds[i]
        : null;
    final flat = text.replaceAll(RegExp(r'\s+'), ' ').trim();
    lines.add('- [${_userRequestPointer(id, message.timestamp)}] $flat');
  }
  return lines;
}