dsh-image-gen 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +172 -171
- package/README.md +182 -187
- package/README.zh-CN.md +172 -171
- package/lib/client.js +186 -25
- package/lib/client.js.map +1 -1
- package/lib/index.js +385 -33
- package/lib/types/client/index.d.ts +22 -2
- package/lib/types/comfyui-workflow.d.ts +8 -0
- package/lib/types/comfyui.d.ts +15 -0
- package/lib/types/config.d.ts +14 -2
- package/lib/types/dashscope.d.ts +2 -2
- package/lib/types/google.d.ts +2 -2
- package/lib/types/openai-compatible.d.ts +1 -1
- package/lib/types/reference-image.d.ts +17 -0
- package/lib/types/seedream.d.ts +2 -2
- package/lib/types/shared.d.ts +5 -1
- package/package.json +133 -131
- package/skills/install-dsh-image-gen/SKILL.md +22 -22
package/lib/client.js
CHANGED
|
@@ -17,19 +17,58 @@ window.__ModuleLoader__.load({
|
|
|
17
17
|
const DEFAULT_OPENAI_BASE_URL = "https://api.openai.com/v1";
|
|
18
18
|
const DEFAULT_SEEDREAM_BASE_URL = "https://ark.cn-beijing.volces.com/api/v3";
|
|
19
19
|
const DEFAULT_DASHSCOPE_ENDPOINT = "https://dashscope.aliyuncs.com/api/v1";
|
|
20
|
+
const DEFAULT_COMFYUI_BASE_URL = "http://127.0.0.1:8188";
|
|
21
|
+
const DEFAULT_COMFYUI_TIMEOUT_MS = 3e5;
|
|
20
22
|
const DEFAULT_MODELS = {
|
|
21
23
|
google: "gemini-3.1-flash-image",
|
|
22
24
|
openai: "gpt-image-2",
|
|
23
25
|
seedream: "doubao-seedream-5-0-260128",
|
|
24
|
-
dashscope: "qwen-image-3.0"
|
|
26
|
+
dashscope: "qwen-image-3.0",
|
|
27
|
+
comfyui: "API workflow"
|
|
25
28
|
};
|
|
26
29
|
const DEFAULT_BASE_URLS = {
|
|
27
30
|
google: DEFAULT_GOOGLE_ENDPOINT,
|
|
28
31
|
openai: DEFAULT_OPENAI_BASE_URL,
|
|
29
32
|
seedream: DEFAULT_SEEDREAM_BASE_URL,
|
|
30
|
-
dashscope: DEFAULT_DASHSCOPE_ENDPOINT
|
|
33
|
+
dashscope: DEFAULT_DASHSCOPE_ENDPOINT,
|
|
34
|
+
comfyui: DEFAULT_COMFYUI_BASE_URL
|
|
31
35
|
};
|
|
32
36
|
//#endregion
|
|
37
|
+
//#region lib/types/comfyui-workflow.js
|
|
38
|
+
/** Pure ComfyUI API-workflow validation and placeholder injection. */
|
|
39
|
+
const COMFYUI_PROMPT_PLACEHOLDER = "{{prompt}}";
|
|
40
|
+
/** Validate imported JSON without exposing workflow graph details to callers. */
|
|
41
|
+
function validateComfyUIWorkflowJson(workflowJson) {
|
|
42
|
+
parseWorkflow(workflowJson);
|
|
43
|
+
}
|
|
44
|
+
function parseWorkflow(workflowJson) {
|
|
45
|
+
if (workflowJson.trim().length === 0) throw new Error("Import a ComfyUI API workflow JSON file in Settings before generating");
|
|
46
|
+
if (new TextEncoder().encode(workflowJson).byteLength > 5242880) throw new Error("ComfyUI workflow file must be no larger than 5 MB");
|
|
47
|
+
let value;
|
|
48
|
+
try {
|
|
49
|
+
value = JSON.parse(workflowJson);
|
|
50
|
+
} catch {
|
|
51
|
+
throw new Error("ComfyUI workflow file is not valid JSON");
|
|
52
|
+
}
|
|
53
|
+
if (!isRecord(value) || Object.keys(value).length === 0) throw new Error("ComfyUI workflow must be a non-empty API-format JSON object");
|
|
54
|
+
if (!Object.values(value).some((node) => {
|
|
55
|
+
const inputs = record(node)?.inputs;
|
|
56
|
+
return inputs !== void 0 && containsPromptPlaceholder(inputs);
|
|
57
|
+
})) throw new Error(`ComfyUI workflow must contain ${COMFYUI_PROMPT_PLACEHOLDER} in a text input`);
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
function containsPromptPlaceholder(value) {
|
|
61
|
+
if (typeof value === "string") return value.includes(COMFYUI_PROMPT_PLACEHOLDER);
|
|
62
|
+
if (Array.isArray(value)) return value.some(containsPromptPlaceholder);
|
|
63
|
+
return isRecord(value) && Object.values(value).some(containsPromptPlaceholder);
|
|
64
|
+
}
|
|
65
|
+
function isRecord(value) {
|
|
66
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
67
|
+
}
|
|
68
|
+
function record(value) {
|
|
69
|
+
return isRecord(value) ? value : void 0;
|
|
70
|
+
}
|
|
71
|
+
//#endregion
|
|
33
72
|
//#region lib/types/client/gallery-store.js
|
|
34
73
|
const DB_NAME = "dsh_image_gen_db";
|
|
35
74
|
const DB_VERSION = 2;
|
|
@@ -906,6 +945,7 @@ window.__ModuleLoader__.load({
|
|
|
906
945
|
providerOpenAI: "OpenAI / 中转站",
|
|
907
946
|
providerSeedream: "字节 Seedream",
|
|
908
947
|
providerDashScope: "阿里 DashScope (通义万相 / Qwen)",
|
|
948
|
+
providerComfyUI: "本地 ComfyUI",
|
|
909
949
|
apiKeyLabel: "{provider} API Key",
|
|
910
950
|
apiKeyPlaceholder: "留空即可保留已配置的 Key",
|
|
911
951
|
apiKeyHint: "安全保存为 {key};页面不会读回明文。",
|
|
@@ -916,7 +956,17 @@ window.__ModuleLoader__.load({
|
|
|
916
956
|
endpointHintOpenAI: "中转站请填其 OpenAI 兼容的 /v1 地址。",
|
|
917
957
|
endpointHintSeedream: "火山方舟兼容的 /api/v3 地址。",
|
|
918
958
|
endpointHintDashScope: "阿里云百炼 DashScope 官方接口地址。",
|
|
959
|
+
endpointHintComfyUI: "正在运行且 DSH Host 可以访问的 ComfyUI 地址,默认使用本机 8188 端口。",
|
|
919
960
|
model: "模型",
|
|
961
|
+
workflow: "API Workflow",
|
|
962
|
+
workflowImport: "导入 JSON 文件",
|
|
963
|
+
workflowReplace: "替换 JSON 文件",
|
|
964
|
+
workflowMissing: "尚未导入工作流",
|
|
965
|
+
workflowImported: "已导入 {name}",
|
|
966
|
+
workflowHint: "请从 ComfyUI 导出 API Format JSON,并在提示词输入位置写入 {{prompt}};可用 {{seed}} 作为随机种子。",
|
|
967
|
+
workflowTooLarge: "工作流文件不能超过 5 MB。",
|
|
968
|
+
timeout: "生成超时(秒)",
|
|
969
|
+
timeoutHint: "包括提交、等待和下载图片;默认 300 秒。",
|
|
920
970
|
saveToWorkspace: "保存到工作区",
|
|
921
971
|
saveToWorkspaceHint: "每次生成后,把图片文件保存到当前会话工作区。",
|
|
922
972
|
folder: "工作区文件夹",
|
|
@@ -946,6 +996,7 @@ window.__ModuleLoader__.load({
|
|
|
946
996
|
providerOpenAI: "OpenAI / Relay",
|
|
947
997
|
providerSeedream: "ByteDance Seedream",
|
|
948
998
|
providerDashScope: "Aliyun DashScope (Wanx / Qwen)",
|
|
999
|
+
providerComfyUI: "Local ComfyUI",
|
|
949
1000
|
apiKeyLabel: "{provider} API Key",
|
|
950
1001
|
apiKeyPlaceholder: "Leave empty to keep configured key",
|
|
951
1002
|
apiKeyHint: "Securely saved as {key}; never read back in plaintext.",
|
|
@@ -956,7 +1007,17 @@ window.__ModuleLoader__.load({
|
|
|
956
1007
|
endpointHintOpenAI: "OpenAI-compatible /v1 base URL for relays.",
|
|
957
1008
|
endpointHintSeedream: "Volcengine Ark compatible /api/v3 base URL.",
|
|
958
1009
|
endpointHintDashScope: "Official Aliyun DashScope endpoint.",
|
|
1010
|
+
endpointHintComfyUI: "A running ComfyUI server reachable by the DSH Host; the default points to port 8188 on this computer.",
|
|
959
1011
|
model: "Model",
|
|
1012
|
+
workflow: "API Workflow",
|
|
1013
|
+
workflowImport: "Import JSON file",
|
|
1014
|
+
workflowReplace: "Replace JSON file",
|
|
1015
|
+
workflowMissing: "No workflow imported",
|
|
1016
|
+
workflowImported: "Imported {name}",
|
|
1017
|
+
workflowHint: "Export an API Format JSON from ComfyUI and place {{prompt}} in its prompt input. {{seed}} is available for a random seed.",
|
|
1018
|
+
workflowTooLarge: "Workflow files must be no larger than 5 MB.",
|
|
1019
|
+
timeout: "Generation timeout (seconds)",
|
|
1020
|
+
timeoutHint: "Covers submission, waiting, and image download; defaults to 300 seconds.",
|
|
960
1021
|
saveToWorkspace: "Save to workspace",
|
|
961
1022
|
saveToWorkspaceHint: "Write each generated image as a file into the session workspace.",
|
|
962
1023
|
folder: "Workspace folder",
|
|
@@ -996,6 +1057,12 @@ window.__ModuleLoader__.load({
|
|
|
996
1057
|
.dsh-ig-input{box-sizing:border-box;width:100%;padding:8px 12px;font-size:13px;border:1px solid var(--dsw-alias-border-l2,#d7dbe0);border-radius:8px;background:var(--dsw-alias-bg-layer-3,transparent);color:inherit;outline:none;transition:border-color .15s}
|
|
997
1058
|
.dsh-ig-input:focus{border-color:var(--dsw-alias-brand-primary,#4c78ff)}
|
|
998
1059
|
.dsh-ig-input-group{display:flex;gap:8px;align-items:center}
|
|
1060
|
+
.dsh-ig-file-row{display:flex;align-items:center;gap:10px;min-width:0}
|
|
1061
|
+
.dsh-ig-file-input{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;clip-path:inset(50%)}
|
|
1062
|
+
.dsh-ig-file-button{appearance:none;flex:none;border:1px solid var(--dsw-alias-border-l2,#d7dbe0);border-radius:8px;padding:7px 12px;background:var(--dsw-alias-bg-layer-3,#f9fafb);color:var(--dsw-alias-label-secondary,inherit);font-size:13px;cursor:pointer;transition:background .15s,border-color .15s}
|
|
1063
|
+
.dsh-ig-file-button:hover{background:var(--dsw-alias-bg-layer-2,#edf0f3);border-color:var(--dsw-alias-label-dimmed,#9ca3af)}
|
|
1064
|
+
.dsh-ig-file-button:focus-within{outline:2px solid var(--dsw-alias-brand-primary,#4c78ff);outline-offset:2px}
|
|
1065
|
+
.dsh-ig-file-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-secondary,inherit);font-size:12px}
|
|
999
1066
|
.dsh-ig-btn-reset{appearance:none;border:1px solid var(--dsw-alias-border-l2,#d7dbe0);border-radius:8px;padding:7px 12px;background:var(--dsw-alias-bg-layer-3,#f9fafb);color:var(--dsw-alias-label-secondary,inherit);font:inherit;font-size:13px;cursor:pointer;white-space:nowrap;transition:background .15s,border-color .15s}
|
|
1000
1067
|
.dsh-ig-btn-reset:hover{background:var(--dsw-alias-bg-layer-2,#edf0f3);border-color:var(--dsw-alias-label-dimmed,#9ca3af)}
|
|
1001
1068
|
.dsh-ig-hint,.dsh-ig-status{margin:0;color:var(--dsw-alias-label-tertiary,#7b818b);font-size:12px;line-height:1.4}
|
|
@@ -1078,16 +1145,16 @@ window.__ModuleLoader__.load({
|
|
|
1078
1145
|
/** Required browser services. */
|
|
1079
1146
|
const inject = [
|
|
1080
1147
|
"slots",
|
|
1081
|
-
"connection",
|
|
1082
1148
|
"remote",
|
|
1149
|
+
"remote.credentials",
|
|
1083
1150
|
"settingsScope",
|
|
1084
1151
|
"locale"
|
|
1085
1152
|
];
|
|
1086
1153
|
/** Mount the settings card, generated-image card, and native conversation gallery view. */
|
|
1087
1154
|
function apply(ctx) {
|
|
1088
|
-
const { api } = ctx.get("connection");
|
|
1089
1155
|
const scope = ctx.settingsScope.bind({ namespace: IMAGE_GENERATION_NAMESPACE });
|
|
1090
1156
|
const locale = ctx.get("locale");
|
|
1157
|
+
const credentials = ctx.remote.credentials;
|
|
1091
1158
|
ctx.effect(() => {
|
|
1092
1159
|
const style = document.createElement("style");
|
|
1093
1160
|
style.dataset.plugin = "dsh-image-gen";
|
|
@@ -1103,7 +1170,7 @@ window.__ModuleLoader__.load({
|
|
|
1103
1170
|
key: IMAGE_GENERATION_NAMESPACE,
|
|
1104
1171
|
inject: () => ({
|
|
1105
1172
|
scope,
|
|
1106
|
-
credentials
|
|
1173
|
+
credentials,
|
|
1107
1174
|
locale
|
|
1108
1175
|
})
|
|
1109
1176
|
}, ImageGenerationSettingsCard));
|
|
@@ -1135,6 +1202,9 @@ window.__ModuleLoader__.load({
|
|
|
1135
1202
|
const [provider, setProvider] = (0, react.useState)("google");
|
|
1136
1203
|
const [model, setModel] = (0, react.useState)("");
|
|
1137
1204
|
const [baseURL, setBaseURL] = (0, react.useState)("");
|
|
1205
|
+
const [workflowJson, setWorkflowJson] = (0, react.useState)("");
|
|
1206
|
+
const [workflowName, setWorkflowName] = (0, react.useState)("");
|
|
1207
|
+
const [timeoutSeconds, setTimeoutSeconds] = (0, react.useState)(DEFAULT_COMFYUI_TIMEOUT_MS / 1e3);
|
|
1138
1208
|
const [saveToWorkspace, setSaveToWorkspace] = (0, react.useState)(true);
|
|
1139
1209
|
const [workspaceFolder, setWorkspaceFolder] = (0, react.useState)("dsh-image-gen");
|
|
1140
1210
|
const [key, setKey] = (0, react.useState)("");
|
|
@@ -1158,7 +1228,8 @@ window.__ModuleLoader__.load({
|
|
|
1158
1228
|
google: t("providerGoogle"),
|
|
1159
1229
|
openai: t("providerOpenAI"),
|
|
1160
1230
|
seedream: t("providerSeedream"),
|
|
1161
|
-
dashscope: t("providerDashScope")
|
|
1231
|
+
dashscope: t("providerDashScope"),
|
|
1232
|
+
comfyui: t("providerComfyUI")
|
|
1162
1233
|
};
|
|
1163
1234
|
(0, react.useEffect)(() => {
|
|
1164
1235
|
const value = snapshot.value;
|
|
@@ -1166,13 +1237,21 @@ window.__ModuleLoader__.load({
|
|
|
1166
1237
|
setProvider(next);
|
|
1167
1238
|
setModel(modelOf(next, value));
|
|
1168
1239
|
setBaseURL(baseURLOf(next, value));
|
|
1240
|
+
setWorkflowJson(value?.comfyuiWorkflowJson ?? "");
|
|
1241
|
+
setWorkflowName(value?.comfyuiWorkflowName ?? "");
|
|
1242
|
+
setTimeoutSeconds(Math.max(1, Math.round((value?.comfyuiTimeoutMs ?? 3e5) / 1e3)));
|
|
1169
1243
|
setSaveToWorkspace(value?.saveToWorkspace ?? true);
|
|
1170
1244
|
setWorkspaceFolder(value?.workspaceFolder ?? "dsh-image-gen");
|
|
1171
1245
|
}, [snapshot]);
|
|
1172
1246
|
(0, react.useEffect)(() => {
|
|
1247
|
+
const keyRef = KEY_REF[provider];
|
|
1248
|
+
if (keyRef === void 0) {
|
|
1249
|
+
setConfigured(void 0);
|
|
1250
|
+
return;
|
|
1251
|
+
}
|
|
1173
1252
|
let active = true;
|
|
1174
|
-
props.credentials.describe(
|
|
1175
|
-
if (active) setConfigured(response.
|
|
1253
|
+
props.credentials.describe([keyRef]).then((response) => {
|
|
1254
|
+
if (active) setConfigured(response.ok ? response.value?.[keyRef]?.configured ?? false : void 0);
|
|
1176
1255
|
}).catch(() => {
|
|
1177
1256
|
if (active) setConfigured(void 0);
|
|
1178
1257
|
});
|
|
@@ -1186,16 +1265,23 @@ window.__ModuleLoader__.load({
|
|
|
1186
1265
|
setMessage("");
|
|
1187
1266
|
try {
|
|
1188
1267
|
await props.scope.set("provider", provider);
|
|
1189
|
-
|
|
1190
|
-
|
|
1268
|
+
if (provider === "comfyui") {
|
|
1269
|
+
validateComfyUIWorkflowJson(workflowJson);
|
|
1270
|
+
await props.scope.set("comfyuiBaseURL", baseURL);
|
|
1271
|
+
await props.scope.set("comfyuiWorkflowJson", workflowJson);
|
|
1272
|
+
await props.scope.set("comfyuiWorkflowName", workflowName);
|
|
1273
|
+
await props.scope.set("comfyuiTimeoutMs", Math.max(1, Math.round(timeoutSeconds)) * 1e3);
|
|
1274
|
+
} else {
|
|
1275
|
+
await props.scope.set(provider === "google" ? "googleModel" : provider === "openai" ? "openaiModel" : provider === "seedream" ? "seedreamModel" : "dashscopeModel", model);
|
|
1276
|
+
await props.scope.set(provider === "google" ? "googleEndpoint" : provider === "openai" ? "openaiBaseURL" : provider === "seedream" ? "seedreamBaseURL" : "dashscopeEndpoint", baseURL);
|
|
1277
|
+
}
|
|
1191
1278
|
await props.scope.set("saveToWorkspace", saveToWorkspace);
|
|
1192
1279
|
await props.scope.set("workspaceFolder", workspaceFolder.trim());
|
|
1193
1280
|
if (key.trim().length > 0) {
|
|
1194
|
-
const
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
if (!response.result.ok) throw new Error(response.result.error.message);
|
|
1281
|
+
const keyRef = KEY_REF[provider];
|
|
1282
|
+
if (keyRef === void 0) throw new Error("ComfyUI does not use an API key in this version");
|
|
1283
|
+
const response = await props.credentials.set(keyRef, key.trim());
|
|
1284
|
+
if (!response.ok) throw new Error(response.error?.message ?? "Failed to save API key");
|
|
1199
1285
|
setKey("");
|
|
1200
1286
|
setConfigured(true);
|
|
1201
1287
|
}
|
|
@@ -1207,6 +1293,23 @@ window.__ModuleLoader__.load({
|
|
|
1207
1293
|
}
|
|
1208
1294
|
};
|
|
1209
1295
|
const keyStatus = configured === void 0 ? t("checkingKey") : configured ? t("keyConfigured") : t("keyNotConfigured");
|
|
1296
|
+
const workflowStatus = workflowName.length > 0 ? t("workflowImported", { name: workflowName }) : t("workflowMissing");
|
|
1297
|
+
const importWorkflow = async (event) => {
|
|
1298
|
+
const file = event.target.files?.[0];
|
|
1299
|
+
event.target.value = "";
|
|
1300
|
+
if (file === void 0) return;
|
|
1301
|
+
setMessage("");
|
|
1302
|
+
try {
|
|
1303
|
+
if (file.size > 5242880) throw new Error(t("workflowTooLarge"));
|
|
1304
|
+
const json = await file.text();
|
|
1305
|
+
validateComfyUIWorkflowJson(json);
|
|
1306
|
+
setWorkflowJson(json);
|
|
1307
|
+
setWorkflowName(file.name);
|
|
1308
|
+
setMessage(t("workflowImported", { name: file.name }));
|
|
1309
|
+
} catch (cause) {
|
|
1310
|
+
setMessage(cause instanceof Error ? cause.message : String(cause));
|
|
1311
|
+
}
|
|
1312
|
+
};
|
|
1210
1313
|
return (0, react_jsx_runtime.jsxs)("li", {
|
|
1211
1314
|
className: `dsh-ig-card ${open ? "dsh-ig-card-open" : ""}`,
|
|
1212
1315
|
children: [(0, react_jsx_runtime.jsxs)("button", {
|
|
@@ -1279,6 +1382,10 @@ window.__ModuleLoader__.load({
|
|
|
1279
1382
|
(0, react_jsx_runtime.jsx)("option", {
|
|
1280
1383
|
value: "dashscope",
|
|
1281
1384
|
children: t("providerDashScope")
|
|
1385
|
+
}),
|
|
1386
|
+
(0, react_jsx_runtime.jsx)("option", {
|
|
1387
|
+
value: "comfyui",
|
|
1388
|
+
children: t("providerComfyUI")
|
|
1282
1389
|
})
|
|
1283
1390
|
]
|
|
1284
1391
|
}),
|
|
@@ -1288,7 +1395,7 @@ window.__ModuleLoader__.load({
|
|
|
1288
1395
|
})
|
|
1289
1396
|
]
|
|
1290
1397
|
}),
|
|
1291
|
-
(0, react_jsx_runtime.jsxs)("label", {
|
|
1398
|
+
provider !== "comfyui" ? (0, react_jsx_runtime.jsxs)("label", {
|
|
1292
1399
|
className: "dsh-ig-field",
|
|
1293
1400
|
children: [
|
|
1294
1401
|
(0, react_jsx_runtime.jsx)("span", {
|
|
@@ -1307,10 +1414,10 @@ window.__ModuleLoader__.load({
|
|
|
1307
1414
|
}),
|
|
1308
1415
|
(0, react_jsx_runtime.jsx)("span", {
|
|
1309
1416
|
className: "dsh-ig-hint",
|
|
1310
|
-
children: t("apiKeyHint", { key: KEY_REF[provider] })
|
|
1417
|
+
children: t("apiKeyHint", { key: KEY_REF[provider] ?? "" })
|
|
1311
1418
|
})
|
|
1312
1419
|
]
|
|
1313
|
-
}),
|
|
1420
|
+
}) : null,
|
|
1314
1421
|
(0, react_jsx_runtime.jsxs)("label", {
|
|
1315
1422
|
className: "dsh-ig-field",
|
|
1316
1423
|
children: [
|
|
@@ -1340,11 +1447,11 @@ window.__ModuleLoader__.load({
|
|
|
1340
1447
|
}),
|
|
1341
1448
|
(0, react_jsx_runtime.jsx)("span", {
|
|
1342
1449
|
className: "dsh-ig-hint",
|
|
1343
|
-
children: provider === "google" ? t("endpointHintGoogle") : provider === "openai" ? t("endpointHintOpenAI") : provider === "seedream" ? t("endpointHintSeedream") : t("endpointHintDashScope")
|
|
1450
|
+
children: provider === "google" ? t("endpointHintGoogle") : provider === "openai" ? t("endpointHintOpenAI") : provider === "seedream" ? t("endpointHintSeedream") : provider === "dashscope" ? t("endpointHintDashScope") : t("endpointHintComfyUI")
|
|
1344
1451
|
})
|
|
1345
1452
|
]
|
|
1346
1453
|
}),
|
|
1347
|
-
(0, react_jsx_runtime.jsxs)("label", {
|
|
1454
|
+
provider !== "comfyui" ? (0, react_jsx_runtime.jsxs)("label", {
|
|
1348
1455
|
className: "dsh-ig-field",
|
|
1349
1456
|
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
1350
1457
|
className: "dsh-ig-label",
|
|
@@ -1357,7 +1464,61 @@ window.__ModuleLoader__.load({
|
|
|
1357
1464
|
},
|
|
1358
1465
|
required: true
|
|
1359
1466
|
})]
|
|
1360
|
-
}),
|
|
1467
|
+
}) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
1468
|
+
className: "dsh-ig-field",
|
|
1469
|
+
children: [
|
|
1470
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
1471
|
+
className: "dsh-ig-label",
|
|
1472
|
+
children: t("workflow")
|
|
1473
|
+
}),
|
|
1474
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
1475
|
+
className: "dsh-ig-file-row",
|
|
1476
|
+
children: [(0, react_jsx_runtime.jsxs)("label", {
|
|
1477
|
+
className: "dsh-ig-file-button",
|
|
1478
|
+
children: [(0, react_jsx_runtime.jsx)("input", {
|
|
1479
|
+
className: "dsh-ig-file-input",
|
|
1480
|
+
type: "file",
|
|
1481
|
+
accept: ".json,application/json",
|
|
1482
|
+
onChange: (event) => {
|
|
1483
|
+
importWorkflow(event);
|
|
1484
|
+
}
|
|
1485
|
+
}), workflowName.length > 0 ? t("workflowReplace") : t("workflowImport")]
|
|
1486
|
+
}), (0, react_jsx_runtime.jsx)("span", {
|
|
1487
|
+
className: "dsh-ig-file-name",
|
|
1488
|
+
title: workflowName,
|
|
1489
|
+
children: workflowName || t("workflowMissing")
|
|
1490
|
+
})]
|
|
1491
|
+
}),
|
|
1492
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
1493
|
+
className: "dsh-ig-hint",
|
|
1494
|
+
children: t("workflowHint")
|
|
1495
|
+
})
|
|
1496
|
+
]
|
|
1497
|
+
}), (0, react_jsx_runtime.jsxs)("label", {
|
|
1498
|
+
className: "dsh-ig-field",
|
|
1499
|
+
children: [
|
|
1500
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
1501
|
+
className: "dsh-ig-label",
|
|
1502
|
+
children: t("timeout")
|
|
1503
|
+
}),
|
|
1504
|
+
(0, react_jsx_runtime.jsx)("input", {
|
|
1505
|
+
className: "dsh-ig-input",
|
|
1506
|
+
type: "number",
|
|
1507
|
+
min: "1",
|
|
1508
|
+
max: "3600",
|
|
1509
|
+
step: "1",
|
|
1510
|
+
value: timeoutSeconds,
|
|
1511
|
+
onChange: (event) => {
|
|
1512
|
+
setTimeoutSeconds(Number(event.target.value));
|
|
1513
|
+
},
|
|
1514
|
+
required: true
|
|
1515
|
+
}),
|
|
1516
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
1517
|
+
className: "dsh-ig-hint",
|
|
1518
|
+
children: t("timeoutHint")
|
|
1519
|
+
})
|
|
1520
|
+
]
|
|
1521
|
+
})] }),
|
|
1361
1522
|
(0, react_jsx_runtime.jsxs)("div", {
|
|
1362
1523
|
className: "dsh-ig-field",
|
|
1363
1524
|
children: [(0, react_jsx_runtime.jsxs)("label", {
|
|
@@ -1403,11 +1564,11 @@ window.__ModuleLoader__.load({
|
|
|
1403
1564
|
children: [(0, react_jsx_runtime.jsx)("p", {
|
|
1404
1565
|
className: "dsh-ig-status",
|
|
1405
1566
|
role: "status",
|
|
1406
|
-
children: message || keyStatus
|
|
1567
|
+
children: message || (provider === "comfyui" ? workflowStatus : keyStatus)
|
|
1407
1568
|
}), (0, react_jsx_runtime.jsx)("button", {
|
|
1408
1569
|
className: "dsh-ig-save",
|
|
1409
1570
|
type: "submit",
|
|
1410
|
-
disabled: saving || !snapshot.writable,
|
|
1571
|
+
disabled: saving || !snapshot.writable || provider === "comfyui" && workflowJson.length === 0,
|
|
1411
1572
|
children: saving ? t("saving") : t("save")
|
|
1412
1573
|
})]
|
|
1413
1574
|
})
|
|
@@ -1656,11 +1817,11 @@ window.__ModuleLoader__.load({
|
|
|
1656
1817
|
});
|
|
1657
1818
|
}
|
|
1658
1819
|
function modelOf(provider, value) {
|
|
1659
|
-
const stored = provider === "google" ? value?.googleModel : provider === "openai" ? value?.openaiModel : provider === "seedream" ? value?.seedreamModel : value?.dashscopeModel;
|
|
1820
|
+
const stored = provider === "google" ? value?.googleModel : provider === "openai" ? value?.openaiModel : provider === "seedream" ? value?.seedreamModel : provider === "dashscope" ? value?.dashscopeModel : value?.comfyuiWorkflowName;
|
|
1660
1821
|
return typeof stored === "string" && stored.length > 0 ? stored : DEFAULT_MODELS[provider];
|
|
1661
1822
|
}
|
|
1662
1823
|
function baseURLOf(provider, value) {
|
|
1663
|
-
const stored = provider === "google" ? value?.googleEndpoint : provider === "openai" ? value?.openaiBaseURL : provider === "seedream" ? value?.seedreamBaseURL : value?.dashscopeEndpoint;
|
|
1824
|
+
const stored = provider === "google" ? value?.googleEndpoint : provider === "openai" ? value?.openaiBaseURL : provider === "seedream" ? value?.seedreamBaseURL : provider === "dashscope" ? value?.dashscopeEndpoint : value?.comfyuiBaseURL;
|
|
1664
1825
|
return typeof stored === "string" && stored.length > 0 ? stored : DEFAULT_BASE_URLS[provider];
|
|
1665
1826
|
}
|
|
1666
1827
|
function imageRef(block) {
|