How to Develop a Flow with Conditional Branches#

This guide demonstrates how to:

  1. Define properties to document the input and output types of nodes in a flow

  2. Configure an LLM model

  3. Define different types of nodes for a flow

  4. Define edges for controlling the flow (including branching and loops) and passing data between nodes

  5. Define a flow and export its Agent Spec configuration

The example illustrates an assistant which generates code, reviews the generated code, and either submits or regenerates it based on the review. This flow pattern can be applied to other use cases.

Basic implementation#

1. Define properties#

Properties are used to annotate node configurations with the expected input and output types. This helps enforce data consistency throughout the flow.

from pyagentspec.property import Property

user_request_property = Property(
    json_schema=dict(
        title="user_request",
        type="string",
    )
)

code_property = Property(
    json_schema=dict(
        title="code",
        type="string",
        default="",
    )
)

review_property = Property(
    json_schema=dict(
        title="review",
        type="string",
        default="",
    )
)

is_code_ready_property = Property(
    json_schema=dict(
        title="is_code_ready",
        type="boolean",
        default=False,
    )
)

API Reference: Property

2. Define the LLM model#

Flows typically contain nodes that rely on messages generated by a Large Language Model (LLM). To define these nodes, you must provide the LLM configuration. Several backend options are supported, including the OCI Generative AI service or a self-hosted model using vLLM.

from pyagentspec.llms import OciGenAiConfig
from pyagentspec.llms.ociclientconfig import OciClientConfigWithApiKey

client_config = OciClientConfigWithApiKey(
    name="Oci Client Config",
    service_endpoint="https://url-to-service-endpoint.com",
    auth_profile="DEFAULT",
    auth_file_location="~/.oci/config"
)

llm_config = OciGenAiConfig(
    name="Oci GenAI Config",
    model_id="provider.model-id",
    compartment_id="compartment-id",
    client_config=client_config,
)

API Reference: VllmConfig

3. Define nodes#

The StartNode specifies the expected input values, while the EndNode defines the outputs returned upon successful execution of the flow.

from pyagentspec.flows.nodes import EndNode, StartNode

start_node = StartNode(
    name="Start node",
    inputs=[user_request_property],
)

end_node = EndNode(
    name="End node",
    outputs=[code_property],
)

API Reference: StartNode and EndNode

Nodes of type LlmNode are configured with a prompt and an LlmConfig to generate a new message from a language model. This message is based on the prompt. The generated message can be, for example, code or a review of previously generated code, as shown in the examples below:

from pyagentspec.flows.nodes import LlmNode

generate_code_node = LlmNode(
    name="Generate code node",
    prompt_template="""You are a great code python software engineer.

    Please write the python code to satisfy the following user request: "{{user_request}}".

    You previously generated the following snippet of code:
    ```
    {{code}}
    ```
    Take inspiration from the snippet of code.

    The code reviewer gave the following feedback:
    {{review}}
    Take also into account the comments in the review

    Write only the python code.
    """,
    llm_config=llm_config,
    inputs=[user_request_property, code_property, review_property],
    outputs=[code_property],
)

review_code_node = LlmNode(
    name="Review code node",
    prompt_template="""You are a great code python software engineer, and a highly skilled code reviewer.
    Please review the following snippet of python code:
    ```
    {{code}}
    ```
    """,
    llm_config=llm_config,
    inputs=[code_property],
    outputs=[review_property],
)

API Reference: LlmNode

A BranchingNode can take different paths through the execution of a flow. In the example below, it is used in conjunction with an LlmNode that evaluates whether the generated code should be accepted or regenerated.

from pyagentspec.flows.nodes import BranchingNode, LlmNode

is_code_ready_decision_node = LlmNode(
    name="Check if code is ready node",
    prompt_template="""You are a software engineer with 20 years of experience. You have to take a decision.
    Based on the following code review, do you think that the code is ready to be deployed?
    ```
    {{review}}
    ```
    Please answer only with `yes` or `no`.
    """,
    llm_config=llm_config,
    inputs=[review_property],
    outputs=[is_code_ready_property],
)

is_code_ready_branching_node = BranchingNode(
    name="Is code ready branching node",
    mapping={
        "yes": "yes",
        "no": "no",
    },
    inputs=[is_code_ready_property],
    outputs=[],
)

