decompose method

List<CoordinatorTask> decompose(
  1. String prompt, {
  2. CoordinatorMode mode = CoordinatorMode.sequential,
})

Decompose a prompt into tasks based on structure.

Implementation

List<CoordinatorTask> decompose(
  String prompt, {
  CoordinatorMode mode = CoordinatorMode.sequential,
}) {
  final tasks = <CoordinatorTask>[];
  final now = DateTime.now();

  // Check for numbered list pattern.
  final numberedPattern = RegExp(r'^\d+[\.\)]\s+(.+)$', multiLine: true);
  final matches = numberedPattern.allMatches(prompt).toList();

  if (matches.length >= 2) {
    String? previousId;
    for (final match in matches) {
      final taskPrompt = match.group(1)!.trim();
      final taskId = _nextId();

      tasks.add(
        CoordinatorTask(
          id: taskId,
          name: _extractTaskName(taskPrompt),
          description: taskPrompt,
          prompt: taskPrompt,
          createdAt: now,
          dependencies:
              mode == CoordinatorMode.sequential && previousId != null
              ? [previousId]
              : [],
          requiredCapabilities: _inferCapabilities(taskPrompt).toList(),
        ),
      );

      previousId = taskId;
    }
    return tasks;
  }

  // Check for bullet list pattern.
  final bulletPattern = RegExp(r'^[-*]\s+(.+)$', multiLine: true);
  final bulletMatches = bulletPattern.allMatches(prompt).toList();

  if (bulletMatches.length >= 2) {
    for (final match in bulletMatches) {
      final taskPrompt = match.group(1)!.trim();
      tasks.add(
        CoordinatorTask(
          id: _nextId(),
          name: _extractTaskName(taskPrompt),
          description: taskPrompt,
          prompt: taskPrompt,
          createdAt: now,
          requiredCapabilities: _inferCapabilities(taskPrompt).toList(),
        ),
      );
    }
    return tasks;
  }

  // Check for "then"/"after"/"next" sequential markers.
  final sequentialParts = prompt.split(
    RegExp(
      r'\.\s+(?:Then|After that|Next|Finally|Lastly)',
      caseSensitive: false,
    ),
  );
  if (sequentialParts.length >= 2) {
    String? previousId;
    for (final part in sequentialParts) {
      final taskPrompt = part.trim();
      if (taskPrompt.isEmpty) continue;
      final taskId = _nextId();

      tasks.add(
        CoordinatorTask(
          id: taskId,
          name: _extractTaskName(taskPrompt),
          description: taskPrompt,
          prompt: taskPrompt,
          createdAt: now,
          dependencies: previousId != null ? [previousId] : [],
          requiredCapabilities: _inferCapabilities(taskPrompt).toList(),
        ),
      );

      previousId = taskId;
    }
    return tasks;
  }

  // Single task.
  tasks.add(
    CoordinatorTask(
      id: _nextId(),
      name: _extractTaskName(prompt),
      description: prompt,
      prompt: prompt,
      createdAt: now,
      requiredCapabilities: _inferCapabilities(prompt).toList(),
    ),
  );

  return tasks;
}