Skip to content

Conversation

shaohuzhang1
Copy link
Contributor

fix: When there is a form node in the loop node, the loop data is lost

Copy link

f2c-ci-robot bot commented Oct 17, 2025

Adding the "do-not-merge/release-note-label-needed" label because no release-note block was detected, please follow our release note process to remove it.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

Copy link

f2c-ci-robot bot commented Oct 17, 2025

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@shaohuzhang1 shaohuzhang1 merged commit c0c15d8 into v2 Oct 17, 2025
4 of 5 checks passed
@shaohuzhang1 shaohuzhang1 deleted the pr@v2@fix_workflow branch October 17, 2025 10:13
'loop_context_data': self.get_loop_context_data(),
'loop_node_data': self.context.get("loop_node_data"),
'loop_answer_data': self.context.get("loop_answer_data"),
'err_message': self.err_message
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The provided code appears to be part of an artificial intelligence (AI) system designed to handle workflows with loop nodes and manage states. Here are some comments and suggestions for improving the code:

  1. Comments: Add more detailed comments explaining what each method does, especially the save_context and get_details methods.

  2. Variable Naming: Use descriptive variable names instead of abbreviations like _, which can make the code harder to read.

  3. Loop Context Data Logic: The logic for generating loop_context_data could potentially lead to unnecessary overhead if certain fields always have valid values. Make sure this logic is optimal based on your needs.

  4. Error Handling: Enhance error handling in critical sections such as saving context and fetching data.

  5. Concurrency Considerations: If the workflow management involves concurrency, consider adding thread-safe operations to avoid data corruption.

Here's a revised version of the code with these considerations in mind:

class BaseLoopNode(ILoopNode):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Initialize variables here

    def save_context(self, details, workflow_manage):
        """
        Save contextual information from the provided details.

        :param details: Dictionary containing result, additional context, etc.
        :param workflow_manage: Instance responsible for managing the workflow state.
        """
        self.context['result'] = details.get('result')
        for key, value in details['context'].items():
            # Avoid overwriting existing keys unless necessary
            if key not in self.context:
                self.context[key] = value
        
        # Ensure answer text is stringified
        self.answer_text = str(details.get('result'))

    def get_answer_list(self) -> List[Answer] | None:
        """
        Get the list of answers related to the current node.

        Returns:
            A list of Answer objects or None if no answers are available.
        """
        return [
            Answer(..., name=self.node.properties.get('stepName'), index=index, ...)
            for index in range(len(self.context["loop_answers"]))
        ]

def workflow_manage_new_instance(
    loop_data: dict,
    global_data: dict,
    start_node_id=None,
    _write_context=get_write_context,
    _is_interrupt=_is_interrupt_exec
):
    """
    Manage the creation of a new instance within a workflow.

    Parameters:
        loop_data: Configuration data for loops.
        global_data: Global workflow data.
        start_node_id: ID of the starting node.
        _write_context: Function to write contextual information.
        _is_interrupt: Function to determine interruption status.

    Returns:
        An instance of a WorkflowManagement class managing the created instance.
    """
    # Implementation goes here

def get_loop_context_data(self) -> Dict[str, Any]:
    """Generate specific context data relevant to this loop."""
    fields = self.node.properties.get('config', {}).get('fields', [])
    
    # Filter fields that exist in the context
    return {
        field.get('value'): self.context.get(field.get('value'))
        for field in filter(lambda x: x.get('value') is not None, fields)
    }

def get_details(self, index: int, **kwargs) -> dict:
    """
    Retrieve detailed information about the current step.

    Parameters:
        index: Index identifying the specific detail required.
        **kwargs: Additional keyword arguments for customization.

    Returns:
        A dictionary containing various details about the current step.
    """
    return {
        "name": self.node.properties.get('stepName'),
        "index": index,
        "error_message": kwargs.pop("err_message", ""),
        "current_item": self.context.get("item"),
        'loop_type': self.node_params_serializer.data.get('loop_type'),
        'status': self.status,
        'loop_context_data': self.get_loop_context_data(),
        'loop_node_data': self.context.get("loop_node_data"),
        'loop_answer_data': self.context.get("loop_answer_data")
    }

These changes focus on clarity, readability, and maintainability while ensuring that the core functionality remains intact.

self.start_node.context[k] = v
self.start_node.context['loop_node_data'] = loop_node_data
self.start_node.context['current_index'] = node_details.get('current_index')
self.start_node.context['current_item'] = node_details.get('current_item')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The provided code appears to be part of a function aimed at retrieving parameters for a node, including handling loop nodes. There are a few optimizations and improvements that can be made:

  1. Use get method with default values: To make the code more robust against missing keys in node_details, use the get method with appropriate default values.

  2. Avoid multiple assignments within loop contexts: If loop_context_data contains many entries, avoid making multiple assignments within a loop. Instead, initialize a dictionary outside the loop and populate it during iteration.

  3. Consider using data classes or dictionaries for consistency: Ensure that the data structure being used (dictionary vs. data class) remains consistent throughout the codebase for better manageability and type safety.

  4. Error Handling: Add error handling around network requests (if applicable) to manage exceptions gracefully.

Here's an optimized version of the code incorporating some of these suggestions:

def get_node_params(n):
    start_node_data = node_details.get('start_node_data', {})

    if n.start_node.type == 'loop-node':
        loop_node_data = node_details.get('loop_node_data', {})
        
        # Initialize context dictionary outside the loop for efficiency
        updated_context = {}

        for k, v in node_details.get('loop_context_data', {}).items():
            if v is not None:
                updated_context[k] = v

        self.start_node.context.update(updated_context)
        self.start_node.context['loop_node_data'] = loop_node_data
        self.start_node.context['current_index'] = node_details.get('current_index', 0)
        self.start_node.context['current_item'] = node_details.get('current_item')

    return params_dict  # Replace 'params_dict' with actual parameter dict logic

This refactored version uses a dictionary updated_context to accumulate loop context values before updating the context field of self.start_node. This reduces redundancy and improves readability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant