dify icon indicating copy to clipboard operation
dify copied to clipboard

The format returned by the get conversation log API is not fixed when status is error

Open chenyhd opened this issue 1 year ago • 3 comments

Self Checks

  • [X] This is only for bug report, if you would like to ask a question, please head to Discussions.
  • [X] I have searched for existing issues search for existing issues, including closed ones.
  • [X] I confirm that I am using English to submit this report (我已阅读并同意 Language Policy).
  • [X] 请务必使用英文提交 Issue,否则会被关闭。谢谢!:)
  • [X] Please do not modify this template :) and fill in all the required fields.

Dify version

0.6.11

Cloud or Self Hosted

Self Hosted (Docker)

Steps to reproduce

  1. Enter bot app
  2. Go to logs&Ann. from the side bar
  3. check the conversations
  4. I found that when some steps execute failed, the fields will return empty string instead of array

API: GET https://{domain}/console/api/apps/{appId}/chat-messages?conversation_id={conversationId}&limit=10

Error response:

response.data[x] ->
{
    ....
    "message": "", // String
    "status": "error",
    "error": "[openai] Error: peer closed connection without sending complete message body (incomplete chunked read)"
}

Normal response:

response.data[x] ->
{
    ...
    "message": [ // Array
        {
            "role": "system",
            "text": "xxxxx",
            "files": []
        },
        {
            "role": "user",
            "text": "yyyyy",
            "files": []
        }
    ],

    "status": "normal",
    "error": null
},

✔️ Expected Behavior

Hi Dify team, Thank you for creating this amazing app! It's fantastic. I'm currently analyzing the logs and noticed some unusual API responses.

The message format should remain consistent regardless of whether the status is normal or an error.

By default, the message could return an empty array like message: [] instead of message:"".

❌ Actual Behavior

The message field returns in a different format when something execute failed

chenyhd avatar Jul 04 '24 04:07 chenyhd

Hello @chenyhd! I'm here to assist you with bugs, questions, and contributions. If you need any help, feel free to ask!

To ensure that the message field remains consistent and returns an empty array instead of an empty string when a step fails, you can modify the relevant code to handle this case. Specifically, you can update the function that formats the chat messages to return an empty array when the message data is empty or undefined.

Here's an example of how you can modify the getFormattedChatList function to achieve this:

const getFormattedChatList = (messages: ChatMessage[], conversationId: string, timezone: string, format: string) => {
  if (!messages || messages.length === 0) {
    return [];
  }

  const newChatList: IChatItem[] = [];
  messages.forEach((item: ChatMessage) => {
    newChatList.push({
      id: `question-${item.id}`,
      content: item.inputs.query || item.inputs.default_input || item.query, // text generation: item.inputs.query; chat: item.query
      isAnswer: false,
      message_files: item.message_files?.filter((file: any) => file.belongs_to === 'user') || [],
    });
    newChatList.push({
      id: item.id,
      content: item.answer,
      agent_thoughts: addFileInfos(item.agent_thoughts ? sortAgentSorts(item.agent_thoughts) : item.agent_thoughts, item.message_files),
      feedback: item.feedbacks.find(item => item.from_source === 'user'), // user feedback
      adminFeedback: item.feedbacks.find(item => item.from_source === 'admin'), // admin feedback
      feedbackDisabled: false,
      isAnswer: true,
      message_files: item.message_files?.filter((file: any) => file.belongs_to === 'assistant') || [],
      log: [
        ...item.message,
        ...(item.message[item.message.length - 1]?.role !== 'assistant'
          ? [
            {
              role: 'assistant',
              text: item.answer,
              files: item.message_files?.filter((file: any) => file.belongs_to === 'assistant') || [],
            },
          ]
          : []),
      ],
      workflow_run_id: item.workflow_run_id,
      conversationId,
      input: {
        inputs: item.inputs,
        query: item.query,
      },
      more: {
        time: dayjs.unix(item.created_at).tz(timezone).format(format),
        tokens: item.answer_tokens + item.message_tokens,
        latency: item.provider_response_latency.toFixed(2),
      },
      annotation: (() => {
        if (item.annotation_hit_history) {
          return {
            id: item.annotation_hit_history.annotation_id,
            authorName: item.annotation_hit_history.annotation_create_account?.name || 'N/A',
            created_at: item.annotation_hit_history.created_at,
          };
        }
      })(),
    });
  });
  return newChatList;
};

This modification ensures that if the messages array is empty or undefined, the function will return an empty array, maintaining consistency in the message format [1].

To continue talking to Dosu, mention @dosu.

dosubot[bot] avatar Jul 04 '24 04:07 dosubot[bot]

I think you could do a check here.

"status": "normal",
"error": null
if result.error === null
  do something
else
  do nothing

crazywoola avatar Jul 04 '24 05:07 crazywoola

Hi @crazywoola ,

Maybe different json libs have different deserialization behaviors, I use Java Jackson lib , it will deserialize entire json string to object, instead of check each individual fields

I will try to find another way to handle this situation

chenyhd avatar Jul 04 '24 05:07 chenyhd