API Reference: StartNode and EndNode

4. Define the control and data flow edges#

There are two types of edges in a flow:

  • ControlFlowEdges control the sequence of nodes that gets executed.

  • DataFlowEdges define how data is passed from one node to another.

This manner of defining control and data flow edges allows for advanced behaviors such as conditional branching and looping, as illustrated in the example below.

In the control edges defined below, notice that two edges are connected to the BranchingNode (is_code_ready_branching_to_end_control_edge) due to the two possible branches of the node.

from pyagentspec.flows.edges.controlflowedge import ControlFlowEdge

control_flow_edges = [
    ControlFlowEdge(
        name="start_to_generate_code_control_edge",
        from_node=start_node,
        to_node=generate_code_node,
    ),
    ControlFlowEdge(
        name="generate_code_to_review_control_edge",
        from_node=generate_code_node,
        to_node=review_code_node,
    ),
    ControlFlowEdge(
        name="review_to_is_code_ready_decision_control_edge",
        from_node=review_code_node,
        to_node=is_code_ready_decision_node,
    ),
    ControlFlowEdge(
        name="is_code_ready_decision_to_is_code_ready_branching_control_edge",
        from_node=is_code_ready_decision_node,
        to_node=is_code_ready_branching_node,
    ),
    ControlFlowEdge(
        name="is_code_ready_branching_to_end_control_edge",
        from_node=is_code_ready_branching_node,
        from_branch="yes",
        to_node=end_node,
    ),
    ControlFlowEdge(
        name="is_code_ready_branching_to_generate_code_control_edge",
        from_node=is_code_ready_branching_node,
        from_branch="no",
        to_node=generate_code_node,
    ),
]

API Reference: ControlFlowEdge

In the data edges below, note that the code output from the generate_code_node is passed to three different nodes:

  • end_node - because the generated code is the final output of the flow.

  • generate_code_node itself - to include previously generated code in the prompt and improve the next version.

  • review_code_node - because the generated code is used to generate a code review.

from pyagentspec.flows.edges.dataflowedge import DataFlowEdge

data_flow_edges = [
    DataFlowEdge(
        name="start_to_generate_code_user_request_data_edge",
        source_node=start_node,
        source_output="user_request",
        destination_node=generate_code_node,
        destination_input="user_request",
    ),
    DataFlowEdge(
        name="generate_code_to_end_code_data_edge",
        source_node=generate_code_node,
        source_output="code",
        destination_node=end_node,
        destination_input="code",
    ),
    DataFlowEdge(
        name="generate_code_to_generate_code_code_data_edge",
        source_node=generate_code_node,
        source_output="code",
        destination_node=generate_code_node,
        destination_input="code",
    ),
    DataFlowEdge(
        name="generate_code_to_review_code_data_edge",
        source_node=generate_code_node,
        source_output="code",
        destination_node=review_code_node,
        destination_input="code",
    ),
    DataFlowEdge(
        name="review_code_to_generate_code_review_data_edge",
        source_node=review_code_node,
        source_output="review",
        destination_node=generate_code_node,
        destination_input="review",
    ),
    DataFlowEdge(
        name="review_code_to_is_code_ready_review_data_edge",
        source_node=review_code_node,
        source_output="review",
        destination_node=is_code_ready_decision_node,
        destination_input="review",
    ),
    DataFlowEdge(
        name="review_code_to_is_code_ready_flag_data_edge",
        source_node=is_code_ready_decision_node,
        source_output="is_code_ready",
        destination_node=is_code_ready_branching_node,
        destination_input="is_code_ready",
    ),
]

API Reference: DataFlowEdge

5. Define and export the Flow#

With all nodes and edges defined, you can now assemble them into a complete flow.

from pyagentspec.flows.flow import Flow

final_assistant_flow = Flow(
    name="Generate code and review flow",
    description="Flow that given a user request, generates a python code snippet to satisfy it and passes it through a code review before returning it",
    start_node=start_node,
    nodes=[
        start_node,
        generate_code_node,
        review_code_node,
        is_code_ready_decision_node,
        is_code_ready_branching_node,
        end_node,
    ],
    control_flow_connections=control_flow_edges,
    data_flow_connections=data_flow_edges,
)

The Agent Spec configuration is generated in JSON format. It can be loaded into any Agent Spec-compatible system, such as the WayFlow runtime. See, for example, How to Execute Agent Spec Configuration with WayFlow.

from pyagentspec.serialization import AgentSpecSerializer

if __name__ == "__main__":
    serialized_agent = AgentSpecSerializer().to_json(final_assistant_flow)
    print(serialized_agent)

API Reference: AgentSpecSerializer

Here is what the Agent Spec representation will look like ↓

Click here to see the assistant configuration.
{
  "component_type": "Flow",
  "id": "0facfa1b-11ac-4fcd-b95b-61955a94353e",
  "name": "Generate code and review flow",
  "description": "Flow that given a user request, generates a python code snippet to satisfy it and passes it through a code review before returning it",
  "metadata": {},
  "inputs": [
    {
      "title": "user_request",
      "type": "string"
    }
  ],
  "outputs": [
    {
      "title": "code",
      "type": "string",
      "default": ""
    }
  ],
  "start_node": {
    "$component_ref": "df5db1b8-528f-4fc9-918f-889677bf154b"
  },
  "nodes": [
    {
      "$component_ref": "df5db1b8-528f-4fc9-918f-889677bf154b"
    },
    {
      "$component_ref": "a97259f8-8be3-42ac-9909-e21cdd07e9a5"
    },
    {
      "$component_ref": "52049362-86df-400d-ab95-112ce0d045dc"
    },
    {
      "$component_ref": "e7c5ca9a-a008-43c0-93f2-efc337a01d90"
    },
    {
      "$component_ref": "075642ba-b177-428d-939f-3b1e16def02c"
    },
    {
      "$component_ref": "3fb86623-80d5-40aa-9362-88b778c61e9b"
    }
  ],
  "control_flow_connections": [
    {
      "component_type": "ControlFlowEdge",
      "id": "e98a0f0f-6372-4f4b-8c5c-1e61c5fdb677",
      "name": "start_to_generate_code_control_edge",
      "description": null,
      "metadata": {},
      "from_node": {
        "$component_ref": "df5db1b8-528f-4fc9-918f-889677bf154b"
      },
      "from_branch": null,
      "to_node": {
        "$component_ref": "a97259f8-8be3-42ac-9909-e21cdd07e9a5"
      }
    },
    {
      "component_type": "ControlFlowEdge",
      "id": "22705617-f433-4f66-bb75-8ff1e35fed1c",
      "name": "generate_code_to_review_control_edge",
      "description": null,
      "metadata": {},
      "from_node": {
        "$component_ref": "a97259f8-8be3-42ac-9909-e21cdd07e9a5"
      },
      "from_branch": null,
      "to_node": {
        "$component_ref": "52049362-86df-400d-ab95-112ce0d045dc"
      }
    },
    {
      "component_type": "ControlFlowEdge",
      "id": "c65c4d53-42cd-43fb-9faf-1138a23f49dc",
      "name": "review_to_is_code_ready_decision_control_edge",
      "description": null,
      "metadata": {},
      "from_node": {
        "$component_ref": "52049362-86df-400d-ab95-112ce0d045dc"
      },
      "from_branch": null,
      "to_node": {
        "$component_ref": "e7c5ca9a-a008-43c0-93f2-efc337a01d90"
      }
    },
    {
      "component_type": "ControlFlowEdge",
      "id": "770ee2ef-9ec4-42e3-b323-767219d3ebe2",
      "name": "is_code_ready_decision_to_is_code_ready_branching_control_edge",
      "description": null,
      "metadata": {},
      "from_node": {
        "$component_ref": "e7c5ca9a-a008-43c0-93f2-efc337a01d90"
      },
      "from_branch": null,
      "to_node": {
        "$component_ref": "075642ba-b177-428d-939f-3b1e16def02c"
      }
    },
    {
      "component_type": "ControlFlowEdge",
      "id": "9763ebfe-e4ce-41e1-98fe-e1c34ca60705",
      "name": "is_code_ready_branching_to_end_control_edge",
      "description": null,
      "metadata": {},
      "from_node": {
        "$component_ref": "075642ba-b177-428d-939f-3b1e16def02c"
      },
      "from_branch": "yes",
      "to_node": {
        "$component_ref": "3fb86623-80d5-40aa-9362-88b778c61e9b"
      }
    },
    {
      "component_type": "ControlFlowEdge",
      "id": "f5186c2a-f5df-4a41-a116-a6a1aa869d68",
      "name": "is_code_ready_branching_to_generate_code_control_edge",
      "description": null,
      "metadata": {},
      "from_node": {
        "$component_ref": "075642ba-b177-428d-939f-3b1e16def02c"
      },
      "from_branch": "no",
      "to_node": {
        "$component_ref": "a97259f8-8be3-42ac-9909-e21cdd07e9a5"
      }
    }
  ],
  "data_flow_connections": [
    {
      "component_type": "DataFlowEdge",
      "id": "1ba462c6-905f-4f1b-b26c-c8d5cb95df06",
      "name": "start_to_generate_code_user_request_data_edge",
      "description": null,
      "metadata": {},
      "source_node": {
        "$component_ref": "df5db1b8-528f-4fc9-918f-889677bf154b"
      },
      "source_output": "user_request",
      "destination_node": {
        "$component_ref": "a97259f8-8be3-42ac-9909-e21cdd07e9a5"
      },
      "destination_input": "user_request"
    },
    {
      "component_type": "DataFlowEdge",
      "id": "4f2924f2-fb71-4a11-abad-204a7cdcaeca",
      "name": "generate_code_to_end_code_data_edge",
      "description": null,
      "metadata": {},
      "source_node": {
        "$component_ref": "a97259f8-8be3-42ac-9909-e21cdd07e9a5"
      },
      "source_output": "code",
      "destination_node": {
        "$component_ref": "3fb86623-80d5-40aa-9362-88b778c61e9b"
      },
      "destination_input": "code"
    },
    {
      "component_type": "DataFlowEdge",
      "id": "8c2d7b8f-2bdd-4119-a047-2f692d54c4ec",
      "name": "generate_code_to_generate_code_code_data_edge",
      "description": null,
      "metadata": {},
      "source_node": {
        "$component_ref": "a97259f8-8be3-42ac-9909-e21cdd07e9a5"
      },
      "source_output": "code",
      "destination_node": {
        "$component_ref": "a97259f8-8be3-42ac-9909-e21cdd07e9a5"
      },
      "destination_input": "code"
    },
    {
      "component_type": "DataFlowEdge",
      "id": "e299c1e1-570f-4b8a-aa75-0a4b2af3bb22",
      "name": "generate_code_to_review_code_data_edge",
      "description": null,
      "metadata": {},
      "source_node": {
        "$component_ref": "a97259f8-8be3-42ac-9909-e21cdd07e9a5"
      },
      "source_output": "code",
      "destination_node": {
        "$component_ref": "52049362-86df-400d-ab95-112ce0d045dc"
      },
      "destination_input": "code"
    },
    {
      "component_type": "DataFlowEdge",
      "id": "6ab1d280-197b-4f9f-85d6-b12512e63b6c",
      "name": "review_code_to_generate_code_review_data_edge",
      "description": null,
      "metadata": {},
      "source_node": {
        "$component_ref": "52049362-86df-400d-ab95-112ce0d045dc"
      },
      "source_output": "review",
      "destination_node": {
        "$component_ref": "a97259f8-8be3-42ac-9909-e21cdd07e9a5"
      },
      "destination_input": "review"
    },
    {
      "component_type": "DataFlowEdge",
      "id": "e01a059a-3745-46f6-a249-b080bca5466d",
      "name": "review_code_to_is_code_ready_review_data_edge",
      "description": null,
      "metadata": {},
      "source_node": {
        "$component_ref": "52049362-86df-400d-ab95-112ce0d045dc"
      },
      "source_output": "review",
      "destination_node": {
        "$component_ref": "e7c5ca9a-a008-43c0-93f2-efc337a01d90"
      },
      "destination_input": "review"
    },
    {
      "component_type": "DataFlowEdge",
      "id": "9e499cf0-cf9f-44c8-8ad8-02ce8bb75832",
      "name": "review_code_to_is_code_ready_flag_data_edge",
      "description": null,
      "metadata": {},
      "source_node": {
        "$component_ref": "e7c5ca9a-a008-43c0-93f2-efc337a01d90"
      },
      "source_output": "is_code_ready",
      "destination_node": {
        "$component_ref": "075642ba-b177-428d-939f-3b1e16def02c"
      },
      "destination_input": "is_code_ready"
    }
  ],
  "$referenced_components": {
    "a97259f8-8be3-42ac-9909-e21cdd07e9a5": {
      "component_type": "LlmNode",
      "id": "a97259f8-8be3-42ac-9909-e21cdd07e9a5",
      "name": "Generate code node",
      "description": null,
      "metadata": {},
      "inputs": [
        {
          "title": "user_request",
          "type": "string"
        },
        {
          "title": "code",
          "type": "string",
          "default": ""
        },
        {
          "title": "review",
          "type": "string",
          "default": ""
        }
      ],
      "outputs": [
        {
          "title": "code",
          "type": "string",
          "default": ""
        }
      ],
      "branches": [
        "next"
      ],
      "llm_config": {
        "$component_ref": "4401c9a2-d5d3-409e-a2c1-e7f8a83c4570"
      },
      "prompt_template": "You are a great code python software engineer.\n\n    Please write the python code to satisfy the following user request: \"{{user_request}}\".\n\n    You previously generated the following snippet of code:\n    ```\n    {{code}}\n    ```\n    Take inspiration from the snippet of code.\n\n    The code reviewer gave the following feedback:\n    {{review}}\n    Take also into account the comments in the review\n\n    Write only the python code.\n    "
    },
    "4401c9a2-d5d3-409e-a2c1-e7f8a83c4570": {
      "component_type": "VllmConfig",
      "id": "4401c9a2-d5d3-409e-a2c1-e7f8a83c4570",
      "name": "Vllm model",
      "description": null,
      "metadata": {},
      "default_generation_parameters": null,
      "url": "vllm_url",
      "model_id": "model_id"
    },
    "df5db1b8-528f-4fc9-918f-889677bf154b": {
      "component_type": "StartNode",
      "id": "df5db1b8-528f-4fc9-918f-889677bf154b",
      "name": "Start node",
      "description": null,
      "metadata": {},
      "inputs": [
        {
          "title": "user_request",
          "type": "string"
        }
      ],
      "outputs": [
        {
          "title": "user_request",
          "type": "string"
        }
      ],
      "branches": [
        "next"
      ]
    },
    "52049362-86df-400d-ab95-112ce0d045dc": {
      "component_type": "LlmNode",
      "id": "52049362-86df-400d-ab95-112ce0d045dc",
      "name": "Review code node",
      "description": null,
      "metadata": {},
      "inputs": [
        {
          "title": "code",
          "type": "string",
          "default": ""
        }
      ],
      "outputs": [
        {
          "title": "review",
          "type": "string",
          "default": ""
        }
      ],
      "branches": [
        "next"
      ],
      "llm_config": {
        "$component_ref": "4401c9a2-d5d3-409e-a2c1-e7f8a83c4570"
      },
      "prompt_template": "You are a great code python software engineer, and a highly skilled code reviewer.\n    Please review the following snippet of python code:\n    ```\n    {{code}}\n    ```\n    "
    },
    "e7c5ca9a-a008-43c0-93f2-efc337a01d90": {
      "component_type": "LlmNode",
      "id": "e7c5ca9a-a008-43c0-93f2-efc337a01d90",
      "name": "Check if code is ready node",
      "description": null,
      "metadata": {},
      "inputs": [
        {
          "title": "review",
          "type": "string",
          "default": ""
        }
      ],
      "outputs": [
        {
          "title": "is_code_ready",
          "type": "boolean",
          "default": false
        }
      ],
      "branches": [
        "next"
      ],
      "llm_config": {
        "$component_ref": "4401c9a2-d5d3-409e-a2c1-e7f8a83c4570"
      },
      "prompt_template": "You are a software engineer with 20 years of experience. You have to take a decision.\n    Based on the following code review, do you think that the code is ready to be deployed?\n    ```\n    {{review}}\n    ```\n    Please answer only with `yes` or `no`.\n    "
    },
    "075642ba-b177-428d-939f-3b1e16def02c": {
      "component_type": "BranchingNode",
      "id": "075642ba-b177-428d-939f-3b1e16def02c",
      "name": "Is code ready branching node",
      "description": null,
      "metadata": {},
      "inputs": [
        {
          "title": "is_code_ready",
          "type": "boolean",
          "default": false
        }
      ],
      "outputs": [],
      "branches": [
        "default",
        "no",
        "yes"
      ],
      "mapping": {
        "yes": "yes",
        "no": "no"
      }
    },
    "3fb86623-80d5-40aa-9362-88b778c61e9b": {
      "component_type": "EndNode",
      "id": "3fb86623-80d5-40aa-9362-88b778c61e9b",
      "name": "End node",
      "description": null,
      "metadata": {},
      "inputs": [
        {
          "title": "code",
          "type": "string",
          "default": ""
        }
      ],
      "outputs": [
        {
          "title": "code",
          "type": "string",
          "default": ""
        }
      ],
      "branches": [],
      "branch_name": "next"
    }
  },
  "agentspec_version": "25.4.1"
}

