Explorar o código

Merge branch 'auto-and-unreported'

fszontagh hai 1 mes
pai
achega
779539a732

+ 19 - 4
nodes/sdcpp/sdcpp-model-load.js

@@ -33,7 +33,7 @@ const configSchema = {
                                      'streamLayers', 'maxVram', 'nThreads', 'weightType'] },
         { title: 'Advanced', fields: ['vaeFormat', 'prediction', 'rngType', 'samplerRngType',
                                       'loraApplyMode', 'vaeConvDirect', 'diffusionConvDirect',
-                                      'taePreviewOnly', 'backend', 'paramsBackend', 'rpcServers',
+                                      'taePreviewOnly', 'forceSdxlVaeConvScale', 'backend', 'paramsBackend', 'rpcServers',
                                       'modelArgs', 'tensorTypeRules', 'options', 'timeout'] }
     ],
     // Pressing this asks the server what it has loaded and writes it into the
@@ -68,6 +68,12 @@ const configSchema = {
             'loadOptions.vae_conv_direct': 'vaeConvDirect',
             'loadOptions.diffusion_conv_direct': 'diffusionConvDirect',
             'loadOptions.tae_preview_only': 'taePreviewOnly',
+            'loadOptions.force_sdxl_vae_conv_scale': 'forceSdxlVaeConvScale',
+            'loadOptions.rng_type': 'rngType',
+            'loadOptions.lora_apply_mode': 'loraApplyMode',
+            'loadOptions.backend': 'backend',
+            'loadOptions.rpc_servers': 'rpcServers',
+            'loadOptions.model_args': 'modelArgs',
             'loadOptions.backend': 'backend',
             'loadOptions.params_backend': 'paramsBackend',
             'loadOptions.rpc_servers': 'rpcServers',
@@ -205,32 +211,40 @@ const configSchema = {
         weightType: {
             type: 'string', title: 'Weight Type',
             enum: ['', 'f32', 'f16', 'bf16', 'q8_0', 'q5_0', 'q5_1', 'q4_0', 'q4_1', 'q4_k', 'q5_k', 'q6_k', 'q8_k', 'q3_k', 'q2_k', 'mxfp4', 'nvfp4', 'q1_0'],
-            default: '', description: 'Force a quantisation. Empty takes it from the file'
+            enumLabels: ['auto - use the weights in the file', 'f32', 'f16', 'bf16', 'q8_0', 'q5_0', 'q5_1', 'q4_0', 'q4_1', 'q4_k', 'q5_k', 'q6_k', 'q8_k', 'q3_k', 'q2_k', 'mxfp4', 'nvfp4', 'q1_0'],
+            default: '', description: 'Force a quantisation. Left on auto, sd.cpp uses whatever the model file holds'
         },
         vaeFormat: {
             type: 'string', title: 'VAE Format',
             enum: ['', 'auto', 'flux', 'sd3', 'flux2', 'wan'],
+            enumLabels: ['not set - leave it to the server', 'auto - detect from the file', 'flux', 'sd3', 'flux2', 'wan'],
             default: '', description: 'Override VAE format detection'
         },
         prediction: {
             type: 'string', title: 'Prediction Type',
             enum: ['', 'eps', 'v', 'edm_v', 'sd3_flow', 'flux_flow', 'flux2_flow', 'sefi_flow', 'minit2i_flow'],
-            default: '', description: 'Override the prediction type. Empty is detected'
+            enumLabels: ['auto - detect from the model', 'eps', 'v', 'edm_v', 'sd3_flow', 'flux_flow', 'flux2_flow', 'sefi_flow', 'minit2i_flow'],
+            default: '', description: 'Override the prediction type. Left on auto it is detected from the model'
         },
         rngType: {
             type: 'string', title: 'RNG', enum: ['', 'cuda', 'std_default', 'cpu'],
+            enumLabels: ['server default', 'cuda', 'std_default', 'cpu'],
             default: '', description: 'Affects whether a seed reproduces across backends'
         },
         samplerRngType: {
             type: 'string', title: 'Sampler RNG', enum: ['', 'cuda', 'std_default', 'cpu'],
-            default: '', description: 'Override the RNG for sampling only'
+            enumLabels: ['same as RNG above', 'cuda', 'std_default', 'cpu'],
+            default: '',
+            description: 'Override the RNG for sampling only. The server does not report this one, so Fill in leaves it alone'
         },
         loraApplyMode: {
             type: 'string', title: 'LoRA Apply Mode', enum: ['', 'auto', 'immediately', 'at_runtime'],
+            enumLabels: ['server default', 'auto', 'immediately', 'at_runtime'],
             default: '', description: 'When a LoRA named in a prompt is applied'
         },
         vaeConvDirect: { type: 'boolean', title: 'Direct VAE Convolution', description: 'Use the ggml_conv2d_direct path for the VAE' },
         diffusionConvDirect: { type: 'boolean', title: 'Direct Diffusion Convolution', description: 'Use the ggml_conv2d_direct path for the diffusion model' },
+        forceSdxlVaeConvScale: { type: 'boolean', title: 'Force SDXL VAE Conv Scale', description: 'SDXL-specific VAE convolution scaling' },
         taePreviewOnly: { type: 'boolean', title: 'TAESD For Preview Only', description: 'Load TAESD purely to render progress previews, skipping the full VAE' },
         backend: { type: 'string', title: 'Backend', description: 'Per-component placement, such as te=cpu,vae=cpu,controlnet=cpu' },
         paramsBackend: { type: 'string', title: 'Parameter Backend', description: 'Global parameter placement, such as *=cpu to hold weights in system RAM' },
@@ -388,6 +402,7 @@ const LOAD_OPTIONS = [
     { setting: 'vaeConvDirect', server: 'vae_conv_direct' },
     { setting: 'diffusionConvDirect', server: 'diffusion_conv_direct' },
     { setting: 'taePreviewOnly', server: 'tae_preview_only' },
+    { setting: 'forceSdxlVaeConvScale', server: 'force_sdxl_vae_conv_scale' },
     { setting: 'backend', server: 'backend' },
     { setting: 'paramsBackend', server: 'params_backend' },
     { setting: 'rpcServers', server: 'rpc_servers' },

+ 26 - 5
webui/src/components/workflow/NodeConfigModal.tsx

@@ -136,11 +136,18 @@ export function NodeConfigModal({
 
       const next: Record<string, any> = { ...editingConfig }
       const filled: string[] = []
+      const notReported: string[] = []
       for (const [from, to] of Object.entries((prefill.map || {}) as Record<string, string>)) {
         const value = readPath(output, from)
-        // A component the server does not have comes back empty or absent.
-        // Writing that would blank a value the person had already set.
-        if (value === undefined || value === null || value === '') continue
+        // Absent and empty are different answers. Absent means the service does
+        // not report this at all, so there is nothing to say and whatever is
+        // already in the box stays. Empty is an answer - it means the service is
+        // using its own default - and writing it is what makes the form agree
+        // with the service instead of only half agreeing.
+        if (value === undefined || value === null) {
+          notReported.push(to)
+          continue
+        }
         next[to] = value
         filled.push(to)
       }
@@ -155,7 +162,17 @@ export function NodeConfigModal({
       }
 
       onConfigChange(next)
-      setPrefilling({ busy: false, error: false, message: `Filled in ${filled.join(', ')}.` })
+      setPrefilling({
+        busy: false,
+        error: false,
+        message:
+          `Filled in ${filled.length} setting${filled.length === 1 ? '' : 's'}.` +
+          (notReported.length > 0
+            ? ` The server does not report ${notReported.join(', ')}, so ${
+                notReported.length === 1 ? 'it was' : 'they were'
+              } left as ${notReported.length === 1 ? 'it is' : 'they are'}.`
+            : ''),
+      })
     } catch (error: any) {
       const detail = error?.response?.data?.error || error?.message || 'Could not reach the server'
       setPrefilling({ busy: false, error: true, message: detail })
@@ -672,7 +689,11 @@ export function NodeConfigModal({
                         }
                         className="w-full px-3 py-2 border border-gray-200 dark:border-slate-600 rounded-lg bg-white dark:bg-slate-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-primary-500 focus:border-primary-500"
                       >
-                        <option value="">Select...</option>
+                        {/* Only when the schema has not given "" a meaning of
+                            its own. Several settings use it for "auto" or
+                            "server default", and a placeholder above that would
+                            take its place and hide the label explaining it. */}
+                        {!prop.enum.includes('') && <option value="">Select...</option>}
                         {prop.enum.map((opt: string, idx: number) => (
                           <option key={opt} value={opt}>
                             {prop.enumLabels?.[idx] || opt}