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/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: api.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({ refs: [KEY_REF[provider]] }).then((response) => {
1175
- if (active) setConfigured(response.result.ok ? response.result.value.credentials[KEY_REF[provider]]?.configured ?? false : void 0);
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
- await props.scope.set(provider === "google" ? "googleModel" : provider === "openai" ? "openaiModel" : provider === "seedream" ? "seedreamModel" : "dashscopeModel", model);
1190
- await props.scope.set(provider === "google" ? "googleEndpoint" : provider === "openai" ? "openaiBaseURL" : provider === "seedream" ? "seedreamBaseURL" : "dashscopeEndpoint", baseURL);
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 response = await props.credentials.set({
1195
- ref: KEY_REF[provider],
1196
- value: key.trim()
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) {