How the Developer Agent Tracks Progress with current_task_idx and current_atomic_task_idx in SWE-Agent
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. 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.
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 (lines 33-38):
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 (lines 40-63). This function implements intelligent index advancement that respects the nested relationship between tasks and atomic tasks:
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 (lines 66-70), the current atomic task is accessed via:
# 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 (lines 103-109) monitors current_task_idx to determine when the entire implementation plan has been processed:
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_idxandcurrent_atomic_task_idxcounters live in theSoftwareDeveloperStatemodel defined inagent/developer/state.py. - Initialization: The
start_implementingnode resets both indices to0at workflow startup. - Advancement logic: The
proceed_to_next_atomic_tasknode 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_completenode checks ifcurrent_task_idxexceeds 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 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 (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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →