Stop Comfy input folder filling with duplicate still uploads.

Name uploads by content hash so the same still overwrites itself, enable stale input sweeps on purge, and remove the pile already on the desktop Shared input folder.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Towsty
2026-09-04 08:20:39 -05:00
co-authored by Cursor
parent 20f373b172
commit c043890ac0
2 changed files with 20 additions and 8 deletions
+9 -4
View File
@@ -1,3 +1,4 @@
import { createHash } from 'node:crypto'
import { AsyncLocalStorage } from 'node:async_hooks'
import { getComfyHost, viaAgentFrontDoor } from '~/server/utils/comfy'
import { comfyJobPrefix } from '~/utils/outputNames'
@@ -94,18 +95,21 @@ export function imageComfyWsUrl(clientId: string) {
return `${getImageComfyHost().replace(/^http/, 'ws')}/ws?clientId=${encodeURIComponent(clientId)}`
}
function imageInputFilename(original: string, jobId?: string) {
function imageInputFilename(original: string, data?: Buffer, jobId?: string) {
const raw = String(original || 'still.png')
const dot = raw.lastIndexOf('.')
const ext = (dot >= 0 ? raw.slice(dot) : '.png').replace(/[^.a-zA-Z0-9]/g, '') || '.png'
const base = (dot >= 0 ? raw.slice(0, dot) : raw).replace(/[^a-zA-Z0-9._-]+/g, '_').slice(0, 48) || 'still'
return `${comfyJobPrefix(jobId)}_${base}${ext}`
const hash = data?.length
? createHash('sha1').update(data).digest('hex').slice(0, 12)
: comfyJobPrefix(jobId)
return `aigen_${hash}_${base}${ext}`
}
export async function uploadImageEdit(file: { filename: string; data: Buffer; type?: string }, jobId?: string) {
const body = new FormData()
const blob = new Blob([new Uint8Array(file.data)], { type: file.type || 'application/octet-stream' })
const filename = imageInputFilename(file.filename, jobId)
const filename = imageInputFilename(file.filename, file.data, jobId)
body.append('image', blob, filename)
body.append('overwrite', 'true')
body.append('type', 'input')
@@ -393,7 +397,8 @@ async function purgeImageOnDesktop(opts: {
imageNames,
imageSubfolder: opts.inputSubfolder || '',
output: opts.output || null,
sweep: false
sweep: true,
sweepMaxAgeMs: 2 * 60 * 1000
}),
signal: AbortSignal.timeout(8000)
})