diff --git a/package.json b/package.json index 9eafe53..aef40d0 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "@litegraph-ts/tsconfig": "workspace:*", "@sveltejs/vite-plugin-svelte": "^2.1.1", "@tsconfig/svelte": "^4.0.1", + "@zerodevx/svelte-json-view": "^1.0.5", "events": "^3.3.0", "framework7": "^8.0.3", "framework7-svelte": "^8.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cc388df..d1bd089 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -73,6 +73,9 @@ importers: '@tsconfig/svelte': specifier: ^4.0.1 version: 4.0.1 + '@zerodevx/svelte-json-view': + specifier: ^1.0.5 + version: 1.0.5(svelte@3.58.0) events: specifier: ^3.3.0 version: 3.3.0 @@ -3375,6 +3378,14 @@ packages: pretty-format: 27.5.1 dev: false + /@zerodevx/svelte-json-view@1.0.5(svelte@3.58.0): + resolution: {integrity: sha512-oQDI9v0dJEte6PYVDVjLOjU58AOoWLYRXjghKggFpZXrglWJJqoMeDe14Jrd0cs6NPcPogT/aR/LtkuW2Z1GkQ==} + peerDependencies: + svelte: ^3.55.1 + dependencies: + svelte: 3.58.0 + dev: false + /@zerodevx/svelte-toast@0.9.3(svelte@3.58.0): resolution: {integrity: sha512-VPKWR4A9y01fyXRscu9HiTj7tV2hFrpRKZvGwMmaPXfHIXR1D9+NNsz0HXcQ7qZ0C5UaHS3n9uNtPtIcAXT7RQ==} peerDependencies: diff --git a/src/lib/ComfyBoxStdPrompt.ts b/src/lib/ComfyBoxStdPrompt.ts index a5ff3d8..ac44ed7 100644 --- a/src/lib/ComfyBoxStdPrompt.ts +++ b/src/lib/ComfyBoxStdPrompt.ts @@ -38,7 +38,7 @@ const GroupKSampler = z.object({ steps: z.number(), sampler_name: z.string(), scheduler: z.string(), - denoise: z.number().default(1.0) + denoise: z.number().default(1.0), type: z.enum(["empty", "image", "upscale"]).optional() }) export type ComfyBoxStdGroupKSampler = z.infer @@ -62,6 +62,12 @@ const GroupSDUpscale = z.object({ }) export type ComfyBoxStdGroupSDUpscale = z.infer +const GroupSelfAttentionGuidance = z.object({ + guidance_scale: z.number(), + mask_threshold: z.number(), +}) +export type ComfyBoxStdGroupSelfAttentionGuidance = z.infer + const GroupHypernetwork = z.object({ model_name: z.string(), model_hashes: ModelHashes.optional(), @@ -102,7 +108,7 @@ const GroupDynamicThresholding = z.object({ mimic_scale: z.number(), threshold_percentile: z.number(), mimic_mode: z.string(), - mimic_scale_min: z.number(), + mimic_scale_minimum: z.number(), cfg_mode: z.string(), cfg_scale_minimum: z.number() }) @@ -120,6 +126,23 @@ const GroupAestheticEmbedding = z.object({ }) export type ComfyBoxStdGroupAestheticEmbedding = z.infer +const GroupDDetailer = z.object({ + positive_prompt: z.string(), + negative_prompt: z.string(), + bitwise: z.string(), + model: z.string().optional(), + model_hashes: ModelHashes.optional(), + conf: z.number(), + mask_blur: z.number(), + denoise: z.number(), + dilation: z.number(), + offset_x: z.number(), + offset_y: z.number(), + inpaint_full: z.number(), + inpaint_padding: z.number(), +}) +export type ComfyBoxStdGroupDDetailer = z.infer + const group = (s: ZodTypeAny) => z.optional(z.array(s).nonempty()); const Parameters = z.object({ @@ -133,7 +156,9 @@ const Parameters = z.object({ hypernetwork: group(GroupHypernetwork), lora: group(GroupLoRA), control_net: group(GroupControlNet), - dynamic_thresholding: group(GroupDynamicThresholding) + dynamic_thresholding: group(GroupDynamicThresholding), + self_attention_guidance: group(GroupSelfAttentionGuidance), + ddetailer: group(GroupDDetailer) }).partial() export type ComfyBoxStdParameters = z.infer @@ -141,14 +166,19 @@ const ComfyBoxExtraData = z.object({ workflows: z.array(z.string()) }) +const A1111ExtraData = z.object({ + params: z.any() +}) + const ExtraData = z.object({ - comfybox: ComfyBoxExtraData.optional() + comfybox: ComfyBoxExtraData.optional(), + a1111: A1111ExtraData.optional() }) const Metadata = z.object({ - version: z.number(), created_with: z.string(), author: z.string().optional(), + app_version: z.string().optional(), commit_hash: z.string().optional(), extra_data: ExtraData }) @@ -159,6 +189,7 @@ const Prompt = z.object({ }) const ComfyBoxStdPrompt = z.object({ + version: z.number(), prompt: Prompt, }) diff --git a/src/lib/components/A1111PromptDisplay.svelte b/src/lib/components/A1111PromptDisplay.svelte new file mode 100644 index 0000000..134ff5b --- /dev/null +++ b/src/lib/components/A1111PromptDisplay.svelte @@ -0,0 +1,114 @@ + + +{#if prompt != null} +
+
+ + + +
+ {#if a1111} + {#if Object.keys(a1111.extraParams).length > 0} + + Unused Parameters +
+ +
+
+ {/if} + {/if} + + Converted Prompt +
+ +
+
+
+
+ + + +
+{/if} + + diff --git a/src/lib/components/ComfyApp.svelte b/src/lib/components/ComfyApp.svelte index 7ded4ef..f99acbb 100644 --- a/src/lib/components/ComfyApp.svelte +++ b/src/lib/components/ComfyApp.svelte @@ -5,13 +5,12 @@ import { Button } from "@gradio/button"; import { BlockTitle } from "@gradio/atoms"; import ComfyUIPane from "./ComfyUIPane.svelte"; - import ComfyApp, { type SerializedAppState } from "./ComfyApp"; + import ComfyApp, { type A1111PromptAndInfo, type SerializedAppState } from "./ComfyApp"; import { Checkbox, TextBox } from "@gradio/form" import uiState from "$lib/stores/uiState"; import layoutState from "$lib/stores/layoutState"; import selectionState from "$lib/stores/selectionState"; import { ImageViewer } from "$lib/ImageViewer"; - import type { ComfyAPIStatus } from "$lib/api"; import { SvelteToast, toast } from '@zerodevx/svelte-toast' import { LGraph } from "@litegraph-ts/core"; @@ -20,14 +19,18 @@ import ComfyProperties from "./ComfyProperties.svelte"; import queueState from "$lib/stores/queueState"; import ComfyUnlockUIButton from "./ComfyUnlockUIButton.svelte"; - import ComfyGraphView from "./ComfyGraphView.svelte"; - import { download, jsonToJsObject } from "$lib/utils"; - import notify from "$lib/notify"; + import ComfyGraphView from "./ComfyGraphView.svelte"; + import { download, jsonToJsObject } from "$lib/utils"; + import notify from "$lib/notify"; + import Modal from "./Modal.svelte"; + import ComfyBoxStdPrompt from "$lib/ComfyBoxStdPrompt"; + import A1111PromptDisplay from "./A1111PromptDisplay.svelte"; + import type { A1111ParsedInfotext } from "$lib/parseA1111"; export let app: ComfyApp = undefined; - let queue: ComfyQueue = undefined; + let alreadySetup: Writable = writable(false); + let a1111Prompt: Writable = writable(null); let mainElem: HTMLDivElement; - let uiPane: ComfyUIPane = undefined; let props: ComfyProperties = undefined; let containerElem: HTMLDivElement; let resizeTimeout: NodeJS.Timeout | null; @@ -44,6 +47,11 @@ } } + $: if(app) { + alreadySetup = app.alreadySetup; + a1111Prompt = app.a1111Prompt; + } + function refreshView(event?: Event) { clearTimeout(resizeTimeout); resizeTimeout = setTimeout(app.resizeCanvas.bind(app), 250); @@ -188,6 +196,10 @@ else { document.getElementById("app-root").classList.remove("dark") } + + let showModal: boolean = false; + + $: showModal = $a1111Prompt != null @@ -196,8 +208,19 @@ {/if} + ($a1111Prompt = null)}> +
+

A1111 Prompt Details

+
+ +
+ +
+
+
-
@@ -208,7 +231,7 @@ - + @@ -217,7 +240,7 @@ @@ -225,35 +248,35 @@
{#if $layoutState.attrs.queuePromptButtonName != ""} - {/if} - - - - - - - - -