Repository: plurai-ai/intellagent
Issue: I encountered a strange problem while generating simulated dialogue data
Root cause: Algorithmic Error

Hi，Bros,
I encountered a strange problem while generating simulated dialogue data，Code execution error，But it was random, and when I saw the code flow control, I thought there were some issues, so I modified the code and everything returned to normal. Here is my thought and repair process

## Current node execution path determination
```
def contains_isolated_correct(text):
    """
    Check if the word 'CORRECT' exists in the text, surrounded only by non-letters or nothing.

    Args:
        text (str): The input string.

    Returns:
        bool: True if 'CORRECT' is found isolated, False otherwise.
    """
    pattern = r'(?<![a-zA-Z])CORRECT(?![a-zA-Z])'
    return bool(re.search(pattern, text))


def intermediate_processing(state: DialogState):
    """Process the state of the dialog after end_critique and determine what is the next step."""
    # This function is only called after end_critique node
    # Check if the critique feedback indicates success
    if contains_isolated_correct(state['critique_feedback']):
        return 'END'
    else:
        return 'user'


def get_end_condition(self):
    def should_end(state: DialogState):
        terminate = self.intermediate_processing(state)
        if terminate == 'END':
            return END
        else:
            return terminate  # return 'user'
    return should_end
```
```
# Both conditional edges use the same function
workflow.add_conditional_edges(
    "user",
    self.get_end_condition(),  #  The problem lies here
    ["chatbot", "end_critique"],
)
workflow.add_conditional_edges(
    "end_critique",
    self.get_end_condition(),
    ["user", END],
)
```

## The problem lies in:
1,The get_end_condition() used by the first conditional edge ("user" → ["chatbot", "end_critique"]) will only return 'END' or 'user'
2,But the defined optional routes are ["chatbot", "end_critique"]
3,This means that we will never reach 'end_critique', only 'chatbot' or 'END',emmm, maybe even worse：
When terminate=='END '→ returns END object → process ends (not in the list)
When terminate=='user '→ returns the' user 'string → jumps back to the user node (not in the list)
Any node in the list ["chatbot", "end_critique"] will not be executed!

## The actual LangGraph mechanism
LangGraph has two working modes for add_deditional_edges:
Mode 1: Dictionary Mapping 
Mode 2: List Mapping (current in your code)

So I will encounter random errors during the process of generating conversations：
Return 'user' string → LangGraph cannot match the index of the list → Possible error or unpredictable behavior
Return END → Not in the list → Possible error
We can never return 'end_critique' because this function does not return this value

## The correct logic should be
```
def user_end_condition(self, state: DialogState):
    """After user node: Decide whether to comment or continue the conversation,decides next step based on stop signal"""
    if state['stop_signal'] != '':  # User sent ###STOP
        return 'end_critique'  #  To make a comment
    else:
        return 'chatbot'  #  continue the conversation

def critique_end_condition(self, state: DialogState):
    """After end_critique node: Deciding whether to end or continue"""
    if self.intermediate_processing(state) == 'END':
        return END  #  Dialogue successful, ended
    else:
        return 'user'  #  Dialogue failed, user retry
```
## Complete flowchart

<img width="1106" height="637" alt="Image" src="https://github.com/user-attachments/assets/579ae933-b381-4e58-be30-f5f49bbcf4e8" />

## Suggested revision

```
def user_end_condition(self, state: DialogState):
    """After user node: decides next step based on stop signal"""
    if state['stop_signal'] != '':
        return 'end_critique'
    else:
        return 'chatbot'

def compile_graph(self):
    workflow = StateGraph(DialogState)
    workflow.add_node("user", self.get_user_node())
    workflow.add_node("chatbot", self.get_chatbot_node())
    workflow.add_node("end_critique", self.get_critique_node())
    workflow.add_edge(START, "user")
    workflow.add_conditional_edges(
        "user",
        self.user_end_condition,  #  change to user_end_condition
        ["chatbot", "end_critique"],
    )
    workflow.add_conditional_edges(
        "end_critique",
        self.get_end_condition(),  #  This can be kept
        ["user", END],
    )
    workflow.add_edge("chatbot", "user")
    self.graph = workflow.compile()
```
in this way can the complete cycle of dialogue, evaluation, and retry be achieved.


I agree that this approach is better. Could you submit a PR?

Hi,bro,
I have submitted a PR and also optimized the file code: [Directly click on the link](https://github.com/plurai-ai/intellagent/pull/95)

1. I believe that node methods return internal functions (get_user_node()、get_critique_node() , etc.), and this multi-layered nesting is unnecessary and not easy to read.
2. Directly defining node processing logic as class methods (simulated_user_node、critique_node、chat_bot_node) can slightly improve performance (reduce the creation of multiple functions at runtime) and slightly improve memory/performance.
3. No functional changes after optimization