From e334cb7a7a3ecb535fcf8e002af2d32b903f7016 Mon Sep 17 00:00:00 2001 From: Towsty Date: Wed, 26 Aug 2026 22:56:37 -0500 Subject: [PATCH] Move library collections as a group and map v2 identity refs. Collapsed collection actions now move, rename, delete, and rerun every part so chains stay together. Identity mode follows the v2u3 Ref2VA picture wiring. Co-authored-by: Cursor --- .env.example | 11 +- components/ImagePickerModal.vue | 1 + nuxt.config.ts | 2 + pages/index.vue | 390 ++++++++++++++----- scripts/comfy-host-agent.mjs | 36 +- scripts/install-image-comfy-host.py | 4 +- server/api/edit.post.ts | 141 ++++--- server/api/extend.post.ts | 1 + server/api/generate.post.ts | 53 ++- server/api/health.get.ts | 52 ++- server/api/interrupt.post.ts | 2 +- server/api/library/clips/[id].delete.ts | 4 +- server/api/library/clips/[id].patch.ts | 11 +- server/api/library/index.get.ts | 1 + server/api/library/stills.post.ts | 2 +- server/assets/workflow_minimax_video_v2.json | 11 +- server/assets/workflow_qwen_edit.json | 29 +- server/plugins/library-cleanup.ts | 22 ++ server/utils/imageComfy.ts | 180 ++++++++- server/utils/imageComfyLifecycle.ts | 85 +++- server/utils/imageWorkflow.ts | 37 +- server/utils/jobs.ts | 1 + server/utils/library.ts | 241 +++++++++++- server/utils/pending.ts | 6 +- server/utils/watch.ts | 8 +- server/utils/workflow.ts | 45 +-- utils/identityPrompt.ts | 40 ++ utils/parseShots.ts | 2 +- 28 files changed, 1125 insertions(+), 293 deletions(-) create mode 100644 server/plugins/library-cleanup.ts create mode 100644 utils/identityPrompt.ts diff --git a/.env.example b/.env.example index c1f7bf1..080bea4 100644 --- a/.env.example +++ b/.env.example @@ -25,12 +25,19 @@ LIBRARY_DIR=/data/library # AUTH_USERNAME= # AUTH_PASSWORD= # COMFY_FILENAME_PREFIX=video/xAIGen -# Desktop Comfy files are deleted after a successful library save (set false to keep them) +# Desktop Comfy files are deleted after a successful library save (set false to keep them). +# Also removes Qwen Edit input/output files from the image sidecar after saveStill. # PURGE_COMFY_OUTPUTS=true -# Second Comfy box (sidecar / Qwen image edit) +# Second Comfy box (Sidecar / Qwen overflow). Beast uses COMFY_HOST first. +# Image edits run on Beast when that Comfy is idle, and roll over to Sidecar only when Beast is busy. IMAGE_COMFY_HOST=http://192.168.77.101:8188 IMAGE_COMFY_PORT=8188 +# Optional override if image Comfy on Beast is not the video instance +# IMAGE_COMFY_PRIMARY_HOST=http://192.168.77.7:8198 +# IMAGE_COMFY_FALLBACK_HOST=http://192.168.77.101:8188 +# Spawned on the sidecar PC (host agent /start and start_comfyui.bat). Listen is 0.0.0.0 so Coolify can reach :8188. +IMAGE_COMFY_LAUNCH_CMD=C:\ComfyUI-QwenEdit\python\python.exe C:\ComfyUI-QwenEdit\ComfyUI\main.py --listen 0.0.0.0 --port 8188 --disable-auto-launch --lowvram --fp8_e4m3fn-unet --disable-cuda-malloc # Optional host agent on the sidecar (scripts/comfy-host-agent.mjs) # IMAGE_COMFY_CONTROL_URL=http://192.168.77.101:8199 # IMAGE_COMFY_CONTROL_TOKEN= diff --git a/components/ImagePickerModal.vue b/components/ImagePickerModal.vue index b4e8c42..73f2ddd 100644 --- a/components/ImagePickerModal.vue +++ b/components/ImagePickerModal.vue @@ -224,6 +224,7 @@ async function unlock() { } async function ingest(file: File) { + if (/last[\s._-]*frame/i.test(file.name || '')) return const body = new FormData() body.append('image', file) body.append('folderId', current.value?.id || activeFolderId.value) diff --git a/nuxt.config.ts b/nuxt.config.ts index 6d53375..1aa0c75 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -31,6 +31,8 @@ export default defineNuxtConfig({ comfyControlToken: process.env.COMFY_CONTROL_TOKEN || '', imageComfyHost: process.env.IMAGE_COMFY_HOST || '', imageComfyPort: process.env.IMAGE_COMFY_PORT || '', + imageComfyPrimaryHost: process.env.IMAGE_COMFY_PRIMARY_HOST || '', + imageComfyFallbackHost: process.env.IMAGE_COMFY_FALLBACK_HOST || '', imageComfyLaunchCmd: process.env.IMAGE_COMFY_LAUNCH_CMD || '', imageComfyControlUrl: process.env.IMAGE_COMFY_CONTROL_URL || '', imageComfyControlToken: process.env.IMAGE_COMFY_CONTROL_TOKEN || '', diff --git a/pages/index.vue b/pages/index.vue index 940ff35..2f2f0c4 100644 --- a/pages/index.vue +++ b/pages/index.vue @@ -20,7 +20,7 @@ {{ imageComfyBadge.label }} @@ -57,7 +57,7 @@

Input

{{ studioMode === 'edit' - ? 'Drop a still and describe the edit. This relays to the sidecar Qwen Comfy box once the workflow is mapped.' + ? 'Drop a still and describe the edit. Beast handles it when free; Sidecar only if Beast is busy.' : 'Drop a still, describe the motion, then relay the job to the local desktop.' }}

@@ -88,28 +88,42 @@
- +
+ + +

- Paste a block. Text before the first marker is shot 1. Write shot 2, shot 3, and so on to queue extensions. Every shot uses the duration slider. + Paste a block. Text before the first marker is shot 1. Put shot 2, shot 3 on their own lines to queue extensions — a line like Shot Type will not start a new shot. Every shot uses the duration slider. + Identity boilerplate is prepended to the first shot only. +

+

+ Write camera, action, and audio. We prepend the <Picture 1> identity lock automatically.