mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-27 17:52:16 +00:00
## Problem Output assets in the assets panel show content hashes (e.g., `a1b2c3d4.png`) instead of display names (e.g., `ComfyUI_00001_.png`). ## Root Cause Cloud inference replaces `filename` with the content hash in the output transform pipeline. The hashed filename gets stored in the jobs table's `preview_output` JSONB. The frontend uses this hash as the display name. ## Solution - Add `display_name` field to `AssetItem` schema and `ResultItemImpl` - Backend (cloud PR) joins job→assets table to resolve the original name and injects `display_name` into job responses - Frontend prefers `display_name` over `name` **only for display text and download filenames** - `asset.name` remains unchanged (the hash) for URLs, drag-to-canvas, export filters, and output key dedup ## Backwards Compatible - OSS: `display_name` is undefined, falls back to `asset.name` (which is already the real filename in OSS) - Cloud pre-deploy: `display_name` absent from API, falls back gracefully - Old jobs with no assets: `display_name` not injected, no change ## Cloud PR https://github.com/Comfy-Org/cloud/pull/2747 https://github.com/user-attachments/assets/8a4c9cac-4ade-4ea2-9a70-9af240a56602
77 lines
2.3 KiB
TypeScript
77 lines
2.3 KiB
TypeScript
import type { AssetItem } from '@/platform/assets/schemas/assetSchema'
|
|
import type { OutputAssetMetadata } from '@/platform/assets/schemas/assetMetadataSchema'
|
|
import type { AssetContext } from '@/platform/assets/schemas/mediaAssetSchema'
|
|
import { appendCloudResParam } from '@/platform/distribution/cloudPreviewUtil'
|
|
import { api } from '@/scripts/api'
|
|
import type { ResultItemImpl, TaskItemImpl } from '@/stores/queueStore'
|
|
|
|
/**
|
|
* Extract asset type from tags array
|
|
* @param tags The tags array from AssetItem
|
|
* @returns The asset type ('input' or 'output')
|
|
*/
|
|
export function getAssetType(tags?: string[]): AssetContext['type'] {
|
|
const tag = tags?.[0]
|
|
if (tag === 'output') return 'output'
|
|
return 'input'
|
|
}
|
|
|
|
/**
|
|
* Maps a TaskItemImpl output to an AssetItem format
|
|
* @param taskItem The task item containing execution data
|
|
* @param output The output from the task
|
|
* @param useDisplayName Whether to truncate the filename for display
|
|
* @returns AssetItem formatted object
|
|
*/
|
|
export function mapTaskOutputToAssetItem(
|
|
taskItem: TaskItemImpl,
|
|
output: ResultItemImpl
|
|
): AssetItem {
|
|
const metadata: OutputAssetMetadata = {
|
|
jobId: taskItem.jobId,
|
|
nodeId: output.nodeId,
|
|
subfolder: output.subfolder,
|
|
executionTimeInSeconds: taskItem.executionTimeInSeconds,
|
|
format: output.format,
|
|
create_time: taskItem.createTime
|
|
}
|
|
|
|
return {
|
|
id: taskItem.jobId,
|
|
name: output.filename,
|
|
display_name: output.display_name,
|
|
size: 0,
|
|
created_at: taskItem.executionStartTimestamp
|
|
? new Date(taskItem.executionStartTimestamp).toISOString()
|
|
: new Date().toISOString(),
|
|
tags: ['output'],
|
|
preview_url: output.previewUrl,
|
|
user_metadata: metadata
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Maps input directory file to AssetItem format
|
|
* @param filename The filename
|
|
* @param index File index for unique ID
|
|
* @param directory The directory type
|
|
* @returns AssetItem formatted object
|
|
*/
|
|
export function mapInputFileToAssetItem(
|
|
filename: string,
|
|
index: number,
|
|
directory: 'input' | 'output' = 'input'
|
|
): AssetItem {
|
|
const params = new URLSearchParams({ filename, type: directory })
|
|
appendCloudResParam(params, filename)
|
|
|
|
return {
|
|
id: `${directory}-${index}-${filename}`,
|
|
name: filename,
|
|
size: 0,
|
|
created_at: new Date().toISOString(),
|
|
tags: [directory],
|
|
preview_url: api.apiURL(`/view?${params}`)
|
|
}
|
|
}
|