Skip to content

Feat: allow conditional cycles in graph #571

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

vria
Copy link

@vria vria commented Jul 30, 2025

Description

There are many cases where cycles in graph orchestration system are very useful. E.g. in my case of software development there is a code-review-fix loop. Here is a simplified example:

be_coder = Agent(
    name="Go Software Engineer",
    system_prompt="""
You are a Go Developer.
When developing a program from scratch, implement exactly what is required - no more, no less.
When fixing issues in existing code, address each issue individually and thoroughly, one at a time.
""",
    model=model,
    tools=[file_read, file_write],
)

reviewer = Agent(
    name="Senior Go Software Engineer",
    system_prompt="""
You are a Senior Go Developer with strong expertise in code review.
Evaluate the code for correctness, security, code quality, readability, performance, and efficiency.
If issues are found, list all necessary improvements clearly and state that the code requires changes with FIXES_REQUIRED keyword. 
If no issues are detected, explicitly state that the code is correct and does not require any modifications REVIEW_PASSED.
Be strict and always find something.
""",
    model=model,
    tools=[file_read],
)

# Build the graph
builder = GraphBuilder()

builder.add_node(be_coder, "code")
builder.add_node(reviewer, "review")

def only_if_fixes_required(state: GraphState):
    """Only if review requre fixes or review was visited less then 3 times."""
    review_node = state.results.get("review")
    if not review_node:
        return False
    
    reviewed_count = sum(1 for node in state.execution_order if node.node_id == "review")
    if reviewed_count >= 3:
        return False

    result_text = str(review_node.result)
    return "fixes_required" in result_text.lower()

# Loop code - review - fix
builder.set_entry_point("code")
builder.add_edge("code", "review")
builder.add_edge("review", "code", condition=only_if_fixes_required)

# Build the graph
graph = builder.build()

# Execute the graph on a task
result = graph("""Devleop the longest ascening sequence program:
- CLI only
- no tests
- no readme
- app/las.go only
""")

# Access the results
print(f"\nStatus: {result.status}")
print(f"Execution order: {[node.node_id for node in result.execution_order]}")

Related Issues

#549
#497

Documentation PR

I'll handle it once this change is validated.

Type of Change

New feature
Backward compatible

Testing

How have you tested the change? Verify that the changes do not break functionality or introduce warnings in consuming repositories: agents-docs, agents-tools, agents-cli

  • I ran hatch run prepare

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant