step method

  1. @override
Future<void> step()
override

Executes a single step of the agent's main logic.

This method is called repeatedly by the orchestrator and should:

  • Check for work to do
  • Perform any necessary actions
  • Update status appropriately

Implementations should be idempotent and handle their own errors.

Implementation

@override
Future<void> step() async {
  if (_activeTask == null || status != AgentStatus.working) return;

  final task = _activeTask!;
  logger.info('[Agent $id] Executing Task #${task.id}: ${task.name}');

  final fileContext = _getFileContext(task.files);

  final prompt = '''
You are an expert developer. Implement the following task.
TASK: ${task.name}
OBJECTIVE: ${task.objective}

CURRENT FILE CONTEXT:
$fileContext

FILES TO MODIFY/CREATE: ${task.files.join(', ')}

Return the full content of each file wrapped in <file_content path="path/to/file"> XML tags.
Example:
<file_content path="lib/main.dart">
void main() {}
</file_content>
''';

  try {
    final response = await provider.generateResponse(prompt);
    final fileContents = _parseFileContents(response);

    if (fileContents.isEmpty) {
      logger.warn(
          '[Agent $id] No file contents generated for Task #${task.id}');
      _completeTask(task.id, success: false);
      return;
    }

    for (final entry in fileContents.entries) {
      final file = File(entry.key);
      if (!file.parent.existsSync()) {
        file.parent.createSync(recursive: true);
      }
      file.writeAsStringSync(entry.value);
      logger.detail('[Agent $id] Updated ${entry.key}');
    }

    logger.success('[Agent $id] Completed Task #${task.id}');
    _completeTask(task.id, success: true);
  } catch (e) {
    logger.err('[Agent $id] Error executing Task #${task.id}: $e');
    // Re-throw to let orchestrator handle error recovery
    rethrow;
  }
}