Compare commits
34
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
778e6fefe6 | ||
|
|
fd310e8478 | ||
|
|
3a3b93d564 | ||
|
|
82c564228d | ||
|
|
ad0a23434b | ||
|
|
292f77f06b | ||
|
|
a139424b91 | ||
|
|
44a91d2093 | ||
|
|
7cff930861 | ||
|
|
ce464c6ce4 | ||
|
|
1c7998c554 | ||
|
|
66d1e42409 | ||
|
|
8882f4983c | ||
|
|
492b81c340 | ||
|
|
8b05ed26c9 | ||
|
|
ce67604926 | ||
|
|
c115c22a91 | ||
|
|
2f33bcf497 | ||
|
|
bcf466c472 | ||
|
|
f812d9d698 | ||
|
|
101b6cca57 | ||
|
|
ae68aae011 | ||
|
|
07926158f0 | ||
|
|
ce92dd0570 | ||
|
|
e2fcf67aec | ||
|
|
79650f48d0 | ||
|
|
69f63f4869 | ||
|
|
50860cd500 | ||
|
|
2eb02fc92e | ||
|
|
d1c54b2b6d | ||
|
|
3a6c3b1ae9 | ||
|
|
0e70db4013 | ||
|
|
06805e310d | ||
|
|
4cd7d7a8f9 |
@@ -1,52 +0,0 @@
|
|||||||
import folder_paths
|
|
||||||
from PIL import Image, ImageOps
|
|
||||||
import numpy as np
|
|
||||||
import torch
|
|
||||||
import json
|
|
||||||
|
|
||||||
class ComfyUIDeployExternalTextList:
|
|
||||||
@classmethod
|
|
||||||
def INPUT_TYPES(s):
|
|
||||||
return {
|
|
||||||
"required": {
|
|
||||||
"input_id": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": False, "default": 'input_text_list'},
|
|
||||||
),
|
|
||||||
"text": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": True, "default": "[]"},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"display_name": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": False, "default": ""},
|
|
||||||
),
|
|
||||||
"description": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": True, "default": ""},
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("STRING",)
|
|
||||||
RETURN_NAMES = ("text",)
|
|
||||||
|
|
||||||
OUTPUT_IS_LIST = (True,)
|
|
||||||
|
|
||||||
FUNCTION = "run"
|
|
||||||
|
|
||||||
CATEGORY = "text"
|
|
||||||
|
|
||||||
def run(self, input_id, text=None, display_name=None, description=None):
|
|
||||||
text_list = []
|
|
||||||
try:
|
|
||||||
text_list = json.loads(text) # Assuming text is a JSON array string
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error processing images: {e}")
|
|
||||||
pass
|
|
||||||
return ([text_list],)
|
|
||||||
|
|
||||||
NODE_CLASS_MAPPINGS = {"ComfyUIDeployExternalTextList": ComfyUIDeployExternalTextList}
|
|
||||||
NODE_DISPLAY_NAME_MAPPINGS = {"ComfyUIDeployExternalTextList": "External Text List (ComfyUI Deploy)"}
|
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import folder_paths
|
||||||
|
class AnyType(str):
|
||||||
|
def __ne__(self, __value: object) -> bool:
|
||||||
|
return False
|
||||||
|
|
||||||
|
from os import walk
|
||||||
|
|
||||||
|
WILDCARD = AnyType("*")
|
||||||
|
|
||||||
|
MODEL_EXTENSIONS = {
|
||||||
|
"safetensors": "SafeTensors file format",
|
||||||
|
"ckpt": "Checkpoint file",
|
||||||
|
"pth": "PyTorch serialized file",
|
||||||
|
"pkl": "Pickle file",
|
||||||
|
"onnx": "ONNX file",
|
||||||
|
}
|
||||||
|
|
||||||
|
def fetch_files(path):
|
||||||
|
for (dirpath, dirnames, filenames) in walk(path):
|
||||||
|
fs = []
|
||||||
|
if len(dirnames) > 0:
|
||||||
|
for dirname in dirnames:
|
||||||
|
fs.extend(fetch_files(f"{dirpath}/{dirname}"))
|
||||||
|
for filename in filenames:
|
||||||
|
# Remove "./models/" from the beginning of dirpath
|
||||||
|
relative_dirpath = dirpath.replace("./models/", "", 1)
|
||||||
|
file_path = f"{relative_dirpath}/{filename}"
|
||||||
|
|
||||||
|
# Only add files that are known model extensions
|
||||||
|
file_extension = filename.split('.')[-1].lower()
|
||||||
|
if file_extension in MODEL_EXTENSIONS:
|
||||||
|
fs.append(file_path)
|
||||||
|
|
||||||
|
return fs
|
||||||
|
allModels = fetch_files("./models")
|
||||||
|
|
||||||
|
class ComfyUIDeployModalList:
|
||||||
|
@classmethod
|
||||||
|
def INPUT_TYPES(s):
|
||||||
|
return {
|
||||||
|
"required": {
|
||||||
|
"model": (allModels, ),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN_TYPES = (WILDCARD,)
|
||||||
|
RETURN_NAMES = ("model",)
|
||||||
|
|
||||||
|
FUNCTION = "run"
|
||||||
|
|
||||||
|
CATEGORY = "model"
|
||||||
|
|
||||||
|
def run(self, model=""):
|
||||||
|
# Split the model path by '/' and select the last item
|
||||||
|
model_name = model.split('/')[-1]
|
||||||
|
return [model_name]
|
||||||
|
|
||||||
|
|
||||||
|
NODE_CLASS_MAPPINGS = {"ComfyUIDeployModelList": ComfyUIDeployModalList}
|
||||||
|
NODE_DISPLAY_NAME_MAPPINGS = {"ComfyUIDeployModelList": "Model List (ComfyUI Deploy)"}
|
||||||
+632
-358
File diff suppressed because it is too large
Load Diff
+25
-8
@@ -6,10 +6,12 @@ from PIL import Image, ImageOps
|
|||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from pydantic import BaseModel as PydanticBaseModel
|
from pydantic import BaseModel as PydanticBaseModel
|
||||||
|
|
||||||
|
|
||||||
class BaseModel(PydanticBaseModel):
|
class BaseModel(PydanticBaseModel):
|
||||||
class Config:
|
class Config:
|
||||||
arbitrary_types_allowed = True
|
arbitrary_types_allowed = True
|
||||||
|
|
||||||
|
|
||||||
class Status(Enum):
|
class Status(Enum):
|
||||||
NOT_STARTED = "not-started"
|
NOT_STARTED = "not-started"
|
||||||
RUNNING = "running"
|
RUNNING = "running"
|
||||||
@@ -17,6 +19,7 @@ class Status(Enum):
|
|||||||
FAILED = "failed"
|
FAILED = "failed"
|
||||||
UPLOADING = "uploading"
|
UPLOADING = "uploading"
|
||||||
|
|
||||||
|
|
||||||
class StreamingPrompt(BaseModel):
|
class StreamingPrompt(BaseModel):
|
||||||
workflow_api: Any
|
workflow_api: Any
|
||||||
auth_token: str
|
auth_token: str
|
||||||
@@ -25,6 +28,8 @@ class StreamingPrompt(BaseModel):
|
|||||||
status_endpoint: Optional[str]
|
status_endpoint: Optional[str]
|
||||||
file_upload_endpoint: Optional[str]
|
file_upload_endpoint: Optional[str]
|
||||||
workflow: Any
|
workflow: Any
|
||||||
|
gpu_event_id: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
class SimplePrompt(BaseModel):
|
class SimplePrompt(BaseModel):
|
||||||
status_endpoint: Optional[str]
|
status_endpoint: Optional[str]
|
||||||
@@ -35,34 +40,39 @@ class SimplePrompt(BaseModel):
|
|||||||
workflow_api: dict
|
workflow_api: dict
|
||||||
status: Status = Status.NOT_STARTED
|
status: Status = Status.NOT_STARTED
|
||||||
progress: set = set()
|
progress: set = set()
|
||||||
last_updated_node: Optional[str] = None,
|
last_updated_node: Optional[str] = None
|
||||||
uploading_nodes: set = set()
|
uploading_nodes: set = set()
|
||||||
done: bool = False
|
done: bool = False
|
||||||
is_realtime: bool = False,
|
is_realtime: bool = False
|
||||||
start_time: Optional[float] = None,
|
start_time: Optional[float] = None
|
||||||
|
gpu_event_id: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
sockets = dict()
|
sockets = dict()
|
||||||
prompt_metadata: dict[str, SimplePrompt] = {}
|
prompt_metadata: dict[str, SimplePrompt] = {}
|
||||||
streaming_prompt_metadata: dict[str, StreamingPrompt] = {}
|
streaming_prompt_metadata: dict[str, StreamingPrompt] = {}
|
||||||
|
|
||||||
|
|
||||||
class BinaryEventTypes:
|
class BinaryEventTypes:
|
||||||
PREVIEW_IMAGE = 1
|
PREVIEW_IMAGE = 1
|
||||||
UNENCODED_PREVIEW_IMAGE = 2
|
UNENCODED_PREVIEW_IMAGE = 2
|
||||||
|
|
||||||
|
|
||||||
max_output_id_length = 24
|
max_output_id_length = 24
|
||||||
|
|
||||||
async def send_image(image_data, sid=None, output_id:str = None):
|
|
||||||
|
async def send_image(image_data, sid=None, output_id: str = None):
|
||||||
max_length = max_output_id_length
|
max_length = max_output_id_length
|
||||||
output_id = output_id[:max_length]
|
output_id = output_id[:max_length]
|
||||||
padded_output_id = output_id.ljust(max_length, '\x00')
|
padded_output_id = output_id.ljust(max_length, "\x00")
|
||||||
encoded_output_id = padded_output_id.encode('ascii', 'replace')
|
encoded_output_id = padded_output_id.encode("ascii", "replace")
|
||||||
|
|
||||||
image_type = image_data[0]
|
image_type = image_data[0]
|
||||||
image = image_data[1]
|
image = image_data[1]
|
||||||
max_size = image_data[2]
|
max_size = image_data[2]
|
||||||
quality = image_data[3]
|
quality = image_data[3]
|
||||||
if max_size is not None:
|
if max_size is not None:
|
||||||
if hasattr(Image, 'Resampling'):
|
if hasattr(Image, "Resampling"):
|
||||||
resampling = Image.Resampling.BILINEAR
|
resampling = Image.Resampling.BILINEAR
|
||||||
else:
|
else:
|
||||||
resampling = Image.ANTIALIAS
|
resampling = Image.ANTIALIAS
|
||||||
@@ -91,12 +101,18 @@ async def send_image(image_data, sid=None, output_id:str = None):
|
|||||||
preview_bytes = bytesIO.getvalue()
|
preview_bytes = bytesIO.getvalue()
|
||||||
await send_bytes(BinaryEventTypes.PREVIEW_IMAGE, preview_bytes, sid=sid)
|
await send_bytes(BinaryEventTypes.PREVIEW_IMAGE, preview_bytes, sid=sid)
|
||||||
|
|
||||||
|
|
||||||
async def send_socket_catch_exception(function, message):
|
async def send_socket_catch_exception(function, message):
|
||||||
try:
|
try:
|
||||||
await function(message)
|
await function(message)
|
||||||
except (aiohttp.ClientError, aiohttp.ClientPayloadError, ConnectionResetError) as err:
|
except (
|
||||||
|
aiohttp.ClientError,
|
||||||
|
aiohttp.ClientPayloadError,
|
||||||
|
ConnectionResetError,
|
||||||
|
) as err:
|
||||||
print("send error:", err)
|
print("send error:", err)
|
||||||
|
|
||||||
|
|
||||||
def encode_bytes(event, data):
|
def encode_bytes(event, data):
|
||||||
if not isinstance(event, int):
|
if not isinstance(event, int):
|
||||||
raise RuntimeError(f"Binary event types must be integers, got {event}")
|
raise RuntimeError(f"Binary event types must be integers, got {event}")
|
||||||
@@ -106,6 +122,7 @@ def encode_bytes(event, data):
|
|||||||
message.extend(data)
|
message.extend(data)
|
||||||
return message
|
return message
|
||||||
|
|
||||||
|
|
||||||
async def send_bytes(event, data, sid=None):
|
async def send_bytes(event, data, sid=None):
|
||||||
message = encode_bytes(event, data)
|
message = encode_bytes(event, data)
|
||||||
|
|
||||||
|
|||||||
+164
-41
@@ -83,11 +83,52 @@ function dispatchAPIEventData(data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const context = {
|
||||||
|
selectedWorkflowInfo: null,
|
||||||
|
};
|
||||||
|
// let selectedWorkflowInfo = {
|
||||||
|
// workflow_id: "05da8f2b-63af-4c0c-86dd-08d01ec512b7",
|
||||||
|
// machine_id: "45ac5f85-b7b6-436f-8d97-2383b25485f3",
|
||||||
|
// native_run_api_endpoint: "http://localhost:3011/api/run",
|
||||||
|
// };
|
||||||
|
|
||||||
|
async function getSelectedWorkflowInfo() {
|
||||||
|
const workflow_info_promise = new Promise((resolve) => {
|
||||||
|
try {
|
||||||
|
const handleMessage = (event) => {
|
||||||
|
try {
|
||||||
|
const message = JSON.parse(event.data);
|
||||||
|
if (message.type === "workflow_info") {
|
||||||
|
resolve(message.data);
|
||||||
|
window.removeEventListener("message", handleMessage);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
resolve(undefined);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.addEventListener("message", handleMessage);
|
||||||
|
sendEventToCD("workflow_info");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
resolve(undefined);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return workflow_info_promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSelectedWorkflowInfo(info) {
|
||||||
|
context.selectedWorkflowInfo = info;
|
||||||
|
}
|
||||||
|
|
||||||
/** @typedef {import('../../../web/types/comfy.js').ComfyExtension} ComfyExtension*/
|
/** @typedef {import('../../../web/types/comfy.js').ComfyExtension} ComfyExtension*/
|
||||||
/** @type {ComfyExtension} */
|
/** @type {ComfyExtension} */
|
||||||
const ext = {
|
const ext = {
|
||||||
name: "BennyKok.ComfyUIDeploy",
|
name: "BennyKok.ComfyUIDeploy",
|
||||||
|
|
||||||
|
native_mode: false,
|
||||||
|
|
||||||
init(app) {
|
init(app) {
|
||||||
addButton();
|
addButton();
|
||||||
|
|
||||||
@@ -97,16 +138,17 @@ const ext = {
|
|||||||
const org_display = queryParams.get("org_display");
|
const org_display = queryParams.get("org_display");
|
||||||
const origin = queryParams.get("origin");
|
const origin = queryParams.get("origin");
|
||||||
const workspace_mode = queryParams.get("workspace_mode");
|
const workspace_mode = queryParams.get("workspace_mode");
|
||||||
|
this.native_mode = queryParams.get("native_mode") === "true";
|
||||||
|
|
||||||
if (workspace_mode) {
|
if (workspace_mode) {
|
||||||
document.querySelector(".comfy-menu").style.display = "none";
|
document.querySelector(".comfy-menu").style.display = "none";
|
||||||
|
|
||||||
sendEventToCD("cd_plugin_onInit");
|
sendEventToCD("cd_plugin_onInit");
|
||||||
|
|
||||||
app.queuePrompt = ((originalFunction) => async () => {
|
// app.queuePrompt = ((originalFunction) => async () => {
|
||||||
// const prompt = await app.graphToPrompt();
|
// // const prompt = await app.graphToPrompt();
|
||||||
sendEventToCD("cd_plugin_onQueuePromptTrigger");
|
// sendEventToCD("cd_plugin_onQueuePromptTrigger");
|
||||||
})(app.queuePrompt);
|
// })(app.queuePrompt);
|
||||||
|
|
||||||
// // Intercept the onkeydown event
|
// // Intercept the onkeydown event
|
||||||
// window.addEventListener(
|
// window.addEventListener(
|
||||||
@@ -213,7 +255,7 @@ const ext = {
|
|||||||
(v) => {
|
(v) => {
|
||||||
this.properties.workflow_name = v;
|
this.properties.workflow_name = v;
|
||||||
},
|
},
|
||||||
{ multiline: false }
|
{ multiline: false },
|
||||||
);
|
);
|
||||||
|
|
||||||
this.addWidget(
|
this.addWidget(
|
||||||
@@ -223,7 +265,7 @@ const ext = {
|
|||||||
(v) => {
|
(v) => {
|
||||||
this.properties.workflow_id = v;
|
this.properties.workflow_id = v;
|
||||||
},
|
},
|
||||||
{ multiline: false }
|
{ multiline: false },
|
||||||
);
|
);
|
||||||
|
|
||||||
this.addWidget(
|
this.addWidget(
|
||||||
@@ -233,7 +275,7 @@ const ext = {
|
|||||||
(v) => {
|
(v) => {
|
||||||
this.properties.version = v;
|
this.properties.version = v;
|
||||||
},
|
},
|
||||||
{ multiline: false }
|
{ multiline: false },
|
||||||
);
|
);
|
||||||
|
|
||||||
this.widgets_start_y = 10;
|
this.widgets_start_y = 10;
|
||||||
@@ -270,11 +312,14 @@ const ext = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Register the node type
|
// Register the node type
|
||||||
LiteGraph.registerNodeType("ComfyDeploy", Object.assign(ComfyDeploy, {
|
LiteGraph.registerNodeType(
|
||||||
title: "Comfy Deploy",
|
"ComfyDeploy",
|
||||||
title_mode: LiteGraph.NORMAL_TITLE,
|
Object.assign(ComfyDeploy, {
|
||||||
collapsable: true,
|
title: "Comfy Deploy",
|
||||||
}));
|
title_mode: LiteGraph.NORMAL_TITLE,
|
||||||
|
collapsable: true,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
ComfyDeploy.category = "deploy";
|
ComfyDeploy.category = "deploy";
|
||||||
},
|
},
|
||||||
@@ -293,6 +338,17 @@ const ext = {
|
|||||||
// This part of the code would depend on how the ComfyUI expects to receive and process the workflow data
|
// This part of the code would depend on how the ComfyUI expects to receive and process the workflow data
|
||||||
// For demonstration, let's assume there's a loadWorkflow method in the ComfyUI API
|
// For demonstration, let's assume there's a loadWorkflow method in the ComfyUI API
|
||||||
if (comfyUIWorkflow && app && app.loadGraphData) {
|
if (comfyUIWorkflow && app && app.loadGraphData) {
|
||||||
|
try {
|
||||||
|
await window["app"].ui.settings.setSettingValueAsync(
|
||||||
|
"Comfy.Validation.Workflows",
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.warning(
|
||||||
|
"Error setting validation to false, is fine to ignore this",
|
||||||
|
error,
|
||||||
|
);
|
||||||
|
}
|
||||||
console.log("loadGraphData");
|
console.log("loadGraphData");
|
||||||
app.loadGraphData(comfyUIWorkflow);
|
app.loadGraphData(comfyUIWorkflow);
|
||||||
}
|
}
|
||||||
@@ -380,6 +436,8 @@ const ext = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
animate();
|
animate();
|
||||||
|
} else if (message.type === "workflow_info") {
|
||||||
|
setSelectedWorkflowInfo(message.data);
|
||||||
}
|
}
|
||||||
// else if (message.type === "refresh") {
|
// else if (message.type === "refresh") {
|
||||||
// sendEventToCD("cd_plugin_onRefresh");
|
// sendEventToCD("cd_plugin_onRefresh");
|
||||||
@@ -399,6 +457,25 @@ const ext = {
|
|||||||
// }
|
// }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (this.native_mode) {
|
||||||
|
// console.log("native mode", window, window.app);
|
||||||
|
try {
|
||||||
|
await app.ui.settings.setSettingValueAsync("Comfy.UseNewMenu", "Top");
|
||||||
|
await app.ui.settings.setSettingValueAsync(
|
||||||
|
"Comfy.Sidebar.Size",
|
||||||
|
"small"
|
||||||
|
);
|
||||||
|
await app.ui.settings.setSettingValueAsync(
|
||||||
|
"Comfy.Sidebar.Location",
|
||||||
|
"right"
|
||||||
|
);
|
||||||
|
localStorage.setItem("Comfy.MenuPosition.Docked", "true");
|
||||||
|
console.log("native mode manmanman");
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error setting validation to false", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
app.graph.onAfterChange = ((originalFunction) =>
|
app.graph.onAfterChange = ((originalFunction) =>
|
||||||
async function () {
|
async function () {
|
||||||
const prompt = await app.graphToPrompt();
|
const prompt = await app.graphToPrompt();
|
||||||
@@ -443,10 +520,10 @@ function createDynamicUIHtml(data) {
|
|||||||
<h3 style="font-size: 14px; font-weight: semibold; margin-bottom: 8px;">Missing Nodes</h3>
|
<h3 style="font-size: 14px; font-weight: semibold; margin-bottom: 8px;">Missing Nodes</h3>
|
||||||
<p style="font-size: 12px;">These nodes are not found with any matching custom_nodes in the ComfyUI Manager Database</p>
|
<p style="font-size: 12px;">These nodes are not found with any matching custom_nodes in the ComfyUI Manager Database</p>
|
||||||
${data.missing_nodes
|
${data.missing_nodes
|
||||||
.map((node) => {
|
.map((node) => {
|
||||||
return `<p style="font-size: 14px; color: #d69e2e;">${node}</p>`;
|
return `<p style="font-size: 14px; color: #d69e2e;">${node}</p>`;
|
||||||
})
|
})
|
||||||
.join("")}
|
.join("")}
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@@ -454,14 +531,17 @@ function createDynamicUIHtml(data) {
|
|||||||
Object.values(data.custom_nodes).forEach((node) => {
|
Object.values(data.custom_nodes).forEach((node) => {
|
||||||
html += `
|
html += `
|
||||||
<div style="border-bottom: 1px solid #e2e8f0; padding-top: 16px;">
|
<div style="border-bottom: 1px solid #e2e8f0; padding-top: 16px;">
|
||||||
<a href="${node.url
|
<a href="${
|
||||||
}" target="_blank" style="font-size: 18px; font-weight: semibold; color: white; text-decoration: none;">${node.name
|
node.url
|
||||||
}</a>
|
}" target="_blank" style="font-size: 18px; font-weight: semibold; color: white; text-decoration: none;">${
|
||||||
|
node.name
|
||||||
|
}</a>
|
||||||
<p style="font-size: 14px; color: #4b5563;">${node.hash}</p>
|
<p style="font-size: 14px; color: #4b5563;">${node.hash}</p>
|
||||||
${node.warning
|
${
|
||||||
? `<p style="font-size: 14px; color: #d69e2e;">${node.warning}</p>`
|
node.warning
|
||||||
: ""
|
? `<p style="font-size: 14px; color: #d69e2e;">${node.warning}</p>`
|
||||||
}
|
: ""
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
});
|
});
|
||||||
@@ -475,8 +555,9 @@ function createDynamicUIHtml(data) {
|
|||||||
Object.entries(data.models).forEach(([section, items]) => {
|
Object.entries(data.models).forEach(([section, items]) => {
|
||||||
html += `
|
html += `
|
||||||
<div style="border-bottom: 1px solid #e2e8f0; padding-top: 8px; padding-bottom: 8px;">
|
<div style="border-bottom: 1px solid #e2e8f0; padding-top: 8px; padding-bottom: 8px;">
|
||||||
<h3 style="font-size: 18px; font-weight: semibold; margin-bottom: 8px;">${section.charAt(0).toUpperCase() + section.slice(1)
|
<h3 style="font-size: 18px; font-weight: semibold; margin-bottom: 8px;">${
|
||||||
}</h3>`;
|
section.charAt(0).toUpperCase() + section.slice(1)
|
||||||
|
}</h3>`;
|
||||||
items.forEach((item) => {
|
items.forEach((item) => {
|
||||||
html += `<p style="font-size: 14px; color: ${textColor};">${item.name}</p>`;
|
html += `<p style="font-size: 14px; color: ${textColor};">${item.name}</p>`;
|
||||||
});
|
});
|
||||||
@@ -492,8 +573,9 @@ function createDynamicUIHtml(data) {
|
|||||||
Object.entries(data.files).forEach(([section, items]) => {
|
Object.entries(data.files).forEach(([section, items]) => {
|
||||||
html += `
|
html += `
|
||||||
<div style="border-bottom: 1px solid #e2e8f0; padding-top: 8px; padding-bottom: 8px;">
|
<div style="border-bottom: 1px solid #e2e8f0; padding-top: 8px; padding-bottom: 8px;">
|
||||||
<h3 style="font-size: 18px; font-weight: semibold; margin-bottom: 8px;">${section.charAt(0).toUpperCase() + section.slice(1)
|
<h3 style="font-size: 18px; font-weight: semibold; margin-bottom: 8px;">${
|
||||||
}</h3>`;
|
section.charAt(0).toUpperCase() + section.slice(1)
|
||||||
|
}</h3>`;
|
||||||
items.forEach((item) => {
|
items.forEach((item) => {
|
||||||
html += `<p style="font-size: 14px; color: ${textColor};">${item.name}</p>`;
|
html += `<p style="font-size: 14px; color: ${textColor};">${item.name}</p>`;
|
||||||
});
|
});
|
||||||
@@ -1013,12 +1095,14 @@ export class LoadingDialog extends ComfyDialog {
|
|||||||
showLoading(title, message) {
|
showLoading(title, message) {
|
||||||
this.show(`
|
this.show(`
|
||||||
<div style="width: 400px; display: flex; gap: 18px; flex-direction: column; overflow: unset">
|
<div style="width: 400px; display: flex; gap: 18px; flex-direction: column; overflow: unset">
|
||||||
<h3 style="margin: 0px; display: flex; align-items: center; justify-content: center; gap: 12px;">${title} ${this.loadingIcon
|
<h3 style="margin: 0px; display: flex; align-items: center; justify-content: center; gap: 12px;">${title} ${
|
||||||
}</h3>
|
this.loadingIcon
|
||||||
${message
|
}</h3>
|
||||||
? `<label style="max-width: 100%; white-space: pre-wrap; word-wrap: break-word;">${message}</label>`
|
${
|
||||||
: ""
|
message
|
||||||
}
|
? `<label style="max-width: 100%; white-space: pre-wrap; word-wrap: break-word;">${message}</label>`
|
||||||
|
: ""
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
@@ -1284,17 +1368,21 @@ export class ConfigDialog extends ComfyDialog {
|
|||||||
</label>
|
</label>
|
||||||
<label style="color: white; width: 100%;">
|
<label style="color: white; width: 100%;">
|
||||||
Endpoint:
|
Endpoint:
|
||||||
<input id="endpoint" style="margin-top: 8px; width: 100%; height:40px; box-sizing: border-box; padding: 0px 6px;" type="text" value="${data.endpoint
|
<input id="endpoint" style="margin-top: 8px; width: 100%; height:40px; box-sizing: border-box; padding: 0px 6px;" type="text" value="${
|
||||||
}">
|
data.endpoint
|
||||||
|
}">
|
||||||
</label>
|
</label>
|
||||||
<div style="color: white;">
|
<div style="color: white;">
|
||||||
API Key: User / Org <button style="font-size: 18px;">${data.displayName ?? ""
|
API Key: User / Org <button style="font-size: 18px;">${
|
||||||
}</button>
|
data.displayName ?? ""
|
||||||
<input id="apiKey" style="margin-top: 8px; width: 100%; height:40px; box-sizing: border-box; padding: 0px 6px;" type="password" value="${data.apiKey
|
}</button>
|
||||||
}">
|
<input id="apiKey" style="margin-top: 8px; width: 100%; height:40px; box-sizing: border-box; padding: 0px 6px;" type="password" value="${
|
||||||
|
data.apiKey
|
||||||
|
}">
|
||||||
<button id="loginButton" style="margin-top: 8px; width: 100%; height:40px; box-sizing: border-box; padding: 0px 6px;">
|
<button id="loginButton" style="margin-top: 8px; width: 100%; height:40px; box-sizing: border-box; padding: 0px 6px;">
|
||||||
${data.apiKey ? "Re-login with ComfyDeploy" : "Login with ComfyDeploy"
|
${
|
||||||
}
|
data.apiKey ? "Re-login with ComfyDeploy" : "Login with ComfyDeploy"
|
||||||
|
}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1483,3 +1571,38 @@ async function loadWorkflowApi(versionId) {
|
|||||||
// Show an error message to the user
|
// Show an error message to the user
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const orginal_fetch_api = api.fetchApi;
|
||||||
|
api.fetchApi = async (route, options) => {
|
||||||
|
console.log("Fetch API called with args:", route, options, ext.native_mode);
|
||||||
|
|
||||||
|
if (route.startsWith("/prompt") && ext.native_mode) {
|
||||||
|
const info = await getSelectedWorkflowInfo();
|
||||||
|
console.log("info", info);
|
||||||
|
if (info) {
|
||||||
|
const body = JSON.parse(options.body);
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
client_id: body.client_id,
|
||||||
|
workflow_api_json: body.prompt,
|
||||||
|
workflow: body?.extra_data?.extra_pnginfo?.workflow,
|
||||||
|
is_native_run: true,
|
||||||
|
machine_id: info.machine_id,
|
||||||
|
workflow_id: info.workflow_id,
|
||||||
|
native_run_api_endpoint: info.native_run_api_endpoint,
|
||||||
|
gpu_event_id: info.gpu_event_id,
|
||||||
|
};
|
||||||
|
|
||||||
|
return await fetch("/comfyui-deploy/run", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${info.cd_token}`,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return await orginal_fetch_api.call(api, route, options);
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user