Open D-siheng opened 1 month ago
The workflow gets stuck in the "running" state and does not produce any results when summarizing a docx document because the _run
method in the ToolNode
class does not handle the case where the tool invocation does not return any messages or the messages are not properly converted. Specifically, the _convert_tool_messages
method might not be handling the messages correctly, leading to an incomplete or empty result.
Here is the relevant code snippet that shows the potential issue:
def _run(self, variable_pool: VariablePool) -> NodeRunResult:
# ... (other code)
try:
messages = ToolEngine.workflow_invoke(
tool=tool_runtime,
tool_parameters=parameters,
user_id=self.user_id,
workflow_id=self.workflow_id,
workflow_tool_callback=DifyWorkflowCallbackHandler()
)
except Exception as e:
return NodeRunResult(
status=WorkflowNodeExecutionStatus.FAILED,
inputs=parameters,
metadata={
NodeRunMetadataKey.TOOL_INFO: tool_info
},
error=f'Failed to invoke tool: {str(e)}',
)
# convert tool messages
plain_text, files = self._convert_tool_messages(messages)
return NodeRunResult(
status=WorkflowNodeExecutionStatus.SUCCEEDED,
outputs={
'text': plain_text,
'files': files
},
metadata={
NodeRunMetadataKey.TOOL_INFO: tool_info
},
inputs=parameters
)
The _convert_tool_messages
method is responsible for converting the tool messages into plain text and files. If this method does not handle the messages correctly, it could result in an empty or incomplete result, causing the workflow to get stuck.
To fix this issue, you should ensure that the _convert_tool_messages
method correctly handles all possible message types and scenarios. According to the Dify documentation, Dify supports various message types such as text
, link
, image
, and file BLOB
. Make sure that your _convert_tool_messages
method can handle these types appropriately. Here are some helper methods provided by Dify for creating different types of messages:
def create_image_message(self, image: str, save_as: str = '') -> ToolInvokeMessage:
# create an image message
pass
def create_link_message(self, link: str, save_as: str = '') -> ToolInvokeMessage:
# create a link message
pass
def create_text_message(self, text: str, save_as: str = '') -> ToolInvokeMessage:
# create a text message
pass
def create_blob_message(self, blob: bytes, meta: dict = None, save_as: str = '') -> ToolInvokeMessage:
# create a blob message
pass
Additionally, you may want to add logging or debugging statements to trace the flow of data and identify where the process might be failing. This will help you pinpoint the exact issue and ensure that all message types are being handled correctly.
Furthermore, ensure that you have properly authorized the tool and configured its inputs and parameters as per the Dify documentation. Configuring a tool node generally involves two steps:
For detailed guidance on creating custom tools and configuring them, please refer to the tool configuration instructions.
Additionally, the useWorkflowRun
hook in Dify's codebase provides a comprehensive mechanism for handling workflow runs, including starting, stopping, and managing the state of the workflow. This hook ensures that the workflow's state is properly managed and updated, which can help in diagnosing and resolving issues related to workflows getting stuck. Here is a relevant excerpt from the useWorkflowRun
hook:
const handleRun = useCallback(async (
params: any,
callback?: IOtherOptions,
) => {
// ... (other code)
ssePost(
url,
{
body: params,
},
{
onWorkflowStarted: (params) => {
// ... (handle workflow started)
},
onWorkflowFinished: (params) => {
// ... (handle workflow finished)
},
onError: (params) => {
// ... (handle error)
},
onNodeStarted: (params) => {
// ... (handle node started)
},
onNodeFinished: (params) => {
// ... (handle node finished)
},
onTextChunk: (params) => {
// ... (handle text chunk)
},
onTextReplace: (params) => {
// ... (handle text replace)
},
...restCallback,
},
)
}, [store, reactflow, workflowStore, doSyncWorkflowDraft])
This hook ensures that the workflow's state transitions are properly managed and provides callbacks for various stages of the workflow execution, which can be useful for debugging and ensuring that the workflow does not get stuck [1][2][3][4].
To continue the conversation, mention @dosu.
Self Checks
Dify version
0.6.7
Cloud or Self Hosted
Self Hosted (Docker)
Steps to reproduce
I wrote an built-in tool following the official guidelines and referencing the code of the Wiki search tool. The tool's function is to output document summaries using the document summary module of langchain. The tool can be displayed normally in the list of built-in tools, and after testing, it can run normally in workflow and output document summaries. I created a START-document summary-END workflow and published it. I ran the workflow in the
explore
interface, and all three nodes in the workflow displayed as completed, and the summary tool output the document summary content normally in the nodes. The end node also had normal input and output, but the workflow process was stuck in the running state and could not become the succeed state, which resulted in the summary result not being output on the screen. After testing, the situation where the workflow process could not end only occurred when a docx document was to be summarized. Besides the workflow, I also tried the chatflow, which consisted of STRAT-document summary-ANSWER three nodes. Running the chatflow could normally end and output formatted document summary content. My code is as follows:✔️ Expected Behavior
The workflow should be able to complete normally and output JSON-formatted results.
❌ Actual Behavior
As long as all three nodes have ended and their status is checked, the workflow remains in the running state and does not output the final result.