langgenius / dify

Dify is an open-source LLM app development platform. Dify's intuitive interface combines AI workflow, RAG pipeline, agent capabilities, model management, observability features and more, letting you quickly go from prototype to production.
https://dify.ai
Other
46.95k stars 6.65k forks source link

I tried to use session variables to solve the problem that iterations cannot be nested, but I found that the value of the session variable accessed in the iteration was wrong, and using code to modify the value of the session variable in the iteration was not effective, and I could no longer continue. #8890

Closed zzkzzk1984 closed 47 minutes ago

zzkzzk1984 commented 2 days ago

Self Checks

Dify version

0.8.0

Cloud or Self Hosted

Self Hosted (Docker)

Steps to reproduce

I tried to use session variables to solve the problem that iterations cannot be nested, but I found that the value of the session variable accessed in the iteration was wrong, and using code to modify the value of the session variable in the iteration was not effective, and I could no longer continue. image image image

✔️ Expected Behavior

Add the function of nested iteration Solve the problem of value transfer exception Run code block to manipulate session variables

❌ Actual Behavior

No response

dosubot[bot] commented 2 days ago

I found a similar unsolved discussion that might be relevant to your issue: Error in item: Invalid variable., which was last updated on 2024-09-23 [1].

To correctly use session variables in nested iterations and avoid the "IndexError: list assignment index out of range" error, ensure that the index used to access elements in the list is within the valid range. Here is an example of how to manage the index and avoid the error:

# Initialize the index and item in the variable pool
variable_pool.add([self.node_id, "index"], 0)
variable_pool.add([self.node_id, "item"], iterator_list_value[0])

# Iterate over the list
for _ in range(len(iterator_list_value)):
    # Run workflow
    rst = graph_engine.run()
    for event in rst:
        # Handle events
        if isinstance(event, NodeRunSucceededEvent):
            # Process the event
            pass

    # Append to iteration output variable list
    current_iteration_output = variable_pool.get_any(self.node_data.output_selector)
    outputs.append(current_iteration_output)

    # Remove all nodes outputs from variable pool
    for node_id in iteration_graph.node_ids:
        variable_pool.remove_node(node_id)

    # Move to next iteration
    current_index = variable_pool.get([self.node_id, "index"])
    if current_index is None:
        raise ValueError(f"iteration {self.node_id} current index not found")

    next_index = int(current_index.to_object()) + 1
    variable_pool.add([self.node_id, "index"], next_index)

    if next_index < len(iterator_list_value):
        variable_pool.add([self.node_id, "item"], iterator_list_value[next_index])

    yield IterationRunNextEvent(
        iteration_id=self.id,
        iteration_node_id=self.node_id,
        iteration_node_type=self.node_type,
        iteration_node_data=self.node_data,
        index=next_index,
        pre_iteration_output=jsonable_encoder(current_iteration_output) if current_iteration_output else None,
    )

In this code:

  1. The index is initialized to 0, and the first item is added to the variable pool.
  2. The loop iterates over the length of the iterator_list_value.
  3. After processing each iteration, the index is incremented.
  4. The next item is added to the variable pool only if the next index is within the valid range (next_index < len(iterator_list_value)).

Additionally, when using session variables, you can leverage the variable assignment node to manage and store variables effectively. For example, you can store user inputs or preferences in session variables and use them in subsequent iterations or workflows. This can help in maintaining context and avoiding errors related to index management [2][3].

To continue talking to Dosu, mention @dosu.