dsh-image-gen 0.6.1 → 0.6.5
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 +12 -2
- package/README.md +13 -3
- package/lib/client.js +548 -21
- package/lib/client.js.map +1 -1
- package/lib/index.js +1421 -103
- package/lib/types/client/index.d.ts +4 -0
- package/lib/types/client/provider-pill.d.ts +1 -1
- package/lib/types/client/tl/diagram-landing.d.ts +75 -0
- package/lib/types/client/tl/diagram-layout.d.ts +76 -0
- package/lib/types/client/tl/diagram-measure.d.ts +40 -0
- package/lib/types/config.d.ts +24 -0
- package/lib/types/diagram.d.ts +42 -0
- package/lib/types/openai-compatible.d.ts +15 -0
- package/lib/types/shared.d.ts +16 -1
- package/lib/types/subscription/blob.d.ts +23 -0
- package/lib/types/subscription/loopback.d.ts +11 -0
- package/lib/types/subscription/manager.d.ts +94 -0
- package/lib/types/subscription/oauth.d.ts +25 -0
- package/lib/types/subscription/subscription-route.d.ts +5 -0
- package/lib/types/subscription/vendors/antigravity.d.ts +66 -0
- package/lib/types/subscription/vendors/codex.d.ts +30 -0
- package/lib/types/subscription/vendors/grok.d.ts +32 -0
- package/lib/types/subscription.d.ts +42 -0
- package/lib/types/test-route.d.ts +9 -0
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -87,6 +87,8 @@ window.__ModuleLoader__.load({
|
|
|
87
87
|
const TEST_CONNECTION_ROUTE = "/plugins/dsh-image-gen/test";
|
|
88
88
|
/** Browser route the workbench infinite canvas pushes live state through. */
|
|
89
89
|
const CANVAS_STATE_ROUTE = "/plugins/dsh-image-gen/canvas-state";
|
|
90
|
+
const SUBSCRIPTION_LOGIN_ROUTE = "/plugins/dsh-image-gen/subscription-login";
|
|
91
|
+
const SUBSCRIPTION_STATUS_ROUTE = "/plugins/dsh-image-gen/subscription-status";
|
|
90
92
|
/** Namespace persisted through DSH Settings. */
|
|
91
93
|
const IMAGE_GENERATION_NAMESPACE = "image-generation";
|
|
92
94
|
/** Supported providers. */
|
|
@@ -98,8 +100,25 @@ window.__ModuleLoader__.load({
|
|
|
98
100
|
"dashscope",
|
|
99
101
|
"xai",
|
|
100
102
|
"zhipu",
|
|
101
|
-
"comfyui"
|
|
103
|
+
"comfyui",
|
|
104
|
+
"chatgpt-sub",
|
|
105
|
+
"grok-sub",
|
|
106
|
+
"google-sub"
|
|
102
107
|
];
|
|
108
|
+
/**
|
|
109
|
+
* Providers that generate through a logged-in subscription account instead
|
|
110
|
+
* of an API key. They use no credential reference and never join the
|
|
111
|
+
* cloud/BYOK sets.
|
|
112
|
+
*/
|
|
113
|
+
const SUBSCRIPTION_PROVIDERS = [
|
|
114
|
+
"chatgpt-sub",
|
|
115
|
+
"grok-sub",
|
|
116
|
+
"google-sub"
|
|
117
|
+
];
|
|
118
|
+
/** True when the provider generates through a logged-in subscription account. */
|
|
119
|
+
function isSubscriptionProvider(provider) {
|
|
120
|
+
return SUBSCRIPTION_PROVIDERS.includes(provider);
|
|
121
|
+
}
|
|
103
122
|
/** Providers supported by the first browser workbench release. */
|
|
104
123
|
const CLOUD_IMAGE_PROVIDERS = [
|
|
105
124
|
"google",
|
|
@@ -184,6 +203,12 @@ window.__ModuleLoader__.load({
|
|
|
184
203
|
if (!existing.includes(candidate)) return candidate;
|
|
185
204
|
}
|
|
186
205
|
}
|
|
206
|
+
/** Default models for the subscription channels; fixed by the bridge protocol. */
|
|
207
|
+
const DEFAULT_SUBSCRIPTION_MODELS = {
|
|
208
|
+
"chatgpt-sub": "gpt-image-2.5-flare",
|
|
209
|
+
"grok-sub": "grok-imagine-image-2.0",
|
|
210
|
+
"google-sub": "gemini-3-pro-image"
|
|
211
|
+
};
|
|
187
212
|
const DEFAULT_MODELS = {
|
|
188
213
|
google: DEFAULT_GOOGLE_MODEL,
|
|
189
214
|
openai: DEFAULT_OPENAI_MODEL,
|
|
@@ -192,7 +217,10 @@ window.__ModuleLoader__.load({
|
|
|
192
217
|
dashscope: DEFAULT_DASHSCOPE_MODEL,
|
|
193
218
|
xai: DEFAULT_XAI_MODEL,
|
|
194
219
|
zhipu: DEFAULT_ZHIPU_MODEL,
|
|
195
|
-
comfyui: DEFAULT_COMFYUI_WORKFLOW_LABEL
|
|
220
|
+
comfyui: DEFAULT_COMFYUI_WORKFLOW_LABEL,
|
|
221
|
+
"chatgpt-sub": DEFAULT_SUBSCRIPTION_MODELS["chatgpt-sub"],
|
|
222
|
+
"grok-sub": DEFAULT_SUBSCRIPTION_MODELS["grok-sub"],
|
|
223
|
+
"google-sub": DEFAULT_SUBSCRIPTION_MODELS["google-sub"]
|
|
196
224
|
};
|
|
197
225
|
const DEFAULT_BASE_URLS = {
|
|
198
226
|
google: DEFAULT_GOOGLE_ENDPOINT,
|
|
@@ -202,7 +230,10 @@ window.__ModuleLoader__.load({
|
|
|
202
230
|
dashscope: DEFAULT_DASHSCOPE_ENDPOINT,
|
|
203
231
|
xai: DEFAULT_XAI_BASE_URL,
|
|
204
232
|
zhipu: DEFAULT_ZHIPU_BASE_URL,
|
|
205
|
-
comfyui: DEFAULT_COMFYUI_BASE_URL
|
|
233
|
+
comfyui: DEFAULT_COMFYUI_BASE_URL,
|
|
234
|
+
"chatgpt-sub": "",
|
|
235
|
+
"grok-sub": "",
|
|
236
|
+
"google-sub": ""
|
|
206
237
|
};
|
|
207
238
|
//#endregion
|
|
208
239
|
//#region lib/types/comfyui-workflow.js
|
|
@@ -121322,6 +121353,10 @@ img.ProseMirror-separator {
|
|
|
121322
121353
|
keyMissing: "未配置 Key",
|
|
121323
121354
|
noKeyNeeded: "无需 Key",
|
|
121324
121355
|
noWorkflow: "未导入工作流",
|
|
121356
|
+
subNoKey: "订阅生图",
|
|
121357
|
+
subSignedIn: "已登录",
|
|
121358
|
+
subSignedOut: "未登录",
|
|
121359
|
+
subStatusUnknown: "状态未知",
|
|
121325
121360
|
readOnly: "图像设置为只读,无法在此切换",
|
|
121326
121361
|
switchFailed: "切换失败"
|
|
121327
121362
|
},
|
|
@@ -121332,6 +121367,10 @@ img.ProseMirror-separator {
|
|
|
121332
121367
|
keyMissing: "No key",
|
|
121333
121368
|
noKeyNeeded: "No key needed",
|
|
121334
121369
|
noWorkflow: "No workflow",
|
|
121370
|
+
subNoKey: "Subscription",
|
|
121371
|
+
subSignedIn: "Signed in",
|
|
121372
|
+
subSignedOut: "Signed out",
|
|
121373
|
+
subStatusUnknown: "Unknown",
|
|
121335
121374
|
readOnly: "Image settings are read-only; switch them in the config source",
|
|
121336
121375
|
switchFailed: "Switch failed"
|
|
121337
121376
|
}
|
|
@@ -121345,8 +121384,25 @@ img.ProseMirror-separator {
|
|
|
121345
121384
|
dashscope: "DashScope",
|
|
121346
121385
|
xai: "Grok",
|
|
121347
121386
|
zhipu: "智谱 GLM",
|
|
121348
|
-
comfyui: "ComfyUI"
|
|
121349
|
-
|
|
121387
|
+
comfyui: "ComfyUI",
|
|
121388
|
+
"chatgpt-sub": "ChatGPT 订阅",
|
|
121389
|
+
"grok-sub": "Grok 订阅",
|
|
121390
|
+
"google-sub": "Google 订阅"
|
|
121391
|
+
};
|
|
121392
|
+
/** Compute the fixed-position anchor from the pill button: open upward when
|
|
121393
|
+
* the chat pane leaves room above the composer, drop down otherwise. */
|
|
121394
|
+
function anchorOf(button) {
|
|
121395
|
+
const rect = button?.getBoundingClientRect();
|
|
121396
|
+
if (rect === void 0) return void 0;
|
|
121397
|
+
if (rect.top >= 332) return {
|
|
121398
|
+
left: rect.left,
|
|
121399
|
+
bottom: window.innerHeight - rect.top + 6
|
|
121400
|
+
};
|
|
121401
|
+
return {
|
|
121402
|
+
left: rect.left,
|
|
121403
|
+
top: rect.bottom + 6
|
|
121404
|
+
};
|
|
121405
|
+
}
|
|
121350
121406
|
/** Whether the user opted into the composer pill; hidden (not merely inert) when off. */
|
|
121351
121407
|
function pillVisible(value) {
|
|
121352
121408
|
return value?.showProviderPill === true;
|
|
@@ -121357,6 +121413,7 @@ img.ProseMirror-separator {
|
|
|
121357
121413
|
const workflow = activeComfyUIWorkflow(value ?? {});
|
|
121358
121414
|
return workflow === void 0 ? "" : workflow.name;
|
|
121359
121415
|
}
|
|
121416
|
+
if (SUBSCRIPTION_PROVIDERS.includes(provider)) return DEFAULT_MODELS[provider];
|
|
121360
121417
|
const stored = provider === "google" ? value?.googleModel : provider === "openai" ? value?.openaiModel : provider === "openai-compat" ? value?.openaiCompatModel : provider === "seedream" ? value?.seedreamModel : provider === "dashscope" ? value?.dashscopeModel : provider === "xai" ? value?.xaiModel : value?.zhipuModel;
|
|
121361
121418
|
return typeof stored === "string" && stored.length > 0 ? stored : DEFAULT_MODELS[provider];
|
|
121362
121419
|
}
|
|
@@ -121377,6 +121434,11 @@ img.ProseMirror-separator {
|
|
|
121377
121434
|
zhipu: "unknown"
|
|
121378
121435
|
});
|
|
121379
121436
|
const [keyTick, setKeyTick] = (0, react.useState)(0);
|
|
121437
|
+
const [subDots, setSubDots] = (0, react.useState)(() => ({
|
|
121438
|
+
"chatgpt-sub": "unknown",
|
|
121439
|
+
"grok-sub": "unknown",
|
|
121440
|
+
"google-sub": "unknown"
|
|
121441
|
+
}));
|
|
121380
121442
|
const buttonRef = (0, react.useRef)(null);
|
|
121381
121443
|
const [menuStyle, setMenuStyle] = (0, react.useState)(null);
|
|
121382
121444
|
(0, react.useEffect)(() => props.scope.subscribe(() => {
|
|
@@ -121419,6 +121481,31 @@ img.ProseMirror-separator {
|
|
|
121419
121481
|
active = false;
|
|
121420
121482
|
};
|
|
121421
121483
|
}, [props.credentials, keyTick]);
|
|
121484
|
+
(0, react.useEffect)(() => {
|
|
121485
|
+
if (!open) return;
|
|
121486
|
+
let active = true;
|
|
121487
|
+
const probe = async () => {
|
|
121488
|
+
try {
|
|
121489
|
+
const response = await fetch(SUBSCRIPTION_STATUS_ROUTE, {
|
|
121490
|
+
method: "POST",
|
|
121491
|
+
cache: "no-store"
|
|
121492
|
+
});
|
|
121493
|
+
if (!active || !response.ok) return;
|
|
121494
|
+
const payload = await response.json();
|
|
121495
|
+
if (!active || payload.statuses === void 0) return;
|
|
121496
|
+
const next = {};
|
|
121497
|
+
for (const provider of SUBSCRIPTION_PROVIDERS) {
|
|
121498
|
+
const row = payload.statuses[provider];
|
|
121499
|
+
next[provider] = row?.state === "logged-in" ? "logged-in" : row?.state === "logged-out" ? "logged-out" : "unknown";
|
|
121500
|
+
}
|
|
121501
|
+
setSubDots(next);
|
|
121502
|
+
} catch {}
|
|
121503
|
+
};
|
|
121504
|
+
probe();
|
|
121505
|
+
return () => {
|
|
121506
|
+
active = false;
|
|
121507
|
+
};
|
|
121508
|
+
}, [open, keyTick]);
|
|
121422
121509
|
const t = (keyName) => (lang === "en" ? PILL_DICT.en : PILL_DICT.zh)[keyName];
|
|
121423
121510
|
const current = snapshot.value?.provider ?? "google";
|
|
121424
121511
|
const writable = snapshot.writable;
|
|
@@ -121427,11 +121514,15 @@ img.ProseMirror-separator {
|
|
|
121427
121514
|
setMenuStyle(null);
|
|
121428
121515
|
return;
|
|
121429
121516
|
}
|
|
121430
|
-
const
|
|
121431
|
-
|
|
121432
|
-
|
|
121433
|
-
|
|
121434
|
-
|
|
121517
|
+
const anchor = () => {
|
|
121518
|
+
const next = anchorOf(buttonRef.current);
|
|
121519
|
+
if (next !== void 0) setMenuStyle(next);
|
|
121520
|
+
};
|
|
121521
|
+
anchor();
|
|
121522
|
+
window.addEventListener("resize", anchor);
|
|
121523
|
+
return () => {
|
|
121524
|
+
window.removeEventListener("resize", anchor);
|
|
121525
|
+
};
|
|
121435
121526
|
}, [open]);
|
|
121436
121527
|
(0, react.useEffect)(() => {
|
|
121437
121528
|
if (!open) return;
|
|
@@ -121442,8 +121533,15 @@ img.ProseMirror-separator {
|
|
|
121442
121533
|
const onKeyDown = (event) => {
|
|
121443
121534
|
if (event.key === "Escape") setOpen(false);
|
|
121444
121535
|
};
|
|
121445
|
-
const onReflow = () => {
|
|
121446
|
-
|
|
121536
|
+
const onReflow = (event) => {
|
|
121537
|
+
if (event.target instanceof Element && event.target.closest(".dsh-ig-pill-menu") !== null) return;
|
|
121538
|
+
const rect = buttonRef.current?.getBoundingClientRect();
|
|
121539
|
+
if (rect !== void 0 && (rect.bottom < 0 || rect.top > window.innerHeight)) {
|
|
121540
|
+
setOpen(false);
|
|
121541
|
+
return;
|
|
121542
|
+
}
|
|
121543
|
+
const next = anchorOf(buttonRef.current);
|
|
121544
|
+
if (next !== void 0) setMenuStyle(next);
|
|
121447
121545
|
};
|
|
121448
121546
|
document.addEventListener("mousedown", onPointerDown, true);
|
|
121449
121547
|
document.addEventListener("keydown", onKeyDown, true);
|
|
@@ -121473,8 +121571,12 @@ img.ProseMirror-separator {
|
|
|
121473
121571
|
setPending(void 0);
|
|
121474
121572
|
});
|
|
121475
121573
|
};
|
|
121574
|
+
/** Plan A dots: ComfyUI is always fixed blue (theme-independent); each
|
|
121575
|
+
* subscription reflects its login state (green in, gray out); cloud rows
|
|
121576
|
+
* reflect their API-key state as before. */
|
|
121476
121577
|
const dotClassOf = (provider) => {
|
|
121477
121578
|
if (provider === "comfyui") return "dsh-ig-pill-dot-neutral";
|
|
121579
|
+
if (isSubscriptionProvider(provider)) return subDots[provider] === "logged-in" ? "dsh-ig-pill-dot-ok" : "dsh-ig-pill-dot-missing";
|
|
121478
121580
|
const dot = dots[provider];
|
|
121479
121581
|
return dot === "configured" ? "dsh-ig-pill-dot-ok" : dot === "missing" ? "dsh-ig-pill-dot-missing" : "dsh-ig-pill-dot-neutral";
|
|
121480
121582
|
};
|
|
@@ -121483,6 +121585,11 @@ img.ProseMirror-separator {
|
|
|
121483
121585
|
const workflow = pillModelOf(provider, snapshot.value);
|
|
121484
121586
|
return workflow.length > 0 ? `${t("noKeyNeeded")} · ${workflow}` : `${t("noKeyNeeded")} · ${t("noWorkflow")}`;
|
|
121485
121587
|
}
|
|
121588
|
+
if (isSubscriptionProvider(provider)) {
|
|
121589
|
+
const state = subDots[provider];
|
|
121590
|
+
const stateText = state === "logged-in" ? t("subSignedIn") : state === "logged-out" ? t("subSignedOut") : t("subStatusUnknown");
|
|
121591
|
+
return `${t("subNoKey")} · ${stateText} · ${pillModelOf(provider, snapshot.value)}`;
|
|
121592
|
+
}
|
|
121486
121593
|
const dot = dots[provider];
|
|
121487
121594
|
const model = pillModelOf(provider, snapshot.value);
|
|
121488
121595
|
if (dot === "configured") return `${t("keyConfigured")} · ${model}`;
|
|
@@ -121635,8 +121742,8 @@ img.ProseMirror-separator {
|
|
|
121635
121742
|
.dsh-ig-pill-option-active{background:var(--dsw-alias-brand-primary-soft,rgba(76,120,255,.10))}
|
|
121636
121743
|
.dsh-ig-pill-dot{flex:none;width:7px;height:7px;border-radius:50%}
|
|
121637
121744
|
.dsh-ig-pill-dot-ok{background:#22c55e}
|
|
121638
|
-
.dsh-ig-pill-dot-missing{background
|
|
121639
|
-
.dsh-ig-pill-dot-neutral{background
|
|
121745
|
+
.dsh-ig-pill-dot-missing{background:#9ca3af}
|
|
121746
|
+
.dsh-ig-pill-dot-neutral{background:#4c78ff}
|
|
121640
121747
|
.dsh-ig-pill-option-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
|
|
121641
121748
|
.dsh-ig-pill-option-name{font-size:12.5px;font-weight:500;color:var(--dsw-alias-label-primary,#111827);line-height:1.2}
|
|
121642
121749
|
.dsh-ig-pill-option-sub{font-size:11px;color:var(--dsw-alias-label-tertiary,#6b7280);line-height:1.2;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
@@ -121645,7 +121752,7 @@ img.ProseMirror-separator {
|
|
|
121645
121752
|
`;
|
|
121646
121753
|
//#endregion
|
|
121647
121754
|
//#region lib/types/client/index.js
|
|
121648
|
-
console.info(`[dsh-image-gen] canvas bundle 2026-09-
|
|
121755
|
+
console.info(`[dsh-image-gen] canvas bundle 2026-09-14T00:33:35.649Z`);
|
|
121649
121756
|
/** Right-sidebar tab-type registration id (DSH 0.1.5 `sidebarRightTabs`). */
|
|
121650
121757
|
const SIDEBAR_STUDIO_TAB_ID = "dsh-image-gen/studio";
|
|
121651
121758
|
/** The tab kind: a page type opened by kind, recognizing no resource address. */
|
|
@@ -121665,6 +121772,27 @@ img.ProseMirror-separator {
|
|
|
121665
121772
|
providerXAI: "xAI Grok Imagine",
|
|
121666
121773
|
providerZhipu: "智谱 GLM-Image",
|
|
121667
121774
|
providerComfyUI: "本地 ComfyUI",
|
|
121775
|
+
providerChatGPTSub: "ChatGPT 订阅",
|
|
121776
|
+
providerGrokSub: "Grok 订阅",
|
|
121777
|
+
providerGoogleSub: "Google 订阅",
|
|
121778
|
+
subBadgeLoggedIn: "已登录",
|
|
121779
|
+
subBadgeLoggedOut: "未登录",
|
|
121780
|
+
subBadgeUnknown: "状态未知",
|
|
121781
|
+
subSectionTitle: "订阅生图",
|
|
121782
|
+
subHint: "通过已登录的订阅账号生图,无需 API Key。登录在你的授权下进行,不会修改任何 API Key 或默认 Provider。",
|
|
121783
|
+
subAccountLabel: "账号",
|
|
121784
|
+
subAccountEmail: "已登录:{email}",
|
|
121785
|
+
subAccountNone: "未登录",
|
|
121786
|
+
subLogin: "登录",
|
|
121787
|
+
subLoggingIn: "正在登录…",
|
|
121788
|
+
subLogout: "退出登录",
|
|
121789
|
+
subLoggingOut: "正在退出…",
|
|
121790
|
+
subWaitingLogin: "已打开授权页面,请在浏览器中完成登录…",
|
|
121791
|
+
subLoginOk: "登录成功",
|
|
121792
|
+
subModelLabel: "订阅模型",
|
|
121793
|
+
subModelHint: "由订阅通道固定,不可更改。",
|
|
121794
|
+
subEditUnsupported: "订阅通道暂不支持图生图(编辑图片),仅支持文字生图。",
|
|
121795
|
+
subDefaultHint: "订阅 Provider 只能生成,不能编辑图片;需要编辑时请切换到 API Key Provider。",
|
|
121668
121796
|
apiKeyLabel: "{provider} API Key",
|
|
121669
121797
|
apiKeyPlaceholder: "留空即可保留已配置的 Key",
|
|
121670
121798
|
apiKeyHint: "安全保存为 {key};页面不会读回明文。",
|
|
@@ -121692,6 +121820,14 @@ img.ProseMirror-separator {
|
|
|
121692
121820
|
endpointHintGoogle: "Google 官方地址或反代端点(全路径)。",
|
|
121693
121821
|
endpointHintOpenAI: "官方 api.openai.com 的 /v1 地址;中转站请使用下方「OpenAI 兼容」行。",
|
|
121694
121822
|
endpointHintOpenAICompat: "中转站/自建服务的 OpenAI 兼容 /v1 地址(必填),例如 https://your-relay.example.com/v1。",
|
|
121823
|
+
editFormat: "图生图请求形态",
|
|
121824
|
+
editFormatMultipart: "标准 multipart(OpenAI 官方)",
|
|
121825
|
+
editFormatJsonImageUrlArray: "JSON images 数组(商汤等中转)",
|
|
121826
|
+
editFormatHint: "文生图不受影响。仅当中转站的图生图接口使用自有 JSON 契约(如商汤 SenseNova)时才需要切换。",
|
|
121827
|
+
editExtra: "附加 JSON 字段",
|
|
121828
|
+
editExtraPlaceholder: "{\"watermark\": false, \"prompt_extend\": true}",
|
|
121829
|
+
editExtraHint: "仅 JSON 形态生效;会合并到请求体末尾,可覆盖默认字段。留空表示不附加。",
|
|
121830
|
+
editExtraInvalid: "附加 JSON 字段必须是合法的 JSON 对象。",
|
|
121695
121831
|
endpointHintSeedream: "火山方舟兼容的 /api/v3 地址。",
|
|
121696
121832
|
endpointHintDashScope: "阿里云百炼 DashScope 官方接口地址。",
|
|
121697
121833
|
endpointHintXAI: "xAI 官方 api.x.ai 的 /v1 地址。",
|
|
@@ -121765,6 +121901,27 @@ img.ProseMirror-separator {
|
|
|
121765
121901
|
providerXAI: "xAI Grok Imagine",
|
|
121766
121902
|
providerZhipu: "Zhipu GLM-Image",
|
|
121767
121903
|
providerComfyUI: "Local ComfyUI",
|
|
121904
|
+
providerChatGPTSub: "ChatGPT Subscription",
|
|
121905
|
+
providerGrokSub: "Grok Subscription",
|
|
121906
|
+
providerGoogleSub: "Google Subscription",
|
|
121907
|
+
subBadgeLoggedIn: "Signed in",
|
|
121908
|
+
subBadgeLoggedOut: "Signed out",
|
|
121909
|
+
subBadgeUnknown: "Unknown",
|
|
121910
|
+
subSectionTitle: "Subscription generation",
|
|
121911
|
+
subHint: "Generates through a logged-in subscription account; no API key needed. Signing in never changes any API key or the default provider.",
|
|
121912
|
+
subAccountLabel: "Account",
|
|
121913
|
+
subAccountEmail: "Signed in: {email}",
|
|
121914
|
+
subAccountNone: "Not signed in",
|
|
121915
|
+
subLogin: "Sign in",
|
|
121916
|
+
subLoggingIn: "Signing in…",
|
|
121917
|
+
subLogout: "Sign out",
|
|
121918
|
+
subLoggingOut: "Signing out…",
|
|
121919
|
+
subWaitingLogin: "Authorization page opened; complete sign-in in your browser…",
|
|
121920
|
+
subLoginOk: "Signed in",
|
|
121921
|
+
subModelLabel: "Subscription model",
|
|
121922
|
+
subModelHint: "Fixed by the subscription channel; not changeable.",
|
|
121923
|
+
subEditUnsupported: "The subscription channel does not support image editing yet; text-to-image only.",
|
|
121924
|
+
subDefaultHint: "Subscription providers can only generate; switch to an API-key provider for editing.",
|
|
121768
121925
|
apiKeyLabel: "{provider} API Key",
|
|
121769
121926
|
apiKeyPlaceholder: "Leave empty to keep configured key",
|
|
121770
121927
|
apiKeyHint: "Securely saved as {key}; never read back in plaintext.",
|
|
@@ -121792,6 +121949,14 @@ img.ProseMirror-separator {
|
|
|
121792
121949
|
endpointHintGoogle: "Official Google endpoint or reverse proxy (full path).",
|
|
121793
121950
|
endpointHintOpenAI: "Official api.openai.com /v1 base URL; for relays use the \"OpenAI-compatible\" row below.",
|
|
121794
121951
|
endpointHintOpenAICompat: "OpenAI-compatible /v1 base URL of your relay or self-hosted service (required), e.g. https://your-relay.example.com/v1.",
|
|
121952
|
+
editFormat: "Edit request format",
|
|
121953
|
+
editFormatMultipart: "Standard multipart (official OpenAI)",
|
|
121954
|
+
editFormatJsonImageUrlArray: "JSON images array (SenseNova etc.)",
|
|
121955
|
+
editFormatHint: "Text-to-image is unaffected. Only switch when the relay runs image edits on its own JSON contract (e.g. SenseNova); size is pinned to \"auto\" in this format (the only value SenseNova's edits endpoint accepts) and can be overridden via extra fields.",
|
|
121956
|
+
editExtra: "Extra JSON fields",
|
|
121957
|
+
editExtraPlaceholder: "{\"watermark\": false, \"prompt_extend\": true}",
|
|
121958
|
+
editExtraHint: "Only used with the JSON format; merged into the request body last and may override defaults. Leave empty for none.",
|
|
121959
|
+
editExtraInvalid: "Extra JSON fields must be a valid JSON object.",
|
|
121795
121960
|
endpointHintSeedream: "Volcengine Ark compatible /api/v3 base URL.",
|
|
121796
121961
|
endpointHintDashScope: "Official Aliyun DashScope endpoint.",
|
|
121797
121962
|
endpointHintXAI: "Official xAI api.x.ai /v1 base URL.",
|
|
@@ -121868,6 +122033,7 @@ img.ProseMirror-separator {
|
|
|
121868
122033
|
.dsh-ig-label{font-size:13px;font-weight:500;color:var(--dsw-alias-label-primary,inherit)}
|
|
121869
122034
|
.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}
|
|
121870
122035
|
.dsh-ig-input:focus{border-color:var(--dsw-alias-brand-primary,#4c78ff)}
|
|
122036
|
+
.dsh-ig-textarea{resize:vertical;min-height:56px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;line-height:1.5}
|
|
121871
122037
|
.dsh-ig-input-group{display:flex;gap:8px;align-items:center}
|
|
121872
122038
|
.dsh-ig-file-row{display:flex;align-items:center;gap:10px;min-width:0}
|
|
121873
122039
|
.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%)}
|
|
@@ -122363,7 +122529,9 @@ img.ProseMirror-separator {
|
|
|
122363
122529
|
messageIsError: false,
|
|
122364
122530
|
workflows: [],
|
|
122365
122531
|
activeWorkflow: "",
|
|
122366
|
-
timeoutSeconds: DEFAULT_COMFYUI_TIMEOUT_MS / 1e3
|
|
122532
|
+
timeoutSeconds: DEFAULT_COMFYUI_TIMEOUT_MS / 1e3,
|
|
122533
|
+
editFormat: "multipart",
|
|
122534
|
+
editExtraText: ""
|
|
122367
122535
|
};
|
|
122368
122536
|
}
|
|
122369
122537
|
/** Settings field each cloud provider persists its model under. */
|
|
@@ -122408,6 +122576,15 @@ img.ProseMirror-separator {
|
|
|
122408
122576
|
function modelPullSupported(_provider) {
|
|
122409
122577
|
return true;
|
|
122410
122578
|
}
|
|
122579
|
+
/** Serialize the extra-fields record into editor text; empty record becomes ''. */
|
|
122580
|
+
function editExtraTextOf(value) {
|
|
122581
|
+
if (value === void 0 || Object.keys(value).length === 0) return "";
|
|
122582
|
+
try {
|
|
122583
|
+
return JSON.stringify(value);
|
|
122584
|
+
} catch {
|
|
122585
|
+
return "";
|
|
122586
|
+
}
|
|
122587
|
+
}
|
|
122411
122588
|
/** Build one row per provider from persisted settings, including ComfyUI extras. */
|
|
122412
122589
|
function rowsFromSettings(value) {
|
|
122413
122590
|
const rows = {};
|
|
@@ -122419,6 +122596,10 @@ img.ProseMirror-separator {
|
|
|
122419
122596
|
workflows: resolveComfyUIWorkflows(value ?? {}),
|
|
122420
122597
|
activeWorkflow: activeComfyUIWorkflow(value ?? {})?.name ?? "",
|
|
122421
122598
|
timeoutSeconds: Math.max(1, Math.round((value?.comfyuiTimeoutMs ?? 3e5) / 1e3))
|
|
122599
|
+
} : {},
|
|
122600
|
+
...provider === "openai-compat" ? {
|
|
122601
|
+
editFormat: value?.openaiCompatEditFormat === "jsonImageUrlArray" ? "jsonImageUrlArray" : "multipart",
|
|
122602
|
+
editExtraText: editExtraTextOf(value?.openaiCompatEditExtra)
|
|
122422
122603
|
} : {}
|
|
122423
122604
|
};
|
|
122424
122605
|
return rows;
|
|
@@ -122440,6 +122621,14 @@ img.ProseMirror-separator {
|
|
|
122440
122621
|
const [workspaceMessageIsError, setWorkspaceMessageIsError] = (0, react.useState)(false);
|
|
122441
122622
|
const [rows, setRows] = (0, react.useState)(() => rowsFromSettings(props.scope.getSnapshot().value));
|
|
122442
122623
|
const [keyTick, setKeyTick] = (0, react.useState)(0);
|
|
122624
|
+
const [subStatus, setSubStatus] = (0, react.useState)(() => ({
|
|
122625
|
+
"chatgpt-sub": { state: "unknown" },
|
|
122626
|
+
"grok-sub": { state: "unknown" },
|
|
122627
|
+
"google-sub": { state: "unknown" }
|
|
122628
|
+
}));
|
|
122629
|
+
const [subTick, setSubTick] = (0, react.useState)(0);
|
|
122630
|
+
const [subBusy, setSubBusy] = (0, react.useState)({});
|
|
122631
|
+
const [subPending, setSubPending] = (0, react.useState)([]);
|
|
122443
122632
|
(0, react.useEffect)(() => props.scope.subscribe(() => {
|
|
122444
122633
|
setSnapshot(props.scope.getSnapshot());
|
|
122445
122634
|
}), [props.scope]);
|
|
@@ -122452,6 +122641,143 @@ img.ProseMirror-separator {
|
|
|
122452
122641
|
(0, react.useEffect)(() => credentialEvents?.listen(() => {
|
|
122453
122642
|
setKeyTick((tick) => tick + 1);
|
|
122454
122643
|
}), [credentialEvents]);
|
|
122644
|
+
const pending = subPending;
|
|
122645
|
+
(0, react.useEffect)(() => {
|
|
122646
|
+
if (!open) return void 0;
|
|
122647
|
+
let active = true;
|
|
122648
|
+
const probe = async () => {
|
|
122649
|
+
try {
|
|
122650
|
+
const response = await fetch(SUBSCRIPTION_STATUS_ROUTE, {
|
|
122651
|
+
method: "POST",
|
|
122652
|
+
cache: "no-store"
|
|
122653
|
+
});
|
|
122654
|
+
if (!response.ok) return;
|
|
122655
|
+
const payload = await response.json();
|
|
122656
|
+
if (!active || payload.statuses === void 0) return;
|
|
122657
|
+
const next = {
|
|
122658
|
+
"chatgpt-sub": { state: "unknown" },
|
|
122659
|
+
"grok-sub": { state: "unknown" },
|
|
122660
|
+
"google-sub": { state: "unknown" }
|
|
122661
|
+
};
|
|
122662
|
+
for (const provider of SUBSCRIPTION_PROVIDERS) {
|
|
122663
|
+
const row = payload.statuses[provider];
|
|
122664
|
+
if (row?.state === "logged-in") next[provider] = {
|
|
122665
|
+
state: "logged-in",
|
|
122666
|
+
...typeof row.email === "string" ? { email: row.email } : {}
|
|
122667
|
+
};
|
|
122668
|
+
else if (row?.state === "logged-out") next[provider] = { state: "logged-out" };
|
|
122669
|
+
}
|
|
122670
|
+
setSubStatus(next);
|
|
122671
|
+
const landed = pending.filter((entry) => next[entry.provider].state === "logged-in");
|
|
122672
|
+
if (landed.length > 0) {
|
|
122673
|
+
setSubPending((current) => current.filter((entry) => next[entry.provider].state !== "logged-in"));
|
|
122674
|
+
for (const entry of landed) updateRow(entry.provider, {
|
|
122675
|
+
message: t("subLoginOk"),
|
|
122676
|
+
messageIsError: false
|
|
122677
|
+
});
|
|
122678
|
+
}
|
|
122679
|
+
const WINDOW_MS = 63e4;
|
|
122680
|
+
if (pending.filter((entry) => Date.now() - entry.startedAt > WINDOW_MS).length > 0) setSubPending((current) => current.filter((entry) => Date.now() - entry.startedAt <= WINDOW_MS));
|
|
122681
|
+
} catch {}
|
|
122682
|
+
};
|
|
122683
|
+
probe();
|
|
122684
|
+
let timer;
|
|
122685
|
+
if (pending.length > 0) timer = setInterval(() => {
|
|
122686
|
+
probe();
|
|
122687
|
+
}, 2e3);
|
|
122688
|
+
const onFocus = () => {
|
|
122689
|
+
probe();
|
|
122690
|
+
};
|
|
122691
|
+
window.addEventListener("focus", onFocus);
|
|
122692
|
+
return () => {
|
|
122693
|
+
active = false;
|
|
122694
|
+
if (timer !== void 0) clearInterval(timer);
|
|
122695
|
+
window.removeEventListener("focus", onFocus);
|
|
122696
|
+
};
|
|
122697
|
+
}, [
|
|
122698
|
+
open,
|
|
122699
|
+
subTick,
|
|
122700
|
+
pending
|
|
122701
|
+
]);
|
|
122702
|
+
/** Start a subscription login: the host registers PKCE and the loopback
|
|
122703
|
+
* catch server, then the browser opens the vendor's authorize URL. The
|
|
122704
|
+
* provider joins the pending set so the badge polls until login lands. */
|
|
122705
|
+
const subscriptionLogin = async (provider) => {
|
|
122706
|
+
updateRow(provider, {
|
|
122707
|
+
message: "",
|
|
122708
|
+
messageIsError: false
|
|
122709
|
+
});
|
|
122710
|
+
setSubBusy((current) => ({
|
|
122711
|
+
...current,
|
|
122712
|
+
[provider]: "login"
|
|
122713
|
+
}));
|
|
122714
|
+
try {
|
|
122715
|
+
const response = await fetch(SUBSCRIPTION_LOGIN_ROUTE, {
|
|
122716
|
+
method: "POST",
|
|
122717
|
+
headers: { "content-type": "application/json" },
|
|
122718
|
+
body: JSON.stringify({ provider })
|
|
122719
|
+
});
|
|
122720
|
+
const payload = await response.json().catch(() => ({}));
|
|
122721
|
+
if (!response.ok || payload.ok !== true || typeof payload.url !== "string") {
|
|
122722
|
+
const detail = typeof payload.error === "string" ? payload.error : payload.error?.message;
|
|
122723
|
+
throw new Error(detail ?? `HTTP ${String(response.status)}`);
|
|
122724
|
+
}
|
|
122725
|
+
setSubPending((current) => [...current.filter((entry) => entry.provider !== provider), {
|
|
122726
|
+
provider,
|
|
122727
|
+
startedAt: Date.now()
|
|
122728
|
+
}]);
|
|
122729
|
+
window.open(payload.url, "_blank", "noopener");
|
|
122730
|
+
updateRow(provider, {
|
|
122731
|
+
message: t("subWaitingLogin"),
|
|
122732
|
+
messageIsError: false
|
|
122733
|
+
});
|
|
122734
|
+
} catch (cause) {
|
|
122735
|
+
updateRow(provider, {
|
|
122736
|
+
message: cause instanceof Error ? cause.message : String(cause),
|
|
122737
|
+
messageIsError: true
|
|
122738
|
+
});
|
|
122739
|
+
} finally {
|
|
122740
|
+
setSubBusy((current) => {
|
|
122741
|
+
const next = { ...current };
|
|
122742
|
+
delete next[provider];
|
|
122743
|
+
return next;
|
|
122744
|
+
});
|
|
122745
|
+
}
|
|
122746
|
+
};
|
|
122747
|
+
/** Sign out one subscription account; nothing else changes. */
|
|
122748
|
+
const subscriptionLogout = async (provider) => {
|
|
122749
|
+
setSubBusy((current) => ({
|
|
122750
|
+
...current,
|
|
122751
|
+
[provider]: "logout"
|
|
122752
|
+
}));
|
|
122753
|
+
try {
|
|
122754
|
+
const response = await fetch(SUBSCRIPTION_LOGIN_ROUTE, {
|
|
122755
|
+
method: "POST",
|
|
122756
|
+
headers: { "content-type": "application/json" },
|
|
122757
|
+
body: JSON.stringify({
|
|
122758
|
+
provider,
|
|
122759
|
+
action: "logout"
|
|
122760
|
+
})
|
|
122761
|
+
});
|
|
122762
|
+
if (!response.ok) throw new Error(`HTTP ${String(response.status)}`);
|
|
122763
|
+
updateRow(provider, {
|
|
122764
|
+
message: "",
|
|
122765
|
+
messageIsError: false
|
|
122766
|
+
});
|
|
122767
|
+
} catch (cause) {
|
|
122768
|
+
updateRow(provider, {
|
|
122769
|
+
message: cause instanceof Error ? cause.message : String(cause),
|
|
122770
|
+
messageIsError: true
|
|
122771
|
+
});
|
|
122772
|
+
} finally {
|
|
122773
|
+
setSubBusy((current) => {
|
|
122774
|
+
const next = { ...current };
|
|
122775
|
+
delete next[provider];
|
|
122776
|
+
return next;
|
|
122777
|
+
});
|
|
122778
|
+
setSubTick((tick) => tick + 1);
|
|
122779
|
+
}
|
|
122780
|
+
};
|
|
122455
122781
|
const t = (keyName, params) => {
|
|
122456
122782
|
let text = (lang === "en" ? DICT.en : DICT.zh)[keyName] || DICT.zh[keyName] || keyName;
|
|
122457
122783
|
if (params) for (const [k, v] of Object.entries(params)) text = text.replace(`{${k}}`, v);
|
|
@@ -122465,7 +122791,10 @@ img.ProseMirror-separator {
|
|
|
122465
122791
|
dashscope: t("providerDashScope"),
|
|
122466
122792
|
xai: t("providerXAI"),
|
|
122467
122793
|
zhipu: t("providerZhipu"),
|
|
122468
|
-
comfyui: t("providerComfyUI")
|
|
122794
|
+
comfyui: t("providerComfyUI"),
|
|
122795
|
+
"chatgpt-sub": t("providerChatGPTSub"),
|
|
122796
|
+
"grok-sub": t("providerGrokSub"),
|
|
122797
|
+
"google-sub": t("providerGoogleSub")
|
|
122469
122798
|
};
|
|
122470
122799
|
(0, react.useEffect)(() => {
|
|
122471
122800
|
const value = snapshot.value;
|
|
@@ -122592,9 +122921,28 @@ img.ProseMirror-separator {
|
|
|
122592
122921
|
await props.scope.set("comfyuiWorkflowJson", activeEntry === void 0 ? "" : activeEntry.json);
|
|
122593
122922
|
await props.scope.set("comfyuiWorkflowName", activeEntry === void 0 ? "" : activeEntry.name);
|
|
122594
122923
|
await props.scope.set("comfyuiTimeoutMs", Math.max(1, Math.round(row.timeoutSeconds)) * 1e3);
|
|
122595
|
-
} else
|
|
122924
|
+
} else if (isSubscriptionProvider(provider)) await Promise.resolve();
|
|
122925
|
+
else {
|
|
122926
|
+
let editExtra = {};
|
|
122927
|
+
if (provider === "openai-compat") {
|
|
122928
|
+
const extraText = row.editExtraText.trim();
|
|
122929
|
+
if (extraText.length > 0) {
|
|
122930
|
+
let parsed;
|
|
122931
|
+
try {
|
|
122932
|
+
parsed = JSON.parse(extraText);
|
|
122933
|
+
} catch {
|
|
122934
|
+
throw new Error(t("editExtraInvalid"));
|
|
122935
|
+
}
|
|
122936
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) throw new Error(t("editExtraInvalid"));
|
|
122937
|
+
editExtra = parsed;
|
|
122938
|
+
}
|
|
122939
|
+
}
|
|
122596
122940
|
await props.scope.set(modelFieldOf(provider), row.model);
|
|
122597
122941
|
await props.scope.set(baseURLFieldOf(provider), row.baseURL);
|
|
122942
|
+
if (provider === "openai-compat") {
|
|
122943
|
+
await props.scope.set("openaiCompatEditFormat", row.editFormat);
|
|
122944
|
+
await props.scope.set("openaiCompatEditExtra", editExtra);
|
|
122945
|
+
}
|
|
122598
122946
|
if (row.keyInput.trim().length > 0) {
|
|
122599
122947
|
const keyRef = cloudCredentialRef(provider);
|
|
122600
122948
|
if (keyRef === void 0) throw new Error(t("comfyuiNoKey"));
|
|
@@ -122738,6 +123086,21 @@ img.ProseMirror-separator {
|
|
|
122738
123086
|
text: t("comfyuiNoKey"),
|
|
122739
123087
|
className: "dsh-ig-badge dsh-ig-badge-neutral"
|
|
122740
123088
|
};
|
|
123089
|
+
if (isSubscriptionProvider(provider)) {
|
|
123090
|
+
const status = subStatus[provider].state;
|
|
123091
|
+
if (status === "logged-in") return {
|
|
123092
|
+
text: t("subBadgeLoggedIn"),
|
|
123093
|
+
className: "dsh-ig-badge dsh-ig-badge-ok"
|
|
123094
|
+
};
|
|
123095
|
+
if (status === "logged-out") return {
|
|
123096
|
+
text: t("subBadgeLoggedOut"),
|
|
123097
|
+
className: "dsh-ig-badge dsh-ig-badge-missing"
|
|
123098
|
+
};
|
|
123099
|
+
return {
|
|
123100
|
+
text: t("subBadgeUnknown"),
|
|
123101
|
+
className: "dsh-ig-badge dsh-ig-badge-neutral"
|
|
123102
|
+
};
|
|
123103
|
+
}
|
|
122741
123104
|
const status = rows[provider].keyStatus;
|
|
122742
123105
|
if (status === "checking") return {
|
|
122743
123106
|
text: t("badgeChecking"),
|
|
@@ -123007,6 +123370,57 @@ img.ProseMirror-separator {
|
|
|
123007
123370
|
}) : null
|
|
123008
123371
|
]
|
|
123009
123372
|
}),
|
|
123373
|
+
provider === "openai-compat" ? (0, react_jsx_runtime.jsxs)("label", {
|
|
123374
|
+
className: "dsh-ig-field",
|
|
123375
|
+
children: [
|
|
123376
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
123377
|
+
className: "dsh-ig-label",
|
|
123378
|
+
children: t("editFormat")
|
|
123379
|
+
}),
|
|
123380
|
+
(0, react_jsx_runtime.jsxs)("select", {
|
|
123381
|
+
className: "dsh-ig-input",
|
|
123382
|
+
value: row.editFormat,
|
|
123383
|
+
onChange: (event) => {
|
|
123384
|
+
updateRow(provider, { editFormat: event.target.value === "jsonImageUrlArray" ? "jsonImageUrlArray" : "multipart" });
|
|
123385
|
+
},
|
|
123386
|
+
disabled: !snapshot.writable,
|
|
123387
|
+
children: [(0, react_jsx_runtime.jsx)("option", {
|
|
123388
|
+
value: "multipart",
|
|
123389
|
+
children: t("editFormatMultipart")
|
|
123390
|
+
}), (0, react_jsx_runtime.jsx)("option", {
|
|
123391
|
+
value: "jsonImageUrlArray",
|
|
123392
|
+
children: t("editFormatJsonImageUrlArray")
|
|
123393
|
+
})]
|
|
123394
|
+
}),
|
|
123395
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
123396
|
+
className: "dsh-ig-hint",
|
|
123397
|
+
children: t("editFormatHint")
|
|
123398
|
+
})
|
|
123399
|
+
]
|
|
123400
|
+
}) : null,
|
|
123401
|
+
provider === "openai-compat" && row.editFormat === "jsonImageUrlArray" ? (0, react_jsx_runtime.jsxs)("label", {
|
|
123402
|
+
className: "dsh-ig-field",
|
|
123403
|
+
children: [
|
|
123404
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
123405
|
+
className: "dsh-ig-label",
|
|
123406
|
+
children: t("editExtra")
|
|
123407
|
+
}),
|
|
123408
|
+
(0, react_jsx_runtime.jsx)("textarea", {
|
|
123409
|
+
className: "dsh-ig-input dsh-ig-textarea",
|
|
123410
|
+
value: row.editExtraText,
|
|
123411
|
+
onChange: (event) => {
|
|
123412
|
+
updateRow(provider, { editExtraText: event.target.value });
|
|
123413
|
+
},
|
|
123414
|
+
placeholder: t("editExtraPlaceholder"),
|
|
123415
|
+
rows: 2,
|
|
123416
|
+
disabled: !snapshot.writable
|
|
123417
|
+
}),
|
|
123418
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
123419
|
+
className: "dsh-ig-hint",
|
|
123420
|
+
children: t("editExtraHint")
|
|
123421
|
+
})
|
|
123422
|
+
]
|
|
123423
|
+
}) : null,
|
|
123010
123424
|
(0, react_jsx_runtime.jsxs)("div", {
|
|
123011
123425
|
className: "dsh-ig-row-actions",
|
|
123012
123426
|
children: [(0, react_jsx_runtime.jsx)("p", {
|
|
@@ -123224,6 +123638,119 @@ img.ProseMirror-separator {
|
|
|
123224
123638
|
})
|
|
123225
123639
|
});
|
|
123226
123640
|
};
|
|
123641
|
+
/** Subscription rows: account login/logout, fixed model, edit limitation. */
|
|
123642
|
+
const renderSubscriptionBody = (provider) => {
|
|
123643
|
+
const row = rows[provider];
|
|
123644
|
+
const status = subStatus[provider];
|
|
123645
|
+
const busy = subBusy[provider];
|
|
123646
|
+
return (0, react_jsx_runtime.jsx)("div", {
|
|
123647
|
+
className: "dsh-ig-provider-body",
|
|
123648
|
+
children: (0, react_jsx_runtime.jsxs)("form", {
|
|
123649
|
+
onSubmit: (event) => {
|
|
123650
|
+
event.preventDefault();
|
|
123651
|
+
saveProviderRow(provider);
|
|
123652
|
+
},
|
|
123653
|
+
children: [
|
|
123654
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
123655
|
+
className: "dsh-ig-field",
|
|
123656
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
123657
|
+
className: "dsh-ig-label",
|
|
123658
|
+
children: t("subSectionTitle")
|
|
123659
|
+
}), (0, react_jsx_runtime.jsx)("p", {
|
|
123660
|
+
className: "dsh-ig-hint",
|
|
123661
|
+
children: t("subHint")
|
|
123662
|
+
})]
|
|
123663
|
+
}),
|
|
123664
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
123665
|
+
className: "dsh-ig-field",
|
|
123666
|
+
children: [
|
|
123667
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
123668
|
+
className: "dsh-ig-label",
|
|
123669
|
+
children: t("subAccountLabel")
|
|
123670
|
+
}),
|
|
123671
|
+
(0, react_jsx_runtime.jsx)("p", {
|
|
123672
|
+
className: "dsh-ig-hint",
|
|
123673
|
+
children: status.state === "logged-in" ? t("subAccountEmail", { email: status.email ?? "" }) : status.state === "logged-out" ? t("subAccountNone") : t("subBadgeUnknown")
|
|
123674
|
+
}),
|
|
123675
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
123676
|
+
className: "dsh-ig-row-buttons",
|
|
123677
|
+
children: status.state === "logged-in" ? (0, react_jsx_runtime.jsx)("button", {
|
|
123678
|
+
type: "button",
|
|
123679
|
+
className: "dsh-ig-btn-secondary",
|
|
123680
|
+
disabled: busy !== void 0,
|
|
123681
|
+
onClick: () => {
|
|
123682
|
+
subscriptionLogout(provider);
|
|
123683
|
+
},
|
|
123684
|
+
children: busy === "logout" ? t("subLoggingOut") : t("subLogout")
|
|
123685
|
+
}) : (0, react_jsx_runtime.jsx)("button", {
|
|
123686
|
+
type: "button",
|
|
123687
|
+
className: "dsh-ig-save",
|
|
123688
|
+
disabled: busy !== void 0,
|
|
123689
|
+
onClick: () => {
|
|
123690
|
+
subscriptionLogin(provider);
|
|
123691
|
+
setSubTick((tick) => tick + 1);
|
|
123692
|
+
},
|
|
123693
|
+
children: busy === "login" ? t("subLoggingIn") : t("subLogin")
|
|
123694
|
+
})
|
|
123695
|
+
})
|
|
123696
|
+
]
|
|
123697
|
+
}),
|
|
123698
|
+
(0, react_jsx_runtime.jsxs)("label", {
|
|
123699
|
+
className: "dsh-ig-field",
|
|
123700
|
+
children: [
|
|
123701
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
123702
|
+
className: "dsh-ig-label",
|
|
123703
|
+
children: t("subModelLabel")
|
|
123704
|
+
}),
|
|
123705
|
+
(0, react_jsx_runtime.jsx)("input", {
|
|
123706
|
+
className: "dsh-ig-input",
|
|
123707
|
+
type: "text",
|
|
123708
|
+
value: row.model,
|
|
123709
|
+
readOnly: true,
|
|
123710
|
+
disabled: true
|
|
123711
|
+
}),
|
|
123712
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
123713
|
+
className: "dsh-ig-hint",
|
|
123714
|
+
children: t("subModelHint")
|
|
123715
|
+
})
|
|
123716
|
+
]
|
|
123717
|
+
}),
|
|
123718
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
123719
|
+
className: "dsh-ig-field",
|
|
123720
|
+
children: (0, react_jsx_runtime.jsx)("span", {
|
|
123721
|
+
className: "dsh-ig-label",
|
|
123722
|
+
children: t("subEditUnsupported")
|
|
123723
|
+
})
|
|
123724
|
+
}),
|
|
123725
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
123726
|
+
className: "dsh-ig-row-actions",
|
|
123727
|
+
children: [(0, react_jsx_runtime.jsx)("p", {
|
|
123728
|
+
className: `dsh-ig-status${row.messageIsError ? " dsh-ig-status-error" : ""}`,
|
|
123729
|
+
role: "status",
|
|
123730
|
+
children: row.message || testResultText(row.testResult)
|
|
123731
|
+
}), (0, react_jsx_runtime.jsxs)("span", {
|
|
123732
|
+
className: "dsh-ig-row-buttons",
|
|
123733
|
+
children: [(0, react_jsx_runtime.jsx)("button", {
|
|
123734
|
+
type: "button",
|
|
123735
|
+
className: "dsh-ig-btn-secondary",
|
|
123736
|
+
disabled: row.testing,
|
|
123737
|
+
onClick: () => {
|
|
123738
|
+
testConnection(provider);
|
|
123739
|
+
setSubTick((tick) => tick + 1);
|
|
123740
|
+
},
|
|
123741
|
+
children: row.testing ? t("testing") : t("testConnection")
|
|
123742
|
+
}), (0, react_jsx_runtime.jsx)("button", {
|
|
123743
|
+
className: "dsh-ig-save",
|
|
123744
|
+
type: "submit",
|
|
123745
|
+
disabled: row.saving || !snapshot.writable,
|
|
123746
|
+
children: row.saving ? t("saving") : t("save")
|
|
123747
|
+
})]
|
|
123748
|
+
})]
|
|
123749
|
+
})
|
|
123750
|
+
]
|
|
123751
|
+
})
|
|
123752
|
+
});
|
|
123753
|
+
};
|
|
123227
123754
|
const renderProviderRow = (provider) => {
|
|
123228
123755
|
const row = rows[provider];
|
|
123229
123756
|
const badge = badgeOf(provider);
|
|
@@ -123265,7 +123792,7 @@ img.ProseMirror-separator {
|
|
|
123265
123792
|
})
|
|
123266
123793
|
})
|
|
123267
123794
|
]
|
|
123268
|
-
}), row.expanded ? provider === "comfyui" ? renderComfyUIBody() : renderCloudBody(provider) : null]
|
|
123795
|
+
}), row.expanded ? provider === "comfyui" ? renderComfyUIBody() : isSubscriptionProvider(provider) ? renderSubscriptionBody(provider) : renderCloudBody(provider) : null]
|
|
123269
123796
|
}, provider);
|
|
123270
123797
|
};
|
|
123271
123798
|
return (0, react_jsx_runtime.jsxs)("li", {
|
|
@@ -124004,11 +124531,11 @@ img.ProseMirror-separator {
|
|
|
124004
124531
|
};
|
|
124005
124532
|
}
|
|
124006
124533
|
function modelOf(provider, value) {
|
|
124007
|
-
const stored = provider === "comfyui" ? activeComfyUIWorkflow(value ?? {})?.name : value?.[CLOUD_MODEL_FIELDS[provider]];
|
|
124534
|
+
const stored = provider === "comfyui" ? activeComfyUIWorkflow(value ?? {})?.name : isSubscriptionProvider(provider) ? DEFAULT_MODELS[provider] : value?.[CLOUD_MODEL_FIELDS[provider]];
|
|
124008
124535
|
return typeof stored === "string" && stored.length > 0 ? stored : DEFAULT_MODELS[provider];
|
|
124009
124536
|
}
|
|
124010
124537
|
function baseURLOf(provider, value) {
|
|
124011
|
-
const stored = provider === "comfyui" ? value?.comfyuiBaseURL : value?.[CLOUD_URL_FIELDS[provider]];
|
|
124538
|
+
const stored = provider === "comfyui" ? value?.comfyuiBaseURL : isSubscriptionProvider(provider) ? "" : value?.[CLOUD_URL_FIELDS[provider]];
|
|
124012
124539
|
return typeof stored === "string" && stored.length > 0 ? stored : DEFAULT_BASE_URLS[provider];
|
|
124013
124540
|
}
|
|
124014
124541
|
//#endregion
|