Recap#

This how-to guide covered how to:

  • Define properties to document the input and output types of nodes in a flow

  • Configure an LLM model

  • Define different types of nodes for a flow

  • Define edges for controlling the flow (including branching and loops) and passing data between nodes

  • Define a flow and export its Agent Spec configuration

Below is the complete code from this guide.
  1from pyagentspec.flows.edges.controlflowedge import ControlFlowEdge
  2from pyagentspec.flows.edges.dataflowedge import DataFlowEdge
  3from pyagentspec.flows.flow import Flow
  4from pyagentspec.flows.nodes import BranchingNode, EndNode, LlmNode, StartNode
  5from pyagentspec.llms.vllmconfig import VllmConfig
  6from pyagentspec.property import Property
  7from pyagentspec.serialization import AgentSpecSerializer
  8
  9user_request_property = Property(
 10    json_schema=dict(
 11        title="user_request",
 12        type="string",
 13    )
 14)
 15
 16code_property = Property(
 17    json_schema=dict(
 18        title="code",
 19        type="string",
 20        default="",
 21    )
 22)
 23
 24review_property = Property(
 25    json_schema=dict(
 26        title="review",
 27        type="string",
 28        default="",
 29    )
 30)
 31
 32is_code_ready_property = Property(
 33    json_schema=dict(
 34        title="is_code_ready",
 35        type="boolean",
 36        default=False,
 37    )
 38)
 39
 40
 41llm_config = VllmConfig(
 42    name="Vllm model",
 43    url="vllm_url",
 44    model_id="model_id",
 45)
 46
 47
 48start_node = StartNode(
 49    name="Start node",
 50    inputs=[user_request_property],
 51)
 52
 53end_node = EndNode(
 54    name="End node",
 55    outputs=[code_property],
 56)
 57
 58
 59generate_code_node = LlmNode(
 60    name="Generate code node",
 61    prompt_template="""You are a great code python software engineer.
 62
 63    Please write the python code to satisfy the following user request: "{{user_request}}".
 64
 65    You previously generated the following snippet of code:
 66    ```
 67    {{code}}
 68    ```
 69    Take inspiration from the snippet of code.
 70
 71    The code reviewer gave the following feedback:
 72    {{review}}
 73    Take also into account the comments in the review
 74
 75    Write only the python code.
 76    """,
 77    llm_config=llm_config,
 78    inputs=[user_request_property, code_property, review_property],
 79    outputs=[code_property],
 80)
 81
 82review_code_node = LlmNode(
 83    name="Review code node",
 84    prompt_template="""You are a great code python software engineer, and a highly skilled code reviewer.
 85    Please review the following snippet of python code:
 86    ```
 87    {{code}}
 88    ```
 89    """,
 90    llm_config=llm_config,
 91    inputs=[code_property],
 92    outputs=[review_property],
 93)
 94
 95is_code_ready_decision_node = LlmNode(
 96    name="Check if code is ready node",
 97    prompt_template="""You are a software engineer with 20 years of experience. You have to take a decision.
 98    Based on the following code review, do you think that the code is ready to be deployed?
 99    ```
100    {{review}}
101    ```
102    Please answer only with `yes` or `no`.
103    """,
104    llm_config=llm_config,
105    inputs=[review_property],
106    outputs=[is_code_ready_property],
107)
108
109is_code_ready_branching_node = BranchingNode(
110    name="Is code ready branching node",
111    mapping={
112        "yes": "yes",
113        "no": "no",
114    },
115    inputs=[is_code_ready_property],
116    outputs=[],
117)
118
119control_flow_edges = [
120    ControlFlowEdge(
121        name="start_to_generate_code_control_edge",
122        from_node=start_node,
123        to_node=generate_code_node,
124    ),
125    ControlFlowEdge(
126        name="generate_code_to_review_control_edge",
127        from_node=generate_code_node,
128        to_node=review_code_node,
129    ),
130    ControlFlowEdge(
131        name="review_to_is_code_ready_decision_control_edge",
132        from_node=review_code_node,
133        to_node=is_code_ready_decision_node,
134    ),
135    ControlFlowEdge(
136        name="is_code_ready_decision_to_is_code_ready_branching_control_edge",
137        from_node=is_code_ready_decision_node,
138        to_node=is_code_ready_branching_node,
139    ),
140    ControlFlowEdge(
141        name="is_code_ready_branching_to_end_control_edge",
142        from_node=is_code_ready_branching_node,
143        from_branch="yes",
144        to_node=end_node,
145    ),
146    ControlFlowEdge(
147        name="is_code_ready_branching_to_generate_code_control_edge",
148        from_node=is_code_ready_branching_node,
149        from_branch="no",
150        to_node=generate_code_node,
151    ),
152]
153
154
155data_flow_edges = [
156    DataFlowEdge(
157        name="start_to_generate_code_user_request_data_edge",
158        source_node=start_node,
159        source_output="user_request",
160        destination_node=generate_code_node,
161        destination_input="user_request",
162    ),
163    DataFlowEdge(
164        name="generate_code_to_end_code_data_edge",
165        source_node=generate_code_node,
166        source_output="code",
167        destination_node=end_node,
168        destination_input="code",
169    ),
170    DataFlowEdge(
171        name="generate_code_to_generate_code_code_data_edge",
172        source_node=generate_code_node,
173        source_output="code",
174        destination_node=generate_code_node,
175        destination_input="code",
176    ),
177    DataFlowEdge(
178        name="generate_code_to_review_code_data_edge",
179        source_node=generate_code_node,
180        source_output="code",
181        destination_node=review_code_node,
182        destination_input="code",
183    ),
184    DataFlowEdge(
185        name="review_code_to_generate_code_review_data_edge",
186        source_node=review_code_node,
187        source_output="review",
188        destination_node=generate_code_node,
189        destination_input="review",
190    ),
191    DataFlowEdge(
192        name="review_code_to_is_code_ready_review_data_edge",
193        source_node=review_code_node,
194        source_output="review",
195        destination_node=is_code_ready_decision_node,
196        destination_input="review",
197    ),
198    DataFlowEdge(
199        name="review_code_to_is_code_ready_flag_data_edge",
200        source_node=is_code_ready_decision_node,
201        source_output="is_code_ready",
202        destination_node=is_code_ready_branching_node,
203        destination_input="is_code_ready",
204    ),
205]
206
207
208final_assistant_flow = Flow(
209    name="Generate code and review flow",
210    description="Flow that given a user request, generates a python code snippet to satisfy it and passes it through a code review before returning it",
211    start_node=start_node,
212    nodes=[
213        start_node,
214        generate_code_node,
215        review_code_node,
216        is_code_ready_decision_node,
217        is_code_ready_branching_node,
218        end_node,
219    ],
220    control_flow_connections=control_flow_edges,
221    data_flow_connections=data_flow_edges,
222)
223
224
225if __name__ == "__main__":
226    serialized_agent = AgentSpecSerializer().to_json(final_assistant_flow)
227    print(serialized_agent)

Next steps#

Having learned how to develop a flow with conditional branches, you may now proceed to How to Execute Agent Spec Configuration with WayFlow.