How to add more iterations in iteration? #5857

Closed
opened 2026-02-21 18:12:54 -05:00 by yindo · 1 comment
Owner

Originally created by @zzkzzk1984 on GitHub (Sep 29, 2024).

Self Checks

  • I have searched for existing issues search for existing issues, including closed ones.
  • I confirm that I am using English to submit this report (我已阅读并同意 Language Policy).
  • [FOR CHINESE USERS] 请务必使用英文提交 Issue,否则会被关闭。谢谢!:)
  • Please do not modify this template :) and fill in all the required fields.

1. Is this request related to a challenge you're experiencing? Tell me about your story.

How to add more iterations in iteration

2. Additional context or comments

No response

3. Can you help us with this feature?

  • I am interested in contributing to this feature.
Originally created by @zzkzzk1984 on GitHub (Sep 29, 2024). ### Self Checks - [X] I have searched for existing issues [search for existing issues](https://github.com/langgenius/dify/issues), including closed ones. - [X] I confirm that I am using English to submit this report (我已阅读并同意 [Language Policy](https://github.com/langgenius/dify/issues/1542)). - [X] [FOR CHINESE USERS] 请务必使用英文提交 Issue,否则会被关闭。谢谢!:) - [X] Please do not modify this template :) and fill in all the required fields. ### 1. Is this request related to a challenge you're experiencing? Tell me about your story. How to add more iterations in iteration ### 2. Additional context or comments _No response_ ### 3. Can you help us with this feature? - [ ] I am interested in contributing to this feature.
yindo added the 💪 enhancement label 2026-02-21 18:12:54 -05:00
yindo closed this issue 2026-02-21 18:12:54 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Sep 29, 2024):

I found a similar open issue that was closed recently. The solution provided involves adjusting the max_iteration property in the tempPayload object. This can be done using a slider or an input field within the AgentSetting component. Here is the relevant code snippet:

const maxIterationsMin = 1
const maxIterationsMax = 5

...

<ItemPanel
  className='mb-4'
  icon={
    <Unblur className='w-4 h-4 text-[#FB6514]' />
  }
  name={t('appDebug.agent.setting.maximumIterations.name')}
  description={t('appDebug.agent.setting.maximumIterations.description')}
>
  <div className='flex items-center'>
    <Slider
      className='mr-3 w-[156px]'
      min={maxIterationsMin}
      max={maxIterationsMax}
      value={tempPayload.max_iteration}
      onChange={(value) => {
        setTempPayload({
          ...tempPayload,
          max_iteration: value,
        })
      }}
    />

    <input
      type="number"
      min={maxIterationsMin}
      max={maxIterationsMax} step={1}
      className="block w-11 h-7 leading-7 rounded-lg border-0 pl-1 px-1.5 bg-gray-100 text-gray-900  placeholder:text-gray-400 focus:ring-1 focus:ring-inset focus:ring-primary-600"
      value={tempPayload.max_iteration}
      onChange={(e) => {
        let value = parseInt(e.target.value, 10)
        if (value < maxIterationsMin)
          value = maxIterationsMin

        if (value > maxIterationsMax)
          value = maxIterationsMax
        setTempPayload({
          ...tempPayload,
          max_iteration: value,
        })
      }} />
  </div>
</ItemPanel>

This code allows you to set the number of iterations within the range defined by maxIterationsMin and maxIterationsMax [1].

Additionally, to add more iterations in the IterationNode class, you need to modify the _run method to handle additional iterations. Here is the relevant part of the code that handles the iterations:

try:
    for _ in range(len(iterator_list_value)):
        # run workflow
        rst = graph_engine.run()
        for event in rst:
            if isinstance(event, (BaseNodeEvent | BaseParallelBranchEvent)) and not event.in_iteration_id:
                event.in_iteration_id = self.node_id
            if (
                isinstance(event, BaseNodeEvent)
                and event.node_type == NodeType.ITERATION_START
                and not isinstance(event, NodeRunStreamChunkEvent)
            ):
                continue

            if isinstance(event, NodeRunSucceededEvent):
                if event.route_node_state.node_run_result:
                    metadata = event.route_node_state.node_run_result.metadata
                    if not metadata:
                        metadata = {}

                    if NodeRunMetadataKey.ITERATION_ID not in metadata:
                        metadata[NodeRunMetadataKey.ITERATION_ID] = self.node_id
                        metadata[NodeRunMetadataKey.ITERATION_INDEX] = variable_pool.get_any(
                            [self.node_id, "index"]
                        )
                        event.route_node_state.node_run_result.metadata = metadata

                yield event
            elif isinstance(event, BaseGraphEvent):
                if isinstance(event, GraphRunFailedEvent):
                    # iteration run failed
                    yield IterationRunFailedEvent(
                        iteration_id=self.id,
                        iteration_node_id=self.node_id,
                        iteration_node_type=self.node_type,
                        iteration_node_data=self.node_data,
                        start_at=start_at,
                        inputs=inputs,
                        outputs={"output": jsonable_encoder(outputs)},
                        steps=len(iterator_list_value),
                        metadata={"total_tokens": graph_engine.graph_runtime_state.total_tokens},
                        error=event.error,
                    )
                    yield RunCompletedEvent(
                        run_result=NodeRunResult(
                            status=WorkflowNodeExecutionStatus.FAILED,
                            error=event.error,
                        )
                    )
                    return
            else:
                event = cast(InNodeEvent, event)
                yield event

        # 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,
        )

To add more iterations, you can modify the loop condition or the iterator_list_value to include more items. For example, if you want to double the number of iterations, you can concatenate the list with itself:

iterator_list_value = iterator_list_value + iterator_list_value

Or, you can change the loop condition to iterate more times:

for _ in range(2 * len(iterator_list_value)):
    # run workflow
    # ...

Make sure to adjust the logic accordingly to handle the additional iterations properly [2][3].

To continue talking to Dosu, mention @dosu.

@dosubot[bot] commented on GitHub (Sep 29, 2024): <!-- Answer --> I found a similar open issue that was closed recently. The solution provided involves adjusting the `max_iteration` property in the `tempPayload` object. This can be done using a slider or an input field within the `AgentSetting` component. Here is the relevant code snippet: ```tsx const maxIterationsMin = 1 const maxIterationsMax = 5 ... <ItemPanel className='mb-4' icon={ <Unblur className='w-4 h-4 text-[#FB6514]' /> } name={t('appDebug.agent.setting.maximumIterations.name')} description={t('appDebug.agent.setting.maximumIterations.description')} > <div className='flex items-center'> <Slider className='mr-3 w-[156px]' min={maxIterationsMin} max={maxIterationsMax} value={tempPayload.max_iteration} onChange={(value) => { setTempPayload({ ...tempPayload, max_iteration: value, }) }} /> <input type="number" min={maxIterationsMin} max={maxIterationsMax} step={1} className="block w-11 h-7 leading-7 rounded-lg border-0 pl-1 px-1.5 bg-gray-100 text-gray-900 placeholder:text-gray-400 focus:ring-1 focus:ring-inset focus:ring-primary-600" value={tempPayload.max_iteration} onChange={(e) => { let value = parseInt(e.target.value, 10) if (value < maxIterationsMin) value = maxIterationsMin if (value > maxIterationsMax) value = maxIterationsMax setTempPayload({ ...tempPayload, max_iteration: value, }) }} /> </div> </ItemPanel> ``` This code allows you to set the number of iterations within the range defined by `maxIterationsMin` and `maxIterationsMax` <sup>[[1]](https://github.com/langgenius/dify/issues/8880)</sup>. Additionally, to add more iterations in the `IterationNode` class, you need to modify the `_run` method to handle additional iterations. Here is the relevant part of the code that handles the iterations: ```python try: for _ in range(len(iterator_list_value)): # run workflow rst = graph_engine.run() for event in rst: if isinstance(event, (BaseNodeEvent | BaseParallelBranchEvent)) and not event.in_iteration_id: event.in_iteration_id = self.node_id if ( isinstance(event, BaseNodeEvent) and event.node_type == NodeType.ITERATION_START and not isinstance(event, NodeRunStreamChunkEvent) ): continue if isinstance(event, NodeRunSucceededEvent): if event.route_node_state.node_run_result: metadata = event.route_node_state.node_run_result.metadata if not metadata: metadata = {} if NodeRunMetadataKey.ITERATION_ID not in metadata: metadata[NodeRunMetadataKey.ITERATION_ID] = self.node_id metadata[NodeRunMetadataKey.ITERATION_INDEX] = variable_pool.get_any( [self.node_id, "index"] ) event.route_node_state.node_run_result.metadata = metadata yield event elif isinstance(event, BaseGraphEvent): if isinstance(event, GraphRunFailedEvent): # iteration run failed yield IterationRunFailedEvent( iteration_id=self.id, iteration_node_id=self.node_id, iteration_node_type=self.node_type, iteration_node_data=self.node_data, start_at=start_at, inputs=inputs, outputs={"output": jsonable_encoder(outputs)}, steps=len(iterator_list_value), metadata={"total_tokens": graph_engine.graph_runtime_state.total_tokens}, error=event.error, ) yield RunCompletedEvent( run_result=NodeRunResult( status=WorkflowNodeExecutionStatus.FAILED, error=event.error, ) ) return else: event = cast(InNodeEvent, event) yield event # 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, ) ``` To add more iterations, you can modify the loop condition or the `iterator_list_value` to include more items. For example, if you want to double the number of iterations, you can concatenate the list with itself: ```python iterator_list_value = iterator_list_value + iterator_list_value ``` Or, you can change the loop condition to iterate more times: ```python for _ in range(2 * len(iterator_list_value)): # run workflow # ... ``` Make sure to adjust the logic accordingly to handle the additional iterations properly <sup>[[2]](https://github.com/langgenius/dify/blob/main/api/core/workflow/nodes/iteration/iteration_node.py)</sup><sup>[[3]](https://github.com/langgenius/dify-docs/blob/main/en/guides/workflow/node/iteration.md)</sup>. <!-- Dosu Comment Footer --> *To continue talking to [Dosu](https://dosu.dev), mention @dosu.*
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langgenius/dify#5857