# How the Developer Agent Tracks Progress with current_task_idx and current_atomic_task_idx in SWE-Agent

> Learn how the SWE-Agent Developer agent tracks task progress using current_task_idx and current_atomic_task_idx. Understand deterministic workflow traversal with LangGraph.

- Repository: [LangTalks/swe-agent](https://github.com/langtalks/swe-agent)
- Tags: internals
- Published: 2026-03-05

---

**The Developer agent in `langtalks/swe-agent` tracks execution progress using two integer counters—`current_task_idx` for the main task position and `current_atomic_task_idx` for the sub-task position—stored in the `SoftwareDeveloperState` model and manipulated by LangGraph nodes to enable deterministic workflow traversal.**

The Developer agent executes software engineering tasks by iterating through a hierarchical implementation plan divided into main tasks and atomic sub-tasks. To maintain precise position within this nested structure and enable resumable execution, the agent stores dual index counters in its state model that coordinate transitions between workflow nodes.

## State Model Definition

The progress tracking fields are defined as part of the `SoftwareDeveloperState` Pydantic model in [`agent/developer/state.py`](https://github.com/langtalks/swe-agent/blob/main/agent/developer/state.py). These integers serve as pointers into the `implementation_plan` structure:

- **`current_task_idx`**: Tracks the index of the main task currently being executed within the implementation plan.
- **`current_atomic_task_idx`**: Tracks the index of the specific atomic (sub-)task within the current main task.

Both fields are standard Python integers that default to `0` when the workflow begins, as seen in lines 30-31 of [`agent/developer/state.py`](https://github.com/langtalks/swe-agent/blob/main/agent/developer/state.py).

## Initialization at Workflow Start

When the LangGraph workflow initiates, the **`start_implementing`** node explicitly resets both counters to ensure a clean execution state. This initialization occurs in [`agent/developer/graph.py`](https://github.com/langtalks/swe-agent/blob/main/agent/developer/graph.py) (lines 33-38):

```python
def start_implementing(state: SoftwareDeveloperState):
    return {
        "current_task_idx": 0,
        "current_atomic_task_idx": 0
    }

```

This guarantees that every execution begins at the first main task and its first atomic sub-task, regardless of any previous state persistence.

## Advancing Through the Task Hierarchy

The core progression logic resides in the **`proceed_to_next_atomic_task`** node within [`agent/developer/graph.py`](https://github.com/langtalks/swe-agent/blob/main/agent/developer/graph.py) (lines 40-63). This function implements intelligent index advancement that respects the nested relationship between tasks and atomic tasks:

```python
def proceed_to_next_atomic_task(state: SoftwareDeveloperState):
    current_task_idx = state.current_task_idx
    current_atomic_task_idx = state.current_atomic_task_idx
    plan = state.implementation_plan
    current_task = plan.tasks[current_task_idx]
    atomic_tasks = current_task.atomic_tasks

    # Move to next main task when all atomic tasks are done

    if current_atomic_task_idx >= len(atomic_tasks) - 1:
        return {
            "current_task_idx": current_task_idx + 1,
            "current_atomic_task_idx": 0
        }
    # Otherwise, just advance the atomic-task index

    return {
        "current_task_idx": current_task_idx,
        "current_atomic_task_idx": current_atomic_task_idx + 1
    }

```

The logic follows a simple hierarchy: increment the atomic task index first, and only when the current main task's atomic tasks are exhausted (detected via `len(atomic_tasks) - 1`), increment the main task index and reset the atomic counter to zero.

## Task Selection During Execution

Throughout the graph execution, downstream nodes consume these indices to retrieve the appropriate task definitions from the state. For example, in [`agent/developer/graph.py`](https://github.com/langtalks/swe-agent/blob/main/agent/developer/graph.py) (lines 66-70), the current atomic task is accessed via:

```python

# Example from get_clear_implementation_plan_for_atomic_task

current_task = state.implementation_plan.tasks[state.current_task_idx]
current_atomic_task = current_task.atomic_tasks[state.current_atomic_task_idx]

```

This pattern ensures that every node in the workflow operates on the correct slice of the implementation plan without maintaining separate tracking variables.

## Detecting Workflow Completion

The **`is_implementation_complete`** node in [`agent/developer/graph.py`](https://github.com/langtalks/swe-agent/blob/main/agent/developer/graph.py) (lines 103-109) monitors `current_task_idx` to determine when the entire implementation plan has been processed:

```python
def is_implementation_complete(state: SoftwareDeveloperState):
    current_task_idx = state.current_task_idx
    plan = state.implementation_plan
    return END if current_task_idx >= len(plan.tasks) else "continue"

```

When the main task index equals or exceeds the total number of tasks in the plan, the graph emits the `END` signal, terminating the workflow. Otherwise, it routes back to `prepare_for_implementation` to continue with the next atomic task.

## Summary

- **State storage**: The `current_task_idx` and `current_atomic_task_idx` counters live in the `SoftwareDeveloperState` model defined in [`agent/developer/state.py`](https://github.com/langtalks/swe-agent/blob/main/agent/developer/state.py).
- **Initialization**: The `start_implementing` node resets both indices to `0` at workflow startup.
- **Advancement logic**: The `proceed_to_next_atomic_task` node increments atomic indices first, then main task indices, resetting the atomic counter when transitioning between main tasks.
- **Data access**: Other graph nodes read these indices to fetch specific task configurations from `state.implementation_plan`.
- **Termination**: The `is_implementation_complete` node checks if `current_task_idx` exceeds the plan length to signal workflow completion.

## Frequently Asked Questions

### What is the difference between current_task_idx and current_atomic_task_idx?

`current_task_idx` tracks the position within the top-level list of tasks in the implementation plan, while `current_atomic_task_idx` tracks the position within the nested `atomic_tasks` list of the current main task. This two-level indexing allows the agent to handle complex tasks that require multiple discrete operations (atomic tasks) while maintaining a clear position marker for the overall workflow.

### How does the Developer agent know when to move to the next main task?

The `proceed_to_next_atomic_task` function in [`agent/developer/graph.py`](https://github.com/langtalks/swe-agent/blob/main/agent/developer/graph.py) compares `current_atomic_task_idx` against `len(atomic_tasks) - 1`. When the atomic task index reaches the end of the current task's sub-task list, the function increments `current_task_idx` by one and resets `current_atomic_task_idx` to zero, effectively advancing to the next main task.

### Where are the progress counters initialized in the SWE-Agent codebase?

The counters are initialized in the `start_implementing` node located in [`agent/developer/graph.py`](https://github.com/langtalks/swe-agent/blob/main/agent/developer/graph.py) (lines 33-38). This node returns a dictionary setting both `current_task_idx` and `current_atomic_task_idx` to `0`, ensuring every workflow execution starts at the beginning of the implementation plan regardless of previous state.

### What happens when all tasks in the implementation plan are completed?

The `is_implementation_complete` node checks if `current_task_idx` is greater than or equal to the length of `plan.tasks`. When this condition is met, the node returns `END`, causing the LangGraph workflow to terminate. Until this condition is satisfied, the conditional edge routes execution back to `prepare_for_implementation` to process the next atomic task.