diff --git a/web/executionUtils.js b/web/executionUtils.js
index 453e2f6..c53a016 100644
--- a/web/executionUtils.js
+++ b/web/executionUtils.js
@@ -135,7 +135,9 @@ export async function executeParallelDistributed(extension, promptWrapper) {
const wantsDelegate = Boolean(extension.config?.settings?.master_delegate_only);
let masterDelegateActive = false;
if (wantsDelegate) {
- if (upscaleNodes.length > 0) {
+ if (activeWorkers.length === 0) {
+ extension.log("Master delegate-only mode disabled: no active workers detected. Falling back to master execution.", "debug");
+ } else if (upscaleNodes.length > 0) {
extension.log("Master delegate-only mode is not yet supported for UltimateSDUpscaleDistributed nodes. Falling back to normal execution.", "warn");
} else if (collectorNodes.length === 0) {
extension.log("Master delegate-only mode requested but no DistributedCollector nodes found. Falling back to normal execution.", "debug");
diff --git a/web/main.js b/web/main.js
index 0e3934c..f2c89ae 100644
--- a/web/main.js
+++ b/web/main.js
@@ -90,8 +90,16 @@ class DistributedExtension {
return this.enabledWorkers.length > 0;
}
+ isMasterParticipationEnabled() {
+ return !Boolean(this.config?.settings?.master_delegate_only);
+ }
+
+ isMasterFallbackActive() {
+ return Boolean(this.config?.settings?.master_delegate_only) && this.enabledWorkers.length === 0;
+ }
+
isMasterParticipating() {
- return !(this.config?.settings?.master_delegate_only);
+ return this.isMasterParticipationEnabled() || this.isMasterFallbackActive();
}
async updateMasterParticipation(enabled) {
@@ -163,6 +171,10 @@ class DistributedExtension {
} catch (error) {
this.log("Error updating worker: " + error.message, "error");
}
+
+ if (this.panelElement) {
+ renderSidebarContent(this, this.panelElement);
+ }
}
async _updateSetting(key, value) {
diff --git a/web/ui.js b/web/ui.js
index 5444b7d..04d5a8d 100644
--- a/web/ui.js
+++ b/web/ui.js
@@ -17,7 +17,14 @@ const cardConfigs = {
const cudaDevice = extension.config?.master?.cuda_device ?? extension.masterCudaDevice;
const cudaInfo = cudaDevice !== undefined ? `CUDA ${cudaDevice} • ` : '';
const port = window.location.port || (window.location.protocol === 'https:' ? '443' : '80');
- const delegateBadge = extension.isMasterParticipating() ? '' : `
Orchestrator-only mode`;
+ const participationEnabled = extension.isMasterParticipationEnabled();
+ const fallbackActive = extension.isMasterFallbackActive();
+ let delegateBadge = '';
+ if (!participationEnabled) {
+ delegateBadge = fallbackActive
+ ? `
Fallback active • Master executing`
+ : `
Orchestrator-only mode`;
+ }
return `${data?.name || extension.config?.master?.name || "Master"}
${cudaInfo}Port ${port}${delegateBadge}`;
},
controls: {
@@ -867,20 +874,32 @@ export class DistributedUI {
const isMasterToggle = config?.masterToggle && typeof extension.isMasterParticipating === 'function';
if (isMasterToggle) {
- const participating = extension.isMasterParticipating();
- checkbox.checked = participating;
+ const participationEnabled = extension.isMasterParticipationEnabled();
+ const fallbackActive = extension.isMasterFallbackActive();
+ const buildTitle = (enabled, fallback) => {
+ if (enabled) {
+ return "Master participating • Click to switch to orchestrator-only";
+ }
+ if (fallback) {
+ return "No workers selected • Master fallback execution active";
+ }
+ return "Master orchestrator-only • Click to re-enable participation";
+ };
+
+ checkbox.checked = participationEnabled;
checkbox.style.pointerEvents = "none";
column.style.cursor = "pointer";
- column.title = participating ? "Master participating • Click to switch to orchestrator-only" : "Master orchestrator-only • Click to re-enable participation";
+ column.title = buildTitle(participationEnabled, fallbackActive);
column.onclick = async (event) => {
if (event) {
event.stopPropagation();
event.preventDefault();
}
- const targetState = !checkbox.checked;
- checkbox.checked = targetState;
- column.title = targetState ? "Master participating • Click to switch to orchestrator-only" : "Master orchestrator-only • Click to re-enable participation";
- await extension.updateMasterParticipation(targetState);
+ const nextState = !extension.isMasterParticipationEnabled();
+ const nextFallback = !nextState && extension.enabledWorkers.length === 0;
+ checkbox.checked = nextState;
+ column.title = buildTitle(nextState, nextFallback);
+ await extension.updateMasterParticipation(nextState);
};
} else if (config?.enabled && !config?.disabled && data?.id) {
checkbox.style.pointerEvents = "none";
@@ -955,14 +974,25 @@ export class DistributedUI {
controlsWrapper.style.cssText = this.styles.controlsWrapper;
if (config.type === 'master') {
- const participating = extension.isMasterParticipating();
- const message = participating ? "Master participating in workflows" : "Master disabled: running as orchestrator only";
+ const participationEnabled = extension.isMasterParticipationEnabled();
+ const fallbackActive = extension.isMasterFallbackActive();
+ let message;
const badge = document.createElement("div");
badge.style.cssText = this.styles.infoBox;
- badge.textContent = message;
- if (!participating) {
+ if (fallbackActive) {
+ message = "No workers selected. Master fallback execution active.";
+ badge.textContent = message;
+ badge.style.backgroundColor = "#243024";
+ badge.style.color = "#6bd06b";
+ badge.style.border = "1px solid #335533";
+ } else if (!participationEnabled) {
+ message = "Master disabled: running as orchestrator only.";
+ badge.textContent = message;
badge.style.backgroundColor = "#3a3a3a";
badge.style.color = "#ffcc66";
+ } else {
+ message = "Master participating in workflows.";
+ badge.textContent = message;
}
controlsWrapper.appendChild(badge);
} else if (config.dynamic && data) {