Skip to content

fix: Having the same suffix for function node names can result in incorrect value retrieval #2513

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 7, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 34 additions & 17 deletions apps/application/flow/workflow_manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,11 +269,36 @@ def __init__(self, flow: Flow, params, work_flow_post_handler: WorkFlowPostHandl
self.child_node = child_node
self.future_list = []
self.lock = threading.Lock()
self.field_list = []
self.global_field_list = []
self.init_fields()
if start_node_id is not None:
self.load_node(chat_record, start_node_id, start_node_data)
else:
self.node_context = []

def init_fields(self):
field_list = []
global_field_list = []
for node in self.flow.nodes:
properties = node.properties
node_name = properties.get('stepName')
node_id = node.id
node_config = properties.get('config')
if node_config is not None:
fields = node_config.get('fields')
if fields is not None:
for field in fields:
field_list.append({**field, 'node_id': node_id, 'node_name': node_name})
global_fields = node_config.get('globalFields')
if global_fields is not None:
for global_field in global_fields:
global_field_list.append({**global_field, 'node_id': node_id, 'node_name': node_name})
field_list.sort(key=lambda f: len(f.get('node_name')), reverse=True)
global_field_list.sort(key=lambda f: len(f.get('node_name')), reverse=True)
self.field_list = field_list
self.global_field_list = global_field_list

def append_answer(self, content):
self.answer += content
self.answer_list[-1] += content
Expand Down Expand Up @@ -739,23 +764,15 @@ def get_workflow_content(self):

def reset_prompt(self, prompt: str):
placeholder = "{}"
for node in self.flow.nodes:
properties = node.properties
node_config = properties.get('config')
if node_config is not None:
fields = node_config.get('fields')
if fields is not None:
for field in fields:
globeLabel = f"{properties.get('stepName')}.{field.get('value')}"
globeValue = f"context.get('{node.id}',{placeholder}).get('{field.get('value', '')}','')"
prompt = prompt.replace(globeLabel, globeValue)
global_fields = node_config.get('globalFields')
if global_fields is not None:
for field in global_fields:
globeLabel = f"全局变量.{field.get('value')}"
globeLabelNew = f"global.{field.get('value')}"
globeValue = f"context.get('global').get('{field.get('value', '')}','')"
prompt = prompt.replace(globeLabel, globeValue).replace(globeLabelNew, globeValue)
for field in self.field_list:
globeLabel = f"{field.get('node_name')}.{field.get('value')}"
globeValue = f"context.get('{field.get('node_id')}',{placeholder}).get('{field.get('value', '')}','')"
prompt = prompt.replace(globeLabel, globeValue)
for field in self.global_field_list:
globeLabel = f"全局变量.{field.get('value')}"
globeLabelNew = f"global.{field.get('value')}"
globeValue = f"context.get('global').get('{field.get('value', '')}','')"
prompt = prompt.replace(globeLabel, globeValue).replace(globeLabelNew, globeValue)
return prompt

def generate_prompt(self, prompt: str):
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 does not contain apparent syntax errors. However, here are some concerns and optimizations that could be made:

Concerns:

  1. Field Initialization: The init_fields method iterates over each node in the flow, checks for specific configurations, and collects field information (fields and globalFields). If a field has no name or value, it results in an incomplete dictionary being appended to the list.

  2. Placeholder Logic: In the reset_prompt method, there is a loop that attempts to replace variable labels with their values from different contexts (context, global, etc.). Since these values are obtained using context retrieval logic, there might be additional complexity added unnecessarily if the context itself is complex or changes frequently.

  3. Ordering of Fields: Sort operations on field_list and global_field_list place nodes alphabetically by stepName, which may lead to inconsistent ordering across runs unless further filtering is applied based on specific needs (e.g., importance levels).

  4. Code Duplication: There appears to be duplication between collecting fields and modifying the prompt at multiple points in the methods.

Optimizations and Suggestions:

  1. Sanitize Field Values: Before adding fields to the lists, ensure they have valid names and values. This can prevent partial dictionaries causing issues later on.

    def sanitize_field(field):
        return {**field, 'node_id': None} if ('node_name' not in field) or not field['node_name'] else field
    
    def init_fields(self):
        self.field_list = []
        self.global_field_list = []
        
        for node in self.flow.nodes:
            properties = node.properties
            node_name = properties.get('stepName')
            node_id = node.id
            node_config = properties.get('config')
            
            if node_config is not None:
                fields = node_config.get('fields', [])
                global_fields = node_config.get('globalFields', [])
    
                # Sanitized before appending
                sanitized_fields = [sanitize_field(field) for field in fields]
                sanitized_global_fields = [sanitize_field(global_field) for global_field in global_fields]
    
                self.field_list.extend(sanitized_fields)
                self.global_field_list.extend(sanitized_global_fields)
        
        self.field_list.sort(key=lambda f: len(f.get('node_name'), reverse=True))
        self.global_field_list.sort(key=lambda f: len(f.get('node_name'), reverse=True))

2. **Combine Placeholder Replacement Logic**: Instead of replacing label and new label separately, consider combining them into one line in the replacement logic. This reduces duplicate logic.

    ```python  
    def reset_prompt(self, prompt: str):
        placeholder = "{}"
        for field in self.field_list + self.global_field_list:
            globeLabel = f"{field.get('node_name')}.{field.get('value')}"
            globeValue = f"context.get('{field.get('node_id')}',{placeholder}).ge'{field.get('value', '')}','')"
            prompt = prompt.replace(globeLabel, globeValue)

        return prompt

These optimizations should help improve the robustness and efficiency of the code while maintaining consistency.

Expand Down