feat: AI node supports workflow calling tools#4955
Conversation
|
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. DetailsInstructions 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. |
| tool_init_params, source_id, source_type, chat_id, tools) | ||
| return NodeResult( | ||
| {'result': r, 'chat_model': chat_model, 'message_list': message_list, | ||
| 'history_message': [{'content': message.content, 'role': message.type} for message in |
There was a problem hiding this comment.
- Import statements: The
uuidmodule is imported twice, which is unnecessary. - Class/function definitions: Ensure all class names and function names are consistent with CamelCase convention (e.g.,
_write_context, not_Write_context). It's generally a good practice to use underscores at the beginning of private methods/functions. - JSON usage consistency: Use standard Python library imports (
json) instead of importing them again under different aliases (json as ...). - Docstrings/Comments: Add more docstrings and comments to explain complex functions and logic, especially those related to handling tools and workflows.
- SQL query optimizations: Consider using ORM queries efficiently, such as eager loading relationships or reducing the number of database roundtrips where applicable.
- Code reuse: Refactor reusable code into separate modules or functions whenever possible to improve maintainability and reduce redundancy.
Here's an optimized version of the script incorporating some suggested improvements:
import json
import re
import time
from functools import reduce
from typing import List, Dict
from langchain_core.tools import StructuredTool
from application.flow.common import Workflow, WorkflowMode
from application.flow.i_step_node import NodeResult, INode, ToolWorkflowPostHandler, ToolWorkflowCallPostHandler
from application.flow.step_node.ai_chat_step_node.i_chat_node import IChatNode
from application.flow.tools import Reasoning, mcp_response_generator
from common.exception.app_exception import AppApiException
from common.utils.rsa_util import rsa_long_decrypt
from common.utils.shared_resource_auth import filter_authorized_ids
from common.utils.tool_code import ToolExecutor
from django.db.models import QuerySet, OuterRef, Subquery
class YourClass:
def _handle_mcp_request(self, mcp_source, mcp_servers, mcp_tool_id, mcp_tool_ids, tool_ids,
application_ids, skill_tool_ids, mcp_output_enable, chat_model, message_list, history_message,
question, chat_id):
# Remove redundant UUID import
import uuid
mcp_servers_config = {}
for item in [mcp_source] + [mcp_tool for mcp_tool in mcp_tool_ids]:
if isinstance(item, str): # Check if item is a string before attempting to decode JSON
try:
decoded_json = json.loads(rsa_long_decrypt(item))
mcp_servers_config.update(decoded_json)
except Exception as e:
print(f"Failed to parse MCP configuration: {e}")
# Continue existing functionality here...
# Example Usage
instance_of_class = YourClass()
result = instance_of_class._handle_mcp_request(...)
| source_id, source_type, temp_dir, chat_id, extra_tools) | ||
| async for chunk in async_gen: | ||
| result_queue.put(('data', chunk)) | ||
| except Exception as e: |
There was a problem hiding this comment.
Here's some advice and comments on your provided code:
- Line 59: The function
_upsert_fragmenthas inconsistent use of brackets()and[ ]. Consider being consistent. - Line 67: There seems to be a logical error in this line related to checking conditions within the loop.
- Line 70: The
result_queue.putcall could benefit from using.join()before processing results asynchronously to ensure proper synchronization. - Overall Structure:
_yield_mcp_response: Async generator should handle exceptions better with try-except blocks.mcp_response_generator: Synchronous wrapper might not work well with global event loops; consider asynchronous alternatives.
Specific Recommendations:
# Ensure consistent bracket usage throughout the code for readability.
def _upsert_fragment(key, raw_id, func_name, part_args):
if part_args == '':
part_args = {}
... rest of methods...
...
async def save_tool_record(tool_id, tool_info, tool_result, source_id, source_type):
...
... add more context-based improvements where appropriate...Feel free to adapt these comments based on further review and understanding of your specific requirements!
|
|
||
| class ToolWorkflowPostHandler(WorkFlowPostHandler): | ||
| def __init__(self, chat_info, tool_id): | ||
| super().__init__(chat_info) |
There was a problem hiding this comment.
The provided code seems to have several issues:
-
Class Duplication: The third class definition of
ToolWorkflowPostHandleris identical to the first one, which can lead to confusion and errors if not resolved. -
Variable Initialization Issue: In the second class definition, there are no values assigned to
self.chat_info, making it impossible to use or modify this variable within the handlers. -
Method Overriding and Reinitialization: Even though this might be an oversight, reassigning
self.chat_infoandself.tool_idafter calling the base class method can cause unexpected behavior. -
Documentation Lack: Comments are sparse, making it difficult to understand the purpose and functionality of each part of the code.
To improve the code:
- Remove the duplicate class definition of
ToolWorkflowPostHandler. - Assign initial values to
self.chat_infoandself.tool_idbefore the call tosuper().__init__(). - Ensure that all necessary methods override their Base class equivalents properly with valid implementations.
Here's a corrected version (assuming you want to keep only one implementation):
class ToolWorkflowPostHandler(WorkFlowPostHandler):
def __init__(self, chat_info, tool_id):
super().__init__()
self.chat_info = chat_info
self.tool_id = tool_id
# Assuming handler needs specific logic related to 'tool_id'
def handler(self, workflow):
print(f"Handling Workflow for Tool ID {self.tool_id}")
# Add actual business logic here based on workflow stateThis revision ensures that ChatInfo and tool_id are initialized correctly during the initialization process and provides a clear structure for handling work items associated with tools through workflows.
|
[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. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
feat: AI node supports workflow calling tools