mirror of
https://github.com/langgenius/dify.git
synced 2026-10-16 15:35:32 +08:00
fix(web): convert agent log thought files only once
The log list converted message files to FileEntity before attaching them to agent thoughts, and AgentContent converted them again for FileList. The second conversion dropped supportFileType, so tool image outputs rendered as blank file cards without a thumbnail or preview. Attach the raw message files, as the chat history hooks do, so the renderer converts them once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
7553fb3daf
commit
6a889f484e
@@ -1,5 +1,6 @@
|
||||
import type { MessageDetailResponse } from '@dify/contracts/api/console/apps/types.gen'
|
||||
import type { IChatItem } from '@/app/components/base/chat/chat/type'
|
||||
import { getProcessedFilesFromResponse } from '@/app/components/base/file-uploader/utils'
|
||||
import {
|
||||
applyAnnotationAdded,
|
||||
applyAnnotationEdited,
|
||||
@@ -291,6 +292,55 @@ describe('log list utils', () => {
|
||||
).toEqual(['https://example.com/file-1'])
|
||||
})
|
||||
|
||||
it('keeps agent thought files raw so the agent renderer converts them once', () => {
|
||||
const [, answer] = getFormattedChatList(
|
||||
[
|
||||
createMessage({
|
||||
id: 'message-1',
|
||||
agent_thoughts: [
|
||||
{
|
||||
id: 'thought-1',
|
||||
message_id: 'message-1',
|
||||
position: 1,
|
||||
files: ['file-1'],
|
||||
tool: 'image_generator',
|
||||
tool_labels: {},
|
||||
},
|
||||
],
|
||||
message_files: [
|
||||
{
|
||||
belongs_to: 'assistant',
|
||||
id: 'file-1',
|
||||
filename: 'image.png',
|
||||
transfer_method: 'tool_file',
|
||||
type: 'image',
|
||||
url: 'https://example.com/image.png',
|
||||
},
|
||||
],
|
||||
}),
|
||||
],
|
||||
'conversation-1',
|
||||
'UTC',
|
||||
'YYYY-MM-DD',
|
||||
)
|
||||
|
||||
const thoughtFiles = answer!.agent_thoughts![0]!.message_files!
|
||||
expect(thoughtFiles).toEqual([
|
||||
expect.objectContaining({
|
||||
id: 'file-1',
|
||||
type: 'image',
|
||||
url: 'https://example.com/image.png',
|
||||
}),
|
||||
])
|
||||
// Mirrors AgentContent, which converts thought files for FileList.
|
||||
const [rendered] = getProcessedFilesFromResponse(
|
||||
thoughtFiles.map((file) => ({ ...file, related_id: file.id }) as never),
|
||||
)
|
||||
expect(rendered).toEqual(
|
||||
expect.objectContaining({ supportFileType: 'image', url: 'https://example.com/image.png' }),
|
||||
)
|
||||
})
|
||||
|
||||
it('should handle default inputs', () => {
|
||||
expect(
|
||||
getConversationRowValues({
|
||||
|
||||
@@ -7,6 +7,7 @@ import type {
|
||||
ThoughtItem,
|
||||
} from '@/app/components/base/chat/chat/type'
|
||||
import type { Annotation } from '@/models/log'
|
||||
import type { VisionFile } from '@/types/app'
|
||||
import type { FileResponse } from '@/types/workflow'
|
||||
import dayjs from 'dayjs'
|
||||
import timezone from 'dayjs/plugin/timezone'
|
||||
@@ -53,6 +54,19 @@ type LogMessage = MessageDetailResponse
|
||||
const isTransferMethod = (value: string): value is TransferMethod =>
|
||||
(Object.values(TransferMethod) as string[]).includes(value)
|
||||
|
||||
// Agent thoughts keep raw message files; the agent content renderer converts them once.
|
||||
const toThoughtFiles = (item: LogMessage): VisionFile[] =>
|
||||
item.message_files.map((file) => ({
|
||||
id: file.id,
|
||||
type: file.type,
|
||||
transfer_method: isTransferMethod(file.transfer_method)
|
||||
? file.transfer_method
|
||||
: TransferMethod.local_file,
|
||||
url: file.url ?? '',
|
||||
upload_file_id: file.upload_file_id ?? '',
|
||||
belongs_to: file.belongs_to ?? undefined,
|
||||
}))
|
||||
|
||||
const toFileResponse = (file: LogMessage['message_files'][number]): FileResponse => ({
|
||||
related_id: file.id ?? file.upload_file_id,
|
||||
extension: '',
|
||||
@@ -146,7 +160,6 @@ export const getFormattedChatList = (
|
||||
const newChatList: IChatItem[] = []
|
||||
|
||||
messages.forEach((item) => {
|
||||
const files = getProcessedFilesFromResponse(item.message_files.map(toFileResponse))
|
||||
const questionFiles = getProcessedFilesFromResponse(
|
||||
item.message_files.filter((file) => file.belongs_to === 'user').map(toFileResponse),
|
||||
)
|
||||
@@ -165,7 +178,7 @@ export const getFormattedChatList = (
|
||||
newChatList.push({
|
||||
id: item.id,
|
||||
content: item.answer,
|
||||
agent_thoughts: addFileInfos(sortAgentSorts(toThoughtItems(item)), files),
|
||||
agent_thoughts: addFileInfos(sortAgentSorts(toThoughtItems(item)), toThoughtFiles(item)),
|
||||
feedback: toFeedback(item.feedbacks.find((feedback) => feedback.from_source === 'user')),
|
||||
adminFeedback: toFeedback(
|
||||
item.feedbacks.find((feedback) => feedback.from_source === 'admin'),
|
||||
|
||||
Reference in New Issue
Block a user