dsh-image-gen 0.4.0 → 0.5.0
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 +262 -90
- package/README.md +256 -94
- package/README.zh-CN.md +2 -171
- package/docs/assets/readme/chat-example.webp +0 -0
- package/docs/assets/readme/comfyui-workflows.webp +0 -0
- package/docs/assets/readme/gallery-management.webp +0 -0
- package/docs/assets/readme/hero-en.webp +0 -0
- package/docs/assets/readme/hero-zh.webp +0 -0
- package/docs/assets/readme/inspiration-library.webp +0 -0
- package/docs/assets/readme/multi-model-compare.webp +0 -0
- package/docs/assets/readme/provider-settings.webp +0 -0
- package/docs/assets/readme/regenerating.webp +0 -0
- package/docs/assets/readme/revision-switcher.webp +0 -0
- package/docs/assets/readme/studio-workbench.webp +0 -0
- package/docs/assets/readme/workflow-overview.webp +0 -0
- package/lib/client.js +1521 -395
- package/lib/client.js.map +1 -1
- package/lib/index.js +5584 -181
- package/lib/types/client/conversation-image-revisions.d.ts +1 -1
- package/lib/types/client/gallery-view.d.ts +8 -2
- package/lib/types/client/image-ref.d.ts +24 -1
- package/lib/types/client/index.d.ts +26 -2
- package/lib/types/client/provider-pill.d.ts +49 -0
- package/lib/types/client/studio-style.d.ts +1 -1
- package/lib/types/config.d.ts +39 -10
- package/lib/types/credentials.d.ts +15 -0
- package/lib/types/index.d.ts +1 -0
- package/lib/types/openai-compatible.d.ts +1 -1
- package/lib/types/redact.d.ts +2 -0
- package/lib/types/shared.d.ts +37 -2
- package/lib/types/test-route.d.ts +73 -0
- package/package.json +14 -16
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment';
|
|
2
|
-
import type
|
|
2
|
+
import { type CloudImageProvider } from '../shared.js';
|
|
3
3
|
/** One regenerated version displayed in place of an original conversation image. */
|
|
4
4
|
export interface ConversationImageRevision {
|
|
5
5
|
attachment: ImageAttachmentRef;
|
|
@@ -22,9 +22,12 @@ declare const DICT: {
|
|
|
22
22
|
readonly tabTasks: "任务";
|
|
23
23
|
readonly filterAllProviders: "全部提供商";
|
|
24
24
|
readonly filterGoogle: "Google Gemini";
|
|
25
|
-
readonly filterOpenAI: "OpenAI
|
|
25
|
+
readonly filterOpenAI: "OpenAI";
|
|
26
|
+
readonly filterOpenAICompat: "OpenAI 兼容";
|
|
26
27
|
readonly filterSeedream: "字节 Seedream";
|
|
27
28
|
readonly filterDashScope: "阿里 DashScope";
|
|
29
|
+
readonly filterXAI: "xAI Grok";
|
|
30
|
+
readonly filterZhipu: "智谱 GLM";
|
|
28
31
|
readonly filterComfyUI: "本地 ComfyUI";
|
|
29
32
|
readonly filterAllModels: "全部模型";
|
|
30
33
|
readonly filterAllRatios: "全部比例";
|
|
@@ -104,9 +107,12 @@ declare const DICT: {
|
|
|
104
107
|
readonly tabTasks: "Tasks";
|
|
105
108
|
readonly filterAllProviders: "All Providers";
|
|
106
109
|
readonly filterGoogle: "Google Gemini";
|
|
107
|
-
readonly filterOpenAI: "OpenAI
|
|
110
|
+
readonly filterOpenAI: "OpenAI";
|
|
111
|
+
readonly filterOpenAICompat: "OpenAI-compatible";
|
|
108
112
|
readonly filterSeedream: "ByteDance Seedream";
|
|
109
113
|
readonly filterDashScope: "Aliyun DashScope";
|
|
114
|
+
readonly filterXAI: "xAI Grok";
|
|
115
|
+
readonly filterZhipu: "Zhipu GLM";
|
|
110
116
|
readonly filterComfyUI: "Local ComfyUI";
|
|
111
117
|
readonly filterAllModels: "All Models";
|
|
112
118
|
readonly filterAllRatios: "All Ratios";
|
|
@@ -1,6 +1,29 @@
|
|
|
1
1
|
/** Dual-path image attachment resolution for legacy rc.2 and modern DSH runtime blocks. */
|
|
2
2
|
import type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment';
|
|
3
|
-
|
|
3
|
+
export interface RunningToolCall {
|
|
4
|
+
callId?: string;
|
|
5
|
+
name?: string;
|
|
6
|
+
argsRaw?: string;
|
|
7
|
+
turn?: number;
|
|
8
|
+
step?: number;
|
|
9
|
+
time?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface ToolResultNode {
|
|
12
|
+
kind?: string;
|
|
13
|
+
callId?: string;
|
|
14
|
+
resultView?: {
|
|
15
|
+
card?: string;
|
|
16
|
+
content?: Array<{
|
|
17
|
+
type: string;
|
|
18
|
+
attachment?: ImageAttachmentRef;
|
|
19
|
+
}>;
|
|
20
|
+
} | null;
|
|
21
|
+
content?: Array<{
|
|
22
|
+
type: string;
|
|
23
|
+
attachment?: ImageAttachmentRef;
|
|
24
|
+
}>;
|
|
25
|
+
}
|
|
26
|
+
export type ToolCallBlock = RunningToolCall | ToolResultNode;
|
|
4
27
|
/**
|
|
5
28
|
* Extract the verified durable image attachment from a completed tool result block.
|
|
6
29
|
* Supports legacy rc.2 `resultView.content` and modern DSH `block.content`.
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
-
|
|
2
|
+
export interface SettingsScopeSnapshot<T> {
|
|
3
|
+
value: T | undefined;
|
|
4
|
+
writable: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface SettingsScope<T> {
|
|
7
|
+
getSnapshot(): SettingsScopeSnapshot<T>;
|
|
8
|
+
subscribe(listener: () => void): () => void;
|
|
9
|
+
set(field: string, value: unknown): Promise<void>;
|
|
10
|
+
}
|
|
3
11
|
import type { InjectFace, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
4
12
|
import { type ComfyUIWorkflowEntry, type ImageProvider } from '../shared.js';
|
|
5
13
|
import { type LocaleService } from './gallery-view.js';
|
|
@@ -11,10 +19,16 @@ interface ImageSettings {
|
|
|
11
19
|
googleEndpoint?: string;
|
|
12
20
|
openaiBaseURL?: string;
|
|
13
21
|
openaiModel?: string;
|
|
22
|
+
openaiCompatBaseURL?: string;
|
|
23
|
+
openaiCompatModel?: string;
|
|
14
24
|
seedreamBaseURL?: string;
|
|
15
25
|
seedreamModel?: string;
|
|
16
26
|
dashscopeEndpoint?: string;
|
|
17
27
|
dashscopeModel?: string;
|
|
28
|
+
xaiBaseURL?: string;
|
|
29
|
+
xaiModel?: string;
|
|
30
|
+
zhipuBaseURL?: string;
|
|
31
|
+
zhipuModel?: string;
|
|
18
32
|
comfyuiBaseURL?: string;
|
|
19
33
|
comfyuiWorkflows?: ComfyUIWorkflowEntry[];
|
|
20
34
|
comfyuiActiveWorkflow?: string;
|
|
@@ -23,9 +37,12 @@ interface ImageSettings {
|
|
|
23
37
|
comfyuiTimeoutMs?: number;
|
|
24
38
|
saveToWorkspace?: boolean;
|
|
25
39
|
workspaceFolder?: string;
|
|
40
|
+
showProviderPill?: boolean;
|
|
26
41
|
}
|
|
27
42
|
interface CredentialInfo {
|
|
28
43
|
configured?: boolean;
|
|
44
|
+
source?: string;
|
|
45
|
+
writable?: boolean;
|
|
29
46
|
}
|
|
30
47
|
interface CredentialResult {
|
|
31
48
|
ok: boolean;
|
|
@@ -40,11 +57,18 @@ interface CredentialMutationResult {
|
|
|
40
57
|
interface CredentialsRemote {
|
|
41
58
|
describe(refs: string[]): Promise<CredentialResult>;
|
|
42
59
|
set(ref: string, value: string): Promise<CredentialMutationResult>;
|
|
60
|
+
/** Present only on modern hosts; feature-detected before use. */
|
|
61
|
+
unset?(ref: string): Promise<CredentialMutationResult>;
|
|
62
|
+
}
|
|
63
|
+
/** Notifies the settings card whenever any credential reference changes on the host. */
|
|
64
|
+
interface CredentialEvents {
|
|
65
|
+
listen(callback: () => void): () => void;
|
|
43
66
|
}
|
|
44
67
|
interface SettingsFace {
|
|
45
68
|
scope: SettingsScope<ImageSettings>;
|
|
46
69
|
credentials: CredentialsRemote;
|
|
47
70
|
locale?: LocaleService | undefined;
|
|
71
|
+
credentialEvents?: CredentialEvents | undefined;
|
|
48
72
|
}
|
|
49
73
|
interface ImageCardFace {
|
|
50
74
|
locale?: LocaleService | undefined;
|
|
@@ -64,7 +88,7 @@ interface ImageResultNodeProps {
|
|
|
64
88
|
export declare const inject: string[];
|
|
65
89
|
/** Mount the settings card, generated-image card, and native conversation gallery view. */
|
|
66
90
|
export declare function apply(ctx: Context): void;
|
|
67
|
-
/** Edit provider
|
|
91
|
+
/** Edit each provider independently, pick an explicit default, and verify keys inline. */
|
|
68
92
|
export declare function ImageGenerationSettingsCard(props: SettingsCardProps): import("react").JSX.Element;
|
|
69
93
|
/** Keep the legacy Tool row for old DSH and hand modern results to the independent Chat node. */
|
|
70
94
|
export declare function GeneratedImageCard(props: ImageCardProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type ComfyUIWorkflowEntry, type ImageProvider } from '../shared.js';
|
|
2
|
+
import type { SettingsScope } from './index.js';
|
|
3
|
+
import type { LocaleService } from './gallery-view.js';
|
|
4
|
+
/** Settings fields the pill reads; a structural subset of the full settings shape. */
|
|
5
|
+
export interface PillSettings {
|
|
6
|
+
provider?: ImageProvider;
|
|
7
|
+
googleModel?: string;
|
|
8
|
+
openaiModel?: string;
|
|
9
|
+
openaiCompatModel?: string;
|
|
10
|
+
seedreamModel?: string;
|
|
11
|
+
dashscopeModel?: string;
|
|
12
|
+
xaiModel?: string;
|
|
13
|
+
zhipuModel?: string;
|
|
14
|
+
comfyuiWorkflows?: readonly ComfyUIWorkflowEntry[];
|
|
15
|
+
comfyuiActiveWorkflow?: string;
|
|
16
|
+
comfyuiWorkflowJson?: string;
|
|
17
|
+
comfyuiWorkflowName?: string;
|
|
18
|
+
/** Opt-in toggle persisted by the settings card; the pill stays hidden until enabled. */
|
|
19
|
+
showProviderPill?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/** Minimal credential face the pill needs; structurally satisfied by the settings card's remote. */
|
|
22
|
+
interface PillCredentials {
|
|
23
|
+
describe(refs: string[]): Promise<{
|
|
24
|
+
ok: boolean;
|
|
25
|
+
value?: Readonly<Record<string, {
|
|
26
|
+
configured?: boolean;
|
|
27
|
+
}>>;
|
|
28
|
+
}>;
|
|
29
|
+
}
|
|
30
|
+
/** Notifies the pill whenever any credential reference changes on the host. */
|
|
31
|
+
interface PillCredentialEvents {
|
|
32
|
+
listen(callback: () => void): () => void;
|
|
33
|
+
}
|
|
34
|
+
/** Business face injected at registration time by the client entry. */
|
|
35
|
+
export interface ProviderPillFace {
|
|
36
|
+
scope: SettingsScope<PillSettings>;
|
|
37
|
+
credentials: PillCredentials;
|
|
38
|
+
locale?: LocaleService | undefined;
|
|
39
|
+
credentialEvents?: PillCredentialEvents | undefined;
|
|
40
|
+
}
|
|
41
|
+
/** Whether the user opted into the composer pill; hidden (not merely inert) when off. */
|
|
42
|
+
export declare function pillVisible(value: PillSettings | undefined): boolean;
|
|
43
|
+
/** Model (or ComfyUI workflow) a provider row will use with the persisted settings. */
|
|
44
|
+
export declare function pillModelOf(provider: ImageProvider, value: PillSettings | undefined): string;
|
|
45
|
+
/** One fixed-position provider menu anchored to the pill button. */
|
|
46
|
+
export declare function ImageProviderPill(props: ProviderPillFace): import("react").JSX.Element | null;
|
|
47
|
+
/** Styles for the pill and its fixed-position menu; injected by the client entry. */
|
|
48
|
+
export declare const PROVIDER_PILL_STYLE = "\n.dsh-ig-pill-root{position:relative;display:inline-flex;align-items:center;height:26px}\n.dsh-ig-pill-button{display:inline-flex;align-items:center;gap:5px;height:26px;padding:0 8px 0 7px;border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:13px;background:var(--dsw-alias-bg-layer-3,#fff);color:var(--dsw-alias-label-secondary,#4b5563);font:inherit;font-size:12px;line-height:1;cursor:pointer;transition:border-color .15s,background .15s,color .15s;-webkit-user-select:none;user-select:none}\n.dsh-ig-pill-button:hover:not(:disabled){border-color:var(--dsw-alias-label-dimmed,#9ca3af);color:var(--dsw-alias-label-primary,#111827)}\n.dsh-ig-pill-button:focus-visible{outline:2px solid var(--dsw-alias-brand-primary,#4c78ff);outline-offset:1px}\n.dsh-ig-pill-button:disabled{opacity:.5;cursor:not-allowed}\n.dsh-ig-pill-button-open{border-color:var(--dsw-alias-brand-primary,#4c78ff);color:var(--dsw-alias-label-primary,#111827)}\n.dsh-ig-pill-icon{flex:none;color:var(--dsw-alias-brand-primary,#4c78ff)}\n.dsh-ig-pill-provider{max-width:96px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.dsh-ig-pill-caret{display:inline-flex;flex:none;transition:transform .15s}\n.dsh-ig-pill-caret-open{transform:rotate(180deg)}\n.dsh-ig-pill-menu{position:fixed;z-index:1000;min-width:264px;max-width:min(320px,calc(100vw - 24px));padding:6px;border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:12px;background:var(--dsw-alias-bg-layer-3,#fff);box-shadow:0 12px 32px rgba(0,0,0,.16),0 2px 8px rgba(0,0,0,.08);max-height:min(320px,calc(100vh - 48px));overflow-y:auto}\n.dsh-ig-pill-menu-title{padding:6px 8px 4px;font-size:11px;font-weight:600;color:var(--dsw-alias-label-tertiary,#6b7280)}\n.dsh-ig-pill-option{display:flex;width:100%;align-items:center;gap:9px;padding:7px 8px;border:0;border-radius:8px;background:none;font:inherit;color:inherit;text-align:left;cursor:pointer}\n.dsh-ig-pill-option:hover:not(:disabled){background:var(--dsw-alias-bg-layer-2,#f3f4f6)}\n.dsh-ig-pill-option:disabled{opacity:.6;cursor:default}\n.dsh-ig-pill-option:focus-visible{outline:2px solid var(--dsw-alias-brand-primary,#4c78ff);outline-offset:-2px}\n.dsh-ig-pill-option-active{background:var(--dsw-alias-brand-primary-soft,rgba(76,120,255,.10))}\n.dsh-ig-pill-dot{flex:none;width:7px;height:7px;border-radius:50%}\n.dsh-ig-pill-dot-ok{background:#22c55e}\n.dsh-ig-pill-dot-missing{background:var(--dsw-alias-border-l2,#d1d5db)}\n.dsh-ig-pill-dot-neutral{background:var(--dsw-alias-brand-primary,#4c78ff)}\n.dsh-ig-pill-option-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}\n.dsh-ig-pill-option-name{font-size:12.5px;font-weight:500;color:var(--dsw-alias-label-primary,#111827);line-height:1.2}\n.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}\n.dsh-ig-pill-check{flex:none;color:var(--dsw-alias-brand-primary,#4c78ff)}\n.dsh-ig-pill-error{margin-top:4px;padding:6px 8px;border-radius:8px;background:rgba(239,68,68,.08);color:#ef4444;font-size:11.5px;line-height:1.4;word-break:break-all}\n";
|
|
49
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const STUDIO_STYLE = "\n.dsh-ig-gallery-page-body.is-workbench{flex:1 1 0;height:100%;min-height:0;padding:0;overflow:hidden;display:flex;flex-direction:column}\n.dsh-ig-workbench{--ig-blue:#2f64f5;--ig-line:color-mix(in srgb,currentColor 11%,transparent);--ig-soft:color-mix(in srgb,currentColor 4%,transparent);position:relative;display:flex;flex-direction:column;min-height:0;height:100%;overflow:hidden;padding:10px 12px 12px;color:var(--foreground,#182033);box-sizing:border-box;background:radial-gradient(circle at 60% -20%,rgba(63,104,246,.07),transparent 30%)}\n.dsh-ig-workbench *{box-sizing:border-box}.dsh-ig-workbench button,.dsh-ig-workbench select,.dsh-ig-workbench textarea{font:inherit;color:inherit}\n.dsh-ig-workbench-grid{display:grid;grid-template-columns:minmax(190px,238px) minmax(0,1fr) minmax(286px,340px);grid-template-rows:minmax(0,1fr);min-height:0;height:0;flex:1 1 0;border:1px solid var(--ig-line);border-radius:12px;overflow:hidden;background:var(--background,#fff);box-shadow:0 12px 32px rgba(30,42,76,.05);transition:grid-template-columns .2s ease}\n.dsh-ig-workbench-grid.is-sidebar-collapsed{grid-template-columns:minmax(0,1fr) minmax(286px,340px)}\n.dsh-ig-recent-panel,.dsh-ig-generate-panel{min-width:0;min-height:0;overflow:hidden;background:color-mix(in srgb,var(--background,#fff) 96%,#f5f7fb)}.dsh-ig-recent-panel{display:flex;flex-direction:column;border-right:1px solid var(--ig-line)}\n.dsh-ig-panel-title{height:48px;flex:0 0 48px;padding:0 12px 0 14px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--ig-line);font-size:13px;font-weight:650}\n.dsh-ig-count-badge{font-size:11px;min-width:22px;text-align:center;padding:2px 6px;border-radius:999px;background:var(--ig-soft);color:#7b8498;font-weight:500}\n.dsh-ig-collapse-btn{width:28px;height:28px;display:inline-flex;align-items:center;justify-content:center;border:1px solid transparent;border-radius:6px;background:transparent;color:#717b90;cursor:pointer;transition:all .15s}\n.dsh-ig-collapse-btn:hover{border-color:var(--ig-line);background:var(--ig-soft);color:var(--foreground,#182033)}\n.dsh-ig-recent-scroll{flex:1 1 0;height:0;padding:8px;overflow-x:hidden;overflow-y:auto;min-height:0}.dsh-ig-recent-empty{min-height:180px;display:flex;flex-direction:column;justify-content:center;align-items:center;gap:10px;color:#929bad;text-align:center;font-size:12px}\n.dsh-ig-recent-item{display:grid;grid-template-columns:70px minmax(0,1fr);gap:10px;width:100%;padding:8px;border:1px solid transparent;border-radius:9px;background:transparent;text-align:left;cursor:pointer;transition:background .16s,border-color .16s,transform .16s}.dsh-ig-recent-item:hover{background:var(--ig-soft);transform:translateY(-1px)}.dsh-ig-recent-item.is-active{border-color:#89a7ff;background:rgba(47,100,245,.075);box-shadow:inset 3px 0 0 var(--ig-blue)}.dsh-ig-recent-thumb{width:70px;height:70px;border-radius:7px;display:flex;align-items:center;justify-content:center;overflow:hidden;background:#eef1f7;color:#929bad}.dsh-ig-recent-thumb img{width:100%;height:100%;object-fit:cover}.dsh-ig-recent-item>div:last-child{min-width:0;padding:1px 0}.dsh-ig-recent-item strong{display:block;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;font-size:12.5px;line-height:19px;font-weight:630}.dsh-ig-recent-item span,.dsh-ig-recent-item small{display:block;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;color:#828b9e;font-size:10.5px;line-height:16px}\n.dsh-ig-load-more{width:100%;height:32px;margin:8px 0;display:flex;align-items:center;justify-content:center;border:1px dashed var(--ig-line);border-radius:7px;background:transparent;font-size:11px;color:#6b758b;cursor:pointer;transition:background .15s,color .15s}.dsh-ig-load-more:hover{background:var(--ig-soft);color:var(--ig-blue);border-color:#a2b9f6}\n.dsh-ig-mini-btn{height:22px;padding:0 7px;display:inline-flex;align-items:center;gap:3px;border:1px solid var(--ig-line);border-radius:5px;background:var(--background,#fff);font-size:10.5px;font-weight:500;color:var(--foreground,#242f44);cursor:pointer;transition:all .15s}.dsh-ig-mini-btn:hover{border-color:#9bb4f5;color:var(--ig-blue);background:rgba(47,100,245,.06)}\n.dsh-ig-canvas-column{min-width:0;min-height:0;height:100%;overflow:hidden;display:flex;flex-direction:column;background:color-mix(in srgb,var(--background,#fff) 97%,#e8edf7)}\n.dsh-ig-canvas-toolbar{height:46px;flex:0 0 46px;display:flex;align-items:center;justify-content:space-between;gap:8px;padding:0 14px;border-bottom:1px solid var(--ig-line)}\n.dsh-ig-canvas-toolbar-left,.dsh-ig-canvas-toolbar-right{display:flex;align-items:center;gap:6px}\n.dsh-ig-canvas-toolbar button{height:30px;min-width:30px;padding:0 9px;display:inline-flex;align-items:center;justify-content:center;gap:5px;border:1px solid var(--ig-line);border-radius:7px;background:var(--background,#fff);color:var(--foreground,#242f44);font-size:11.5px;font-weight:500;cursor:pointer;transition:border-color .15s,background .15s,color .15s}\n.dsh-ig-canvas-toolbar button:hover{border-color:#9bb4f5;background:rgba(47,100,245,.05);color:var(--ig-blue)}\n.dsh-ig-canvas-toolbar button.is-active{border-color:#8ba8f8;background:rgba(47,100,245,.08);color:var(--ig-blue);font-weight:550}\n.dsh-ig-zoom-display{font-size:11px;min-width:38px;text-align:center;color:#64748b;user-select:none;font-variant-numeric:tabular-nums}\n.dsh-ig-status-badge-wrap{position:relative;display:inline-flex;align-items:center}\n.dsh-ig-status-badge{height:30px;display:inline-flex;align-items:center;gap:7px;padding:0 10px;border:1px solid var(--ig-line);border-radius:7px;background:var(--background,#fff);cursor:pointer;user-select:none;transition:border-color .15s,background .15s,box-shadow .15s}\n.dsh-ig-status-badge:hover{border-color:#9bb4f5;background:rgba(47,100,245,.04)}\n.dsh-ig-status-dot{width:7px;height:7px;min-width:7px;max-width:7px;border-radius:50%;flex-shrink:0;box-sizing:border-box}\n.dsh-ig-status-dot.is-ready{background:#10b981;box-shadow:0 0 0 2px rgba(16,185,129,.2)}\n.dsh-ig-status-dot.is-muted{background:#ef4444;box-shadow:0 0 0 2px rgba(239,68,68,.2)}\n.dsh-ig-status-text{font-size:11.5px;font-weight:500;color:var(--foreground,#242f44);line-height:1}\n.dsh-ig-status-arrow{color:#94a3b8;transition:transform .15s,color .15s}\n.dsh-ig-status-badge-wrap:hover .dsh-ig-status-arrow{transform:rotate(180deg);color:var(--ig-blue)}\n.dsh-ig-status-popover{position:absolute;left:0;top:calc(100% + 6px);width:260px;background:var(--background,#fff);border:1px solid var(--ig-line);border-radius:9px;box-shadow:0 12px 36px rgba(20,28,45,.14);padding:10px 12px;z-index:40;opacity:0;pointer-events:none;transform:translateY(4px);transition:opacity .15s cubic-bezier(.16,1,.3,1),transform .15s cubic-bezier(.16,1,.3,1)}\n.dsh-ig-status-badge-wrap:hover .dsh-ig-status-popover{opacity:1;pointer-events:auto;transform:translateY(0)}\n.dsh-ig-status-popover-title{display:flex;align-items:center;justify-content:space-between;font-size:10px;font-weight:650;color:#8590a6;margin-bottom:8px;letter-spacing:.02em;text-transform:uppercase}\n.dsh-ig-status-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:5px}\n.dsh-ig-status-list li{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 8px;border-radius:6px;transition:background .12s}\n.dsh-ig-status-list li.is-configured{background:rgba(16,185,129,.05);border:1px solid rgba(16,185,129,.12)}\n.dsh-ig-status-list li.is-missing{background:rgba(239,68,68,.04);border:1px solid rgba(239,68,68,.12);opacity:.75}\n.dsh-ig-status-item-name{display:flex;flex-direction:column;min-width:0}\n.dsh-ig-status-item-name strong{font-size:11.5px;font-weight:600;color:var(--foreground,#182033);line-height:16px}\n.dsh-ig-status-item-name small{font-size:9.5px;color:#7c869a;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:145px;line-height:14px}\n.dsh-ig-status-item-tag{font-size:10px;font-weight:600;padding:2px 6px;border-radius:4px;flex-shrink:0}\n.is-configured .dsh-ig-status-item-tag{color:#059669;background:rgba(16,185,129,.14)}\n.is-missing .dsh-ig-status-item-tag{color:#dc2626;background:rgba(239,68,68,.14)}\n.dsh-ig-canvas{position:relative;flex:1 1 0;height:0;min-height:0;display:flex;align-items:center;justify-content:center;overflow:hidden;padding:24px;touch-action:none;user-select:none;cursor:grab;background-image:linear-gradient(45deg,rgba(114,128,156,.035) 25%,transparent 25%),linear-gradient(-45deg,rgba(114,128,156,.035) 25%,transparent 25%),linear-gradient(45deg,transparent 75%,rgba(114,128,156,.035) 75%),linear-gradient(-45deg,transparent 75%,rgba(114,128,156,.035) 75%);background-size:24px 24px;background-position:0 0,0 12px,12px -12px,-12px 0}\n.dsh-ig-canvas.is-dragging,.dsh-ig-canvas.is-dragging *{cursor:grabbing!important}\n.dsh-ig-canvas img{display:block;max-width:100%;max-height:100%;width:auto;height:auto;border-radius:10px;box-shadow:0 14px 45px rgba(25,35,63,.18);user-select:none;-webkit-user-drag:none;pointer-events:auto}\n.dsh-ig-canvas-empty,.dsh-ig-generating-state{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;gap:12px;color:#929bad;font-size:12px;padding:26px;cursor:default}\n.dsh-ig-generating-state strong{font-size:15px;color:var(--foreground,#182033)}.dsh-ig-generating-state span{font-size:11px}.dsh-ig-generation-orbit{width:66px;height:66px;border-radius:50%;display:grid;place-items:center;color:var(--ig-blue);background:rgba(47,100,245,.09);box-shadow:0 0 0 10px rgba(47,100,245,.035);animation:dshIgPulse 1.8s ease-in-out infinite}\n.dsh-ig-result-strip{flex:0 0 auto;min-height:52px;padding:8px 14px;display:flex;align-items:center;justify-content:space-between;gap:12px;border-top:1px solid var(--ig-line)}.dsh-ig-result-strip>span{font-size:12px;font-weight:650}.dsh-ig-result-strip>div,.dsh-ig-result-actions>div{display:flex;gap:7px}.dsh-ig-result-strip button,.dsh-ig-result-actions button{height:32px;display:inline-flex;align-items:center;gap:6px;padding:0 10px;border:1px solid var(--ig-line);border-radius:7px;background:var(--background,#fff);font-size:11px;cursor:pointer}.dsh-ig-result-strip button:hover,.dsh-ig-result-actions button:hover{border-color:#9fb2ed;color:var(--ig-blue)}.dsh-ig-result-actions{flex:0 0 auto;min-height:54px;padding:8px 14px;display:flex;align-items:center;justify-content:space-between;gap:12px;border-top:1px solid var(--ig-line)}.dsh-ig-result-actions p{margin:0;min-width:0;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-size:11.5px;line-height:18px;color:#596277}.dsh-ig-result-meta{flex:0 0 auto;min-height:32px;padding:6px 14px;display:flex;gap:13px;align-items:center;flex-wrap:wrap;border-top:1px solid var(--ig-line);font-size:10px;color:#8790a3}.dsh-ig-result-meta span+span:before{content:'\u00B7';margin-right:13px}\n.dsh-ig-generate-panel{height:100%;display:flex;flex-direction:column;border-left:1px solid var(--ig-line);overflow:hidden}.dsh-ig-panel-tabs{height:48px;flex:0 0 48px;display:grid;grid-template-columns:1fr 1fr;border-bottom:1px solid var(--ig-line);padding:0 14px}.dsh-ig-panel-tabs button{position:relative;border:0;background:transparent;font-size:12px;color:#7c8598;cursor:pointer}.dsh-ig-panel-tabs button.is-active{color:var(--ig-blue);font-weight:650}.dsh-ig-panel-tabs button.is-active:after{content:'';position:absolute;left:20%;right:20%;bottom:-1px;height:2px;background:var(--ig-blue);border-radius:2px 2px 0 0}.dsh-ig-generator-form{flex:1 1 0;height:0;padding:15px;display:flex;flex-direction:column;gap:15px;overflow-x:hidden;overflow-y:auto;min-height:0}.dsh-ig-mode-switch{display:grid;grid-template-columns:1fr 1fr;gap:8px}.dsh-ig-mode-switch button{height:39px;border:1px solid var(--ig-line);border-radius:8px;background:var(--background,#fff);display:flex;align-items:center;justify-content:center;gap:7px;font-size:12px;cursor:pointer}.dsh-ig-mode-switch button.is-active{border-color:#789bff;color:var(--ig-blue);background:rgba(47,100,245,.065);box-shadow:inset 0 0 0 1px rgba(47,100,245,.1)}\n.dsh-ig-field{position:relative;display:flex;flex-direction:column;gap:7px}.dsh-ig-field>label,.dsh-ig-field-label label{font-size:11.5px;font-weight:630}.dsh-ig-field>label span{font-weight:400;color:#929bad}.dsh-ig-field-label{display:flex;align-items:center;justify-content:space-between}.dsh-ig-field-label b{color:#e14d4d}.dsh-ig-field-label button{border:0;background:transparent;color:#798397;font-size:10.5px;cursor:pointer}.dsh-ig-field textarea{width:100%;height:112px;padding:11px 12px 22px;resize:vertical;border:1px solid var(--ig-line);border-radius:9px;background:var(--background,#fff);font-size:12px;line-height:19px;outline:none}.dsh-ig-field textarea:focus{border-color:var(--ig-blue);box-shadow:0 0 0 3px rgba(47,100,245,.09)}.dsh-ig-field>small{position:absolute;right:9px;bottom:7px;color:#9aa2b2;font-size:9.5px}.dsh-ig-field-grid{display:grid;grid-template-columns:1fr 1fr;gap:9px}.dsh-ig-field-select{display:flex;flex-direction:column;gap:6px;min-width:0}.dsh-ig-field-select>span{font-size:11px;font-weight:620}.dsh-ig-field-select select{width:100%;height:36px;padding:0 26px 0 9px;border:1px solid var(--ig-line);border-radius:8px;background:var(--background,#fff);font-size:11px;outline:none;text-overflow:ellipsis}.dsh-ig-field-select select:focus{border-color:var(--ig-blue)}.dsh-ig-count-row{display:grid;grid-template-columns:repeat(4,1fr);gap:6px}.dsh-ig-count-pill{height:34px;border:1px solid var(--ig-line);border-radius:7px;background:var(--background,#fff);font-size:12px;font-weight:600;color:#596277;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .15s}.dsh-ig-count-pill:hover{border-color:#9fb2ed;color:var(--ig-blue)}.dsh-ig-count-pill.is-active{border-color:var(--ig-blue);background:rgba(47,100,245,.08);color:var(--ig-blue);box-shadow:inset 0 0 0 1px var(--ig-blue)}\n.dsh-ig-generation-kind{display:grid;grid-template-columns:1fr 1fr;gap:4px;padding:3px;border:1px solid var(--ig-line);border-radius:9px;background:var(--ig-soft)}.dsh-ig-generation-kind button{height:31px;border:0;border-radius:6px;background:transparent;color:#778196;font-size:11.5px;display:flex;align-items:center;justify-content:center;gap:6px;cursor:pointer;transition:background .15s,color .15s,box-shadow .15s}.dsh-ig-generation-kind button.is-active{background:var(--background,#fff);color:var(--ig-blue);font-weight:650;box-shadow:0 2px 8px rgba(30,42,76,.09)}\n.dsh-ig-compare-box{padding:10px;border:1px solid rgba(47,100,245,.2);border-radius:10px;background:linear-gradient(145deg,rgba(47,100,245,.055),rgba(99,102,241,.018));display:flex;flex-direction:column;gap:9px}.dsh-ig-compare-heading{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}.dsh-ig-compare-heading>div{min-width:0;display:flex;flex-direction:column;gap:2px}.dsh-ig-compare-heading strong{font-size:11.5px}.dsh-ig-compare-heading small{font-size:9.5px;color:#838da1}.dsh-ig-compare-heading>span{flex:none;padding:2px 6px;border-radius:999px;background:rgba(47,100,245,.11);color:var(--ig-blue);font-size:9.5px;font-weight:650}.dsh-ig-model-checks{display:flex;flex-direction:column;gap:6px}.dsh-ig-model-checks>button{min-height:43px;width:100%;padding:6px 7px;display:grid;grid-template-columns:18px minmax(0,1fr) auto;align-items:center;gap:7px;border:1px solid var(--ig-line);border-radius:8px;background:var(--background,#fff);text-align:left;cursor:pointer;transition:border-color .15s,background .15s,transform .15s}.dsh-ig-model-checks>button:hover{border-color:#9cb2ef;transform:translateY(-1px)}.dsh-ig-model-checks>button.is-selected{border-color:#86a4fa;background:rgba(47,100,245,.055);box-shadow:inset 3px 0 0 var(--ig-blue)}.dsh-ig-model-checkmark{width:17px;height:17px;border:1px solid #bdc6d8;border-radius:5px;display:grid;place-items:center;color:#fff;background:var(--background,#fff)}.dsh-ig-model-checks>button.is-selected .dsh-ig-model-checkmark{border-color:var(--ig-blue);background:var(--ig-blue)}.dsh-ig-model-copy{display:flex;flex-direction:column;min-width:0}.dsh-ig-model-copy strong{font-size:11px;line-height:15px}.dsh-ig-model-copy small{max-width:130px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#80899b;font-size:9.5px;line-height:14px}.dsh-ig-model-settings{display:flex;flex-direction:column;align-items:flex-end;gap:2px;color:#596277;font-size:9.5px;white-space:nowrap}.dsh-ig-model-settings em{font-style:normal;color:#a16a0a;font-size:8.5px}.dsh-ig-compare-box>p{margin:0;color:#8a7180;font-size:9.5px;line-height:14px}\n.dsh-ig-upload{height:92px;border:1px dashed #bcc6d9;border-radius:9px;background:rgba(255,255,255,.45);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;color:#7d879b;cursor:pointer}.dsh-ig-upload strong{font-size:11px;font-weight:570}.dsh-ig-upload small{font-size:9.5px}.dsh-ig-upload:hover,.dsh-ig-upload.is-dragging{border-color:var(--ig-blue);background:rgba(47,100,245,.05);color:var(--ig-blue)}\n.dsh-ig-reference-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(64px,1fr));gap:8px}\n.dsh-ig-reference-card{position:relative;aspect-ratio:1;border-radius:8px;overflow:hidden;background:#eef1f7;border:1px solid var(--ig-line)}\n.dsh-ig-reference-card img{width:100%;height:100%;object-fit:cover}\n.dsh-ig-reference-card button{position:absolute;right:4px;top:4px;width:18px;height:18px;border:0;border-radius:50%;display:grid;place-items:center;background:rgba(20,28,45,.75);color:#fff;cursor:pointer;padding:0;transition:background .15s}\n.dsh-ig-reference-card button:hover{background:#ef4444}\n.dsh-ig-reference-add{aspect-ratio:1;border:1px dashed #bcc6d9;border-radius:8px;background:rgba(255,255,255,.45);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;color:#7d879b;cursor:pointer;font-size:10px;transition:border-color .15s,color .15s,background .15s}\n.dsh-ig-reference-add:hover{border-color:var(--ig-blue);background:rgba(47,100,245,.05);color:var(--ig-blue)}\n.dsh-ig-reference-preview{position:relative;height:108px;border-radius:9px;overflow:hidden;background:#eef1f7}.dsh-ig-reference-preview img{width:100%;height:100%;object-fit:contain}.dsh-ig-reference-preview button{position:absolute;right:7px;top:7px;width:25px;height:25px;border:0;border-radius:50%;display:grid;place-items:center;background:rgba(20,28,45,.72);color:#fff;cursor:pointer}\n.dsh-ig-inline-note,.dsh-ig-form-error{padding:9px 10px;border-radius:7px;font-size:10.5px;line-height:16px}.dsh-ig-inline-note{background:#fff8e7;color:#8b671c;border:1px solid #f1dfae}.dsh-ig-form-error{background:#fff1f1;color:#b63737;border:1px solid #f2caca}.dsh-ig-form-loading{height:70px;display:grid;place-items:center;color:var(--ig-blue)}\n.dsh-ig-config-error{padding:14px;display:flex;flex-direction:column;align-items:center;gap:10px;background:#fff1f1;border:1px solid #f2caca;border-radius:8px;color:#b63737;font-size:11.5px;text-align:center}.dsh-ig-config-error p{margin:0;line-height:17px}.dsh-ig-config-error button{height:30px;display:inline-flex;align-items:center;gap:6px;padding:0 12px;border:1px solid #e0a8a8;border-radius:6px;background:#fff;color:#b63737;font-size:11.5px;font-weight:600;cursor:pointer}.dsh-ig-config-error button:hover{background:#ffebeb}\n.dsh-ig-generate-button{height:42px;flex:0 0 auto;border:0;border-radius:8px;background:linear-gradient(135deg,#386cf6,#2758e7);color:#fff!important;display:flex;align-items:center;justify-content:center;gap:8px;font-size:12px;font-weight:650;cursor:pointer;box-shadow:0 8px 18px rgba(47,100,245,.22);transition:transform .16s,box-shadow .16s}.dsh-ig-generate-button:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 10px 24px rgba(47,100,245,.28)}.dsh-ig-generate-button:disabled{opacity:.55;cursor:not-allowed;box-shadow:none}\n.dsh-ig-generate-button.is-cancel{background:linear-gradient(135deg,#ef4444,#dc2626);box-shadow:0 8px 18px rgba(239,68,68,.25)}.dsh-ig-generate-button.is-cancel:hover{background:linear-gradient(135deg,#dc2626,#b91c1c);box-shadow:0 10px 24px rgba(239,68,68,.35)}\n.dsh-ig-details{padding:16px;margin:0;overflow:auto}.dsh-ig-details>div{padding:12px 0;border-bottom:1px solid var(--ig-line)}.dsh-ig-details dt{font-size:10.5px;color:#8992a4;margin-bottom:5px}.dsh-ig-details dd{margin:0;font-size:11.5px;line-height:18px;word-break:break-word}.dsh-ig-details-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;height:220px;padding:20px;color:#929bad;font-size:11px;text-align:center}\n.dsh-ig-workbench-modal-backdrop{position:fixed;inset:0;background:rgba(15,23,42,.45);backdrop-filter:blur(3px);z-index:999;display:grid;place-items:center;padding:16px}\n.dsh-ig-workbench-modal-box{width:100%;max-width:380px;background:var(--background,#fff);border-radius:12px;padding:20px;box-shadow:0 20px 48px rgba(0,0,0,.22);display:flex;flex-direction:column;gap:14px}\n.dsh-ig-workbench-modal-header{display:flex;align-items:center;gap:10px}\n.dsh-ig-workbench-modal-header strong{font-size:14px;font-weight:650;color:#b91c1c}\n.dsh-ig-workbench-modal-desc{font-size:12px;line-height:18px;color:#555f77;margin:0}\n.dsh-ig-workbench-modal-option{display:flex;align-items:center;gap:8px;font-size:11.5px;color:#4b5563;cursor:pointer}\n.dsh-ig-workbench-modal-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:4px}\n.dsh-ig-workbench-modal-actions button{height:32px;padding:0 14px;border-radius:7px;font-size:11.5px;font-weight:600;cursor:pointer}\n.dsh-ig-workbench-modal-cancel{border:1px solid var(--ig-line);background:var(--background,#fff);color:#6b7280}\n.dsh-ig-workbench-modal-cancel:hover{background:#f3f4f6}\n.dsh-ig-workbench-modal-danger{border:0;background:#dc2626;color:#fff}\n.dsh-ig-workbench-modal-danger:hover{background:#b91c1c}\n@keyframes dshIgPulse{50%{transform:scale(1.06);box-shadow:0 0 0 16px rgba(47,100,245,.025)}}\n.dsh-ig-workbench-toast{position:fixed;bottom:28px;left:50%;transform:translateX(-50%);background:rgba(15,23,42,0.88);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);color:#fff;padding:8px 18px;border-radius:10px;font-size:12.5px;font-weight:500;box-shadow:0 12px 32px rgba(0,0,0,0.3);z-index:99999;animation:dshIgFade .15s ease-out;pointer-events:none}\n@keyframes dshIgFade{from{opacity:0;transform:translate(-50%,6px)}to{opacity:1;transform:translate(-50%,0)}}\n@media(max-width:1120px){.dsh-ig-workbench-grid{grid-template-columns:190px minmax(360px,1fr) 300px}.dsh-ig-result-actions button span{display:none}}\n@media(max-width:900px){.dsh-ig-gallery-page-body.is-workbench{height:auto;overflow:auto}.dsh-ig-workbench{height:auto;min-height:100%;overflow:visible;padding:12px}.dsh-ig-workbench-heading{height:auto;padding-bottom:12px;align-items:center}.dsh-ig-provider-quick>span{display:none}.dsh-ig-workbench-grid{height:auto;display:flex;flex:none;flex-direction:column;overflow:visible}.dsh-ig-recent-panel{height:auto;overflow:hidden;border-right:0;border-bottom:1px solid var(--ig-line)}.dsh-ig-recent-scroll{height:auto;display:flex;overflow-x:auto;overflow-y:hidden;padding:8px}.dsh-ig-recent-item{min-width:220px}.dsh-ig-canvas-column{height:auto;min-height:560px}.dsh-ig-generate-panel{height:auto;border-left:0;border-top:1px solid var(--ig-line);min-height:560px}.dsh-ig-generator-form{height:auto;overflow:visible}.dsh-ig-canvas{height:auto;min-height:360px}}\n@media(max-width:560px){.dsh-ig-workbench-heading>div{display:block}.dsh-ig-workbench-heading h1{font-size:15px}.dsh-ig-provider-quick select{min-width:128px;max-width:150px}.dsh-ig-canvas{padding:12px;min-height:300px}.dsh-ig-result-strip,.dsh-ig-result-actions{align-items:flex-start;flex-direction:column}.dsh-ig-result-strip>div,.dsh-ig-result-actions>div{width:100%}.dsh-ig-result-strip button,.dsh-ig-result-actions button{flex:1;justify-content:center}.dsh-ig-result-actions button span{display:inline}.dsh-ig-field-grid{grid-template-columns:1fr}.dsh-ig-result-meta span+span:before{display:none}}\n@media(prefers-reduced-motion:reduce){.dsh-ig-workbench *{scroll-behavior:auto!important;animation-duration:.01ms!important;transition-duration:.01ms!important}}\n.dsh-ig-field-label>span{display:flex;align-items:center;gap:5px}.dsh-ig-field-label .dsh-ig-find-inspiration{display:inline-flex;align-items:center;gap:3px;color:var(--ig-blue);font-weight:600}.dsh-ig-field-label .dsh-ig-find-inspiration:hover{color:#1644c1}\n.dsh-ig-workspace-filter-label{height:30px;display:inline-flex;align-items:center;gap:6px;padding:0 10px;border:1px solid var(--ig-line,rgba(0,0,0,.1));border-radius:7px;background:var(--background,#fff);font-size:11.5px;color:var(--foreground,#242f44);cursor:pointer;user-select:none;transition:border-color .15s,background .15s}\n.dsh-ig-workspace-filter-label:hover{border-color:#9bb4f5;background:rgba(47,100,245,.04)}\n.dsh-ig-workspace-checkbox{cursor:pointer;accent-color:#2f64f5;width:13.5px;height:13.5px;margin:0}\n.dsh-ig-workspace-filter-text{font-weight:500;white-space:nowrap}\n.dsh-ig-workspace-filter-badge{font-size:10px;font-weight:600;padding:1px 6px;border-radius:999px;background:color-mix(in srgb,currentColor 7%,transparent);color:#64748b;font-variant-numeric:tabular-nums}\n.dsh-ig-canvas-cluster{display:grid;gap:16px;align-items:center;justify-content:center;user-select:none;pointer-events:auto;flex-shrink:0}\n.dsh-ig-canvas-cluster[data-count=\"2\"]{grid-template-columns:repeat(2,1fr);max-width:880px}\n.dsh-ig-canvas-cluster[data-count=\"3\"],.dsh-ig-canvas-cluster[data-count=\"4\"]{grid-template-columns:repeat(2,1fr);max-width:760px}\n.dsh-ig-canvas-item{position:relative;display:flex;align-items:center;justify-content:center;border-radius:10px;cursor:pointer;transition:transform .12s ease-out}\n.dsh-ig-canvas-item img{display:block;max-width:100%;max-height:360px;width:auto;height:auto;object-fit:contain;border-radius:10px;box-shadow:0 10px 30px rgba(25,35,63,.16);user-select:none;-webkit-user-drag:none;pointer-events:auto;transition:box-shadow .15s,outline .15s}\n.dsh-ig-canvas-item:hover img{box-shadow:0 14px 40px rgba(47,100,245,.2)}\n.dsh-ig-canvas-item.is-active img{box-shadow:0 14px 40px rgba(47,100,245,.28)}\n.dsh-ig-canvas-item.is-checked img{outline:3px solid var(--ig-blue);outline-offset:2px;box-shadow:0 14px 40px rgba(47,100,245,.35)}\n.dsh-ig-canvas-badge{position:absolute;top:10px;left:10px;background:rgba(15,23,42,.7);color:#fff;font-size:11px;font-weight:700;padding:2px 7px;border-radius:5px;backdrop-filter:blur(4px);pointer-events:none;transition:background .15s;z-index:2}\n.dsh-ig-canvas-badge.is-model{max-width:calc(100% - 20px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600}\n.dsh-ig-canvas-item.is-checked .dsh-ig-canvas-badge{background:var(--ig-blue)}\n.dsh-ig-canvas-check{position:absolute;top:10px;right:10px;width:22px;height:22px;border:1.5px solid rgba(255,255,255,.85);border-radius:50%;display:grid;place-items:center;background:rgba(15,23,42,.48);color:#fff;box-shadow:0 2px 8px rgba(15,23,42,.18);backdrop-filter:blur(4px);z-index:2;pointer-events:none}.dsh-ig-canvas-item.is-checked .dsh-ig-canvas-check{border-color:#fff;background:var(--ig-blue)}\n.dsh-ig-canvas-item-loading{width:260px;height:260px;display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,.45);border:1px solid var(--ig-line);border-radius:10px;color:#929bad}\n.dsh-ig-lightbox-nav{position:absolute;top:50%;transform:translateY(-50%);width:42px;height:42px;border-radius:50%;border:0;background:rgba(15,23,42,.65);color:#fff;display:grid;place-items:center;cursor:pointer;transition:background .15s,transform .15s;z-index:10;backdrop-filter:blur(4px)}\n.dsh-ig-lightbox-nav:hover{background:rgba(47,100,245,.85);transform:translateY(-50%) scale(1.08)}\n.dsh-ig-lightbox-nav.is-prev{left:18px}\n.dsh-ig-lightbox-nav.is-next{right:18px}\n.dsh-ig-save-gallery-btn{color:var(--ig-blue)!important;border-color:rgba(47,100,245,.35)!important;background:rgba(47,100,245,.06)!important}\n.dsh-ig-save-gallery-btn:hover{background:rgba(47,100,245,.12)!important}\n.dsh-ig-save-gallery-btn.is-saved{color:#64748b!important;border-color:var(--ig-line)!important;background:transparent!important}\n";
|
|
1
|
+
export declare const STUDIO_STYLE = "\n.dsh-ig-gallery-page-body.is-workbench{flex:1 1 0;height:100%;min-height:0;padding:0;overflow:hidden;display:flex;flex-direction:column}\n.dsh-ig-workbench{--ig-blue:#2f64f5;--ig-line:color-mix(in srgb,currentColor 11%,transparent);--ig-soft:color-mix(in srgb,currentColor 4%,transparent);position:relative;display:flex;flex-direction:column;min-height:0;height:100%;overflow:hidden;padding:10px 12px 12px;color:var(--foreground,#182033);box-sizing:border-box;background:radial-gradient(circle at 60% -20%,rgba(63,104,246,.07),transparent 30%)}\n.dsh-ig-workbench *{box-sizing:border-box}.dsh-ig-workbench button,.dsh-ig-workbench select,.dsh-ig-workbench textarea{font:inherit;color:inherit}\n.dsh-ig-workbench-grid{display:grid;grid-template-columns:minmax(190px,238px) minmax(0,1fr) minmax(286px,340px);grid-template-rows:minmax(0,1fr);min-height:0;height:0;flex:1 1 0;border:1px solid var(--ig-line);border-radius:12px;overflow:hidden;background:var(--background,#fff);box-shadow:0 12px 32px rgba(30,42,76,.05);transition:grid-template-columns .2s ease}\n.dsh-ig-workbench-grid.is-sidebar-collapsed{grid-template-columns:minmax(0,1fr) minmax(286px,340px)}\n.dsh-ig-recent-panel,.dsh-ig-generate-panel{min-width:0;min-height:0;overflow:hidden;background:color-mix(in srgb,var(--background,#fff) 96%,#f5f7fb)}.dsh-ig-recent-panel{display:flex;flex-direction:column;border-right:1px solid var(--ig-line)}\n.dsh-ig-panel-title{height:48px;flex:0 0 48px;padding:0 12px 0 14px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--ig-line);font-size:13px;font-weight:650}\n.dsh-ig-count-badge{font-size:11px;min-width:22px;text-align:center;padding:2px 6px;border-radius:999px;background:var(--ig-soft);color:#7b8498;font-weight:500}\n.dsh-ig-collapse-btn{width:28px;height:28px;display:inline-flex;align-items:center;justify-content:center;border:1px solid transparent;border-radius:6px;background:transparent;color:#717b90;cursor:pointer;transition:all .15s}\n.dsh-ig-collapse-btn:hover{border-color:var(--ig-line);background:var(--ig-soft);color:var(--foreground,#182033)}\n.dsh-ig-recent-scroll{flex:1 1 0;height:0;padding:8px;overflow-x:hidden;overflow-y:auto;min-height:0}.dsh-ig-recent-empty{min-height:180px;display:flex;flex-direction:column;justify-content:center;align-items:center;gap:10px;color:#929bad;text-align:center;font-size:12px}\n.dsh-ig-recent-item{display:grid;grid-template-columns:70px minmax(0,1fr);gap:10px;width:100%;padding:8px;border:1px solid transparent;border-radius:9px;background:transparent;text-align:left;cursor:pointer;transition:background .16s,border-color .16s,transform .16s}.dsh-ig-recent-item:hover{background:var(--ig-soft);transform:translateY(-1px)}.dsh-ig-recent-item.is-active{border-color:#89a7ff;background:rgba(47,100,245,.075);box-shadow:inset 3px 0 0 var(--ig-blue)}.dsh-ig-recent-thumb{width:70px;height:70px;border-radius:7px;display:flex;align-items:center;justify-content:center;overflow:hidden;background:#eef1f7;color:#929bad}.dsh-ig-recent-thumb img{width:100%;height:100%;object-fit:cover}.dsh-ig-recent-item>div:last-child{min-width:0;padding:1px 0}.dsh-ig-recent-item strong{display:block;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;font-size:12.5px;line-height:19px;font-weight:630}.dsh-ig-recent-item span,.dsh-ig-recent-item small{display:block;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;color:#828b9e;font-size:10.5px;line-height:16px}\n.dsh-ig-load-more{width:100%;height:32px;margin:8px 0;display:flex;align-items:center;justify-content:center;border:1px dashed var(--ig-line);border-radius:7px;background:transparent;font-size:11px;color:#6b758b;cursor:pointer;transition:background .15s,color .15s}.dsh-ig-load-more:hover{background:var(--ig-soft);color:var(--ig-blue);border-color:#a2b9f6}\n.dsh-ig-mini-btn{height:22px;padding:0 7px;display:inline-flex;align-items:center;gap:3px;border:1px solid var(--ig-line);border-radius:5px;background:var(--background,#fff);font-size:10.5px;font-weight:500;color:var(--foreground,#242f44);cursor:pointer;transition:all .15s}.dsh-ig-mini-btn:hover{border-color:#9bb4f5;color:var(--ig-blue);background:rgba(47,100,245,.06)}\n.dsh-ig-canvas-column{min-width:0;min-height:0;height:100%;overflow:hidden;display:flex;flex-direction:column;background:color-mix(in srgb,var(--background,#fff) 97%,#e8edf7)}\n.dsh-ig-canvas-toolbar{height:46px;flex:0 0 46px;display:flex;align-items:center;justify-content:space-between;gap:8px;padding:0 14px;border-bottom:1px solid var(--ig-line)}\n.dsh-ig-canvas-toolbar-left,.dsh-ig-canvas-toolbar-right{display:flex;align-items:center;gap:6px}\n.dsh-ig-canvas-toolbar button{height:30px;min-width:30px;padding:0 9px;display:inline-flex;align-items:center;justify-content:center;gap:5px;border:1px solid var(--ig-line);border-radius:7px;background:var(--background,#fff);color:var(--foreground,#242f44);font-size:11.5px;font-weight:500;cursor:pointer;transition:border-color .15s,background .15s,color .15s}\n.dsh-ig-canvas-toolbar button:hover{border-color:#9bb4f5;background:rgba(47,100,245,.05);color:var(--ig-blue)}\n.dsh-ig-canvas-toolbar button.is-active{border-color:#8ba8f8;background:rgba(47,100,245,.08);color:var(--ig-blue);font-weight:550}\n.dsh-ig-zoom-display{font-size:11px;min-width:38px;text-align:center;color:#64748b;user-select:none;font-variant-numeric:tabular-nums}\n.dsh-ig-status-badge-wrap{position:relative;display:inline-flex;align-items:center}\n.dsh-ig-status-badge{height:30px;display:inline-flex;align-items:center;gap:7px;padding:0 10px;border:1px solid var(--ig-line);border-radius:7px;background:var(--background,#fff);cursor:pointer;user-select:none;transition:border-color .15s,background .15s,box-shadow .15s}\n.dsh-ig-status-badge:hover{border-color:#9bb4f5;background:rgba(47,100,245,.04)}\n.dsh-ig-status-dot{width:7px;height:7px;min-width:7px;max-width:7px;border-radius:50%;flex-shrink:0;box-sizing:border-box}\n.dsh-ig-status-dot.is-ready{background:#10b981;box-shadow:0 0 0 2px rgba(16,185,129,.2)}\n.dsh-ig-status-dot.is-muted{background:#ef4444;box-shadow:0 0 0 2px rgba(239,68,68,.2)}\n.dsh-ig-status-text{font-size:11.5px;font-weight:500;color:var(--foreground,#242f44);line-height:1}\n.dsh-ig-status-arrow{color:#94a3b8;transition:transform .15s,color .15s}\n.dsh-ig-status-badge-wrap:hover .dsh-ig-status-arrow{transform:rotate(180deg);color:var(--ig-blue)}\n.dsh-ig-status-popover{position:absolute;left:0;top:calc(100% + 6px);width:260px;background:var(--background,#fff);border:1px solid var(--ig-line);border-radius:9px;box-shadow:0 12px 36px rgba(20,28,45,.14);padding:10px 12px;z-index:40;opacity:0;pointer-events:none;transform:translateY(4px);transition:opacity .15s cubic-bezier(.16,1,.3,1),transform .15s cubic-bezier(.16,1,.3,1)}\n.dsh-ig-status-badge-wrap:hover .dsh-ig-status-popover{opacity:1;pointer-events:auto;transform:translateY(0)}\n.dsh-ig-status-popover-title{display:flex;align-items:center;justify-content:space-between;font-size:10px;font-weight:650;color:#8590a6;margin-bottom:8px;letter-spacing:.02em;text-transform:uppercase}\n.dsh-ig-status-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:5px}\n.dsh-ig-status-list li{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 8px;border-radius:6px;transition:background .12s}\n.dsh-ig-status-list li.is-configured{background:rgba(16,185,129,.05);border:1px solid rgba(16,185,129,.12)}\n.dsh-ig-status-list li.is-missing{background:rgba(239,68,68,.04);border:1px solid rgba(239,68,68,.12);opacity:.75}\n.dsh-ig-status-item-name{display:flex;flex-direction:column;min-width:0}\n.dsh-ig-status-item-name strong{font-size:11.5px;font-weight:600;color:var(--foreground,#182033);line-height:16px}\n.dsh-ig-status-item-name small{font-size:9.5px;color:#7c869a;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:145px;line-height:14px}\n.dsh-ig-status-item-tag{font-size:10px;font-weight:600;padding:2px 6px;border-radius:4px;flex-shrink:0}\n.is-configured .dsh-ig-status-item-tag{color:#059669;background:rgba(16,185,129,.14)}\n.is-missing .dsh-ig-status-item-tag{color:#dc2626;background:rgba(239,68,68,.14)}\n.dsh-ig-canvas{position:relative;flex:1 1 0;height:0;min-height:0;display:flex;align-items:center;justify-content:center;overflow:hidden;padding:24px;touch-action:none;user-select:none;cursor:grab;background-image:linear-gradient(45deg,rgba(114,128,156,.035) 25%,transparent 25%),linear-gradient(-45deg,rgba(114,128,156,.035) 25%,transparent 25%),linear-gradient(45deg,transparent 75%,rgba(114,128,156,.035) 75%),linear-gradient(-45deg,transparent 75%,rgba(114,128,156,.035) 75%);background-size:24px 24px;background-position:0 0,0 12px,12px -12px,-12px 0}\n.dsh-ig-canvas.is-dragging,.dsh-ig-canvas.is-dragging *{cursor:grabbing!important}\n.dsh-ig-canvas img{display:block;max-width:100%;max-height:100%;width:auto;height:auto;border-radius:10px;box-shadow:0 14px 45px rgba(25,35,63,.18);user-select:none;-webkit-user-drag:none;pointer-events:auto}\n.dsh-ig-canvas-empty,.dsh-ig-generating-state{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;gap:12px;color:#929bad;font-size:12px;padding:26px;cursor:default}\n.dsh-ig-generating-state strong{font-size:15px;color:var(--foreground,#182033)}.dsh-ig-generating-state span{font-size:11px}.dsh-ig-generation-orbit{width:66px;height:66px;border-radius:50%;display:grid;place-items:center;color:var(--ig-blue);background:rgba(47,100,245,.09);box-shadow:0 0 0 10px rgba(47,100,245,.035);animation:dshIgPulse 1.8s ease-in-out infinite}\n.dsh-ig-result-strip{flex:0 0 auto;min-height:52px;padding:8px 14px;display:flex;align-items:center;justify-content:space-between;gap:12px;border-top:1px solid var(--ig-line)}.dsh-ig-result-strip>span{font-size:12px;font-weight:650}.dsh-ig-result-strip>div,.dsh-ig-result-actions>div{display:flex;gap:7px}.dsh-ig-result-strip button,.dsh-ig-result-actions button{height:32px;display:inline-flex;align-items:center;gap:6px;padding:0 10px;border:1px solid var(--ig-line);border-radius:7px;background:var(--background,#fff);font-size:11px;cursor:pointer}.dsh-ig-result-strip button:hover,.dsh-ig-result-actions button:hover{border-color:#9fb2ed;color:var(--ig-blue)}.dsh-ig-result-actions{flex:0 0 auto;min-height:54px;padding:8px 14px;display:flex;align-items:center;justify-content:space-between;gap:12px;border-top:1px solid var(--ig-line)}.dsh-ig-result-actions p{margin:0;min-width:0;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-size:11.5px;line-height:18px;color:#596277}.dsh-ig-result-meta{flex:0 0 auto;min-height:32px;padding:6px 14px;display:flex;gap:13px;align-items:center;flex-wrap:wrap;border-top:1px solid var(--ig-line);font-size:10px;color:#8790a3}.dsh-ig-result-meta span+span:before{content:'\u00B7';margin-right:13px}\n.dsh-ig-generate-panel{height:100%;display:flex;flex-direction:column;border-left:1px solid var(--ig-line);overflow:hidden}.dsh-ig-panel-tabs{height:48px;flex:0 0 48px;display:grid;grid-template-columns:1fr 1fr;border-bottom:1px solid var(--ig-line);padding:0 14px}.dsh-ig-panel-tabs button{position:relative;border:0;background:transparent;font-size:12px;color:#7c8598;cursor:pointer}.dsh-ig-panel-tabs button.is-active{color:var(--ig-blue);font-weight:650}.dsh-ig-panel-tabs button.is-active:after{content:'';position:absolute;left:20%;right:20%;bottom:-1px;height:2px;background:var(--ig-blue);border-radius:2px 2px 0 0}.dsh-ig-generator-form{flex:1 1 0;height:0;padding:15px;display:flex;flex-direction:column;gap:15px;overflow-x:hidden;overflow-y:auto;min-height:0}.dsh-ig-mode-switch{display:grid;grid-template-columns:1fr 1fr;gap:8px}.dsh-ig-mode-switch button{height:39px;border:1px solid var(--ig-line);border-radius:8px;background:var(--background,#fff);display:flex;align-items:center;justify-content:center;gap:7px;font-size:12px;cursor:pointer}.dsh-ig-mode-switch button.is-active{border-color:#789bff;color:var(--ig-blue);background:rgba(47,100,245,.065);box-shadow:inset 0 0 0 1px rgba(47,100,245,.1)}\n.dsh-ig-field{position:relative;display:flex;flex-direction:column;gap:7px}.dsh-ig-field>label,.dsh-ig-field-label label{font-size:11.5px;font-weight:630}.dsh-ig-field>label span{font-weight:400;color:#929bad}.dsh-ig-field-label{display:flex;align-items:center;justify-content:space-between}.dsh-ig-field-label b{color:#e14d4d}.dsh-ig-field-label button{border:0;background:transparent;color:#798397;font-size:10.5px;cursor:pointer}.dsh-ig-field textarea{width:100%;height:112px;padding:11px 12px 22px;resize:vertical;border:1px solid var(--ig-line);border-radius:9px;background:var(--background,#fff);font-size:12px;line-height:19px;outline:none}.dsh-ig-field textarea:focus{border-color:var(--ig-blue);box-shadow:0 0 0 3px rgba(47,100,245,.09)}.dsh-ig-field>small{position:absolute;right:9px;bottom:7px;color:#9aa2b2;font-size:9.5px}.dsh-ig-field-grid{display:grid;grid-template-columns:1fr 1fr;gap:9px}.dsh-ig-field-select{display:flex;flex-direction:column;gap:6px;min-width:0}.dsh-ig-field-select>span{font-size:11px;font-weight:620}.dsh-ig-field-select select{width:100%;height:36px;padding:0 26px 0 9px;border:1px solid var(--ig-line);border-radius:8px;background:var(--background,#fff);font-size:11px;outline:none;text-overflow:ellipsis}.dsh-ig-field-select select:focus{border-color:var(--ig-blue)}.dsh-ig-count-row{display:grid;grid-template-columns:repeat(4,1fr);gap:6px}.dsh-ig-count-pill{height:34px;border:1px solid var(--ig-line);border-radius:7px;background:var(--background,#fff);font-size:12px;font-weight:600;color:#596277;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .15s}.dsh-ig-count-pill:hover{border-color:#9fb2ed;color:var(--ig-blue)}.dsh-ig-count-pill.is-active{border-color:var(--ig-blue);background:rgba(47,100,245,.08);color:var(--ig-blue);box-shadow:inset 0 0 0 1px var(--ig-blue)}\n.dsh-ig-generation-kind{display:grid;grid-template-columns:1fr 1fr;gap:4px;padding:3px;border:1px solid var(--ig-line);border-radius:9px;background:var(--ig-soft)}.dsh-ig-generation-kind button{height:31px;border:0;border-radius:6px;background:transparent;color:#778196;font-size:11.5px;display:flex;align-items:center;justify-content:center;gap:6px;cursor:pointer;transition:background .15s,color .15s,box-shadow .15s}.dsh-ig-generation-kind button.is-active{background:var(--background,#fff);color:var(--ig-blue);font-weight:650;box-shadow:0 2px 8px rgba(30,42,76,.09)}\n.dsh-ig-compare-box{padding:10px;border:1px solid rgba(47,100,245,.2);border-radius:10px;background:linear-gradient(145deg,rgba(47,100,245,.055),rgba(99,102,241,.018));display:flex;flex-direction:column;gap:9px}.dsh-ig-compare-heading{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}.dsh-ig-compare-heading>div{min-width:0;display:flex;flex-direction:column;gap:2px}.dsh-ig-compare-heading strong{font-size:11.5px}.dsh-ig-compare-heading small{font-size:9.5px;color:#838da1}.dsh-ig-compare-heading>span{flex:none;padding:2px 6px;border-radius:999px;background:rgba(47,100,245,.11);color:var(--ig-blue);font-size:9.5px;font-weight:650}.dsh-ig-model-checks{display:flex;flex-direction:column;gap:6px}.dsh-ig-model-checks>button{min-height:43px;width:100%;padding:6px 7px;display:grid;grid-template-columns:18px minmax(0,1fr) auto;align-items:center;gap:7px;border:1px solid var(--ig-line);border-radius:8px;background:var(--background,#fff);text-align:left;cursor:pointer;transition:border-color .15s,background .15s,transform .15s}.dsh-ig-model-checks>button:hover{border-color:#9cb2ef;transform:translateY(-1px)}.dsh-ig-model-checks>button.is-selected{border-color:#86a4fa;background:rgba(47,100,245,.055);box-shadow:inset 3px 0 0 var(--ig-blue)}.dsh-ig-model-checkmark{width:17px;height:17px;border:1px solid #bdc6d8;border-radius:5px;display:grid;place-items:center;color:#fff;background:var(--background,#fff)}.dsh-ig-model-checks>button.is-selected .dsh-ig-model-checkmark{border-color:var(--ig-blue);background:var(--ig-blue)}.dsh-ig-model-copy{display:flex;flex-direction:column;min-width:0}.dsh-ig-model-copy strong{font-size:11px;line-height:15px}.dsh-ig-model-copy small{max-width:130px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#80899b;font-size:9.5px;line-height:14px}.dsh-ig-model-settings{display:flex;flex-direction:column;align-items:flex-end;gap:2px;color:#596277;font-size:9.5px;white-space:nowrap}.dsh-ig-model-settings em{font-style:normal;color:#a16a0a;font-size:8.5px}.dsh-ig-compare-box>p{margin:0;color:#8a7180;font-size:9.5px;line-height:14px}\n.dsh-ig-upload{height:92px;border:1px dashed #bcc6d9;border-radius:9px;background:rgba(255,255,255,.45);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;color:#7d879b;cursor:pointer}.dsh-ig-upload strong{font-size:11px;font-weight:570}.dsh-ig-upload small{font-size:9.5px}.dsh-ig-upload:hover,.dsh-ig-upload.is-dragging{border-color:var(--ig-blue);background:rgba(47,100,245,.05);color:var(--ig-blue)}\n.dsh-ig-reference-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(64px,1fr));gap:8px}\n.dsh-ig-reference-card{position:relative;aspect-ratio:1;border-radius:8px;overflow:hidden;background:#eef1f7;border:1px solid var(--ig-line)}\n.dsh-ig-reference-card img{width:100%;height:100%;object-fit:cover}\n.dsh-ig-reference-card button{position:absolute;right:4px;top:4px;width:18px;height:18px;border:0;border-radius:50%;display:grid;place-items:center;background:rgba(20,28,45,.75);color:#fff;cursor:pointer;padding:0;transition:background .15s}\n.dsh-ig-reference-card button:hover{background:#ef4444}\n.dsh-ig-reference-add{aspect-ratio:1;border:1px dashed #bcc6d9;border-radius:8px;background:rgba(255,255,255,.45);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;color:#7d879b;cursor:pointer;font-size:10px;transition:border-color .15s,color .15s,background .15s}\n.dsh-ig-reference-add:hover{border-color:var(--ig-blue);background:rgba(47,100,245,.05);color:var(--ig-blue)}\n.dsh-ig-reference-preview{position:relative;height:108px;border-radius:9px;overflow:hidden;background:#eef1f7}.dsh-ig-reference-preview img{width:100%;height:100%;object-fit:contain}.dsh-ig-reference-preview button{position:absolute;right:7px;top:7px;width:25px;height:25px;border:0;border-radius:50%;display:grid;place-items:center;background:rgba(20,28,45,.72);color:#fff;cursor:pointer}\n.dsh-ig-inline-note,.dsh-ig-form-error{padding:9px 10px;border-radius:7px;font-size:10.5px;line-height:16px}.dsh-ig-inline-note{background:#fff8e7;color:#8b671c;border:1px solid #f1dfae}.dsh-ig-form-error{background:#fff1f1;color:#b63737;border:1px solid #f2caca}.dsh-ig-form-loading{height:70px;display:grid;place-items:center;color:var(--ig-blue)}\n.dsh-ig-config-error{padding:14px;display:flex;flex-direction:column;align-items:center;gap:10px;background:#fff1f1;border:1px solid #f2caca;border-radius:8px;color:#b63737;font-size:11.5px;text-align:center}.dsh-ig-config-error p{margin:0;line-height:17px}.dsh-ig-config-error button{height:30px;display:inline-flex;align-items:center;gap:6px;padding:0 12px;border:1px solid #e0a8a8;border-radius:6px;background:#fff;color:#b63737;font-size:11.5px;font-weight:600;cursor:pointer}.dsh-ig-config-error button:hover{background:#ffebeb}\n.dsh-ig-generate-button{height:42px;flex:0 0 auto;border:0;border-radius:8px;background:linear-gradient(135deg,#386cf6,#2758e7);color:#fff!important;display:flex;align-items:center;justify-content:center;gap:8px;font-size:12px;font-weight:650;cursor:pointer;box-shadow:0 8px 18px rgba(47,100,245,.22);transition:transform .16s,box-shadow .16s}.dsh-ig-generate-button:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 10px 24px rgba(47,100,245,.28)}.dsh-ig-generate-button:disabled{opacity:.55;cursor:not-allowed;box-shadow:none}\n.dsh-ig-generate-button.is-cancel{background:linear-gradient(135deg,#ef4444,#dc2626);box-shadow:0 8px 18px rgba(239,68,68,.25)}.dsh-ig-generate-button.is-cancel:hover{background:linear-gradient(135deg,#dc2626,#b91c1c);box-shadow:0 10px 24px rgba(239,68,68,.35)}\n.dsh-ig-details{padding:16px;margin:0;overflow:auto}.dsh-ig-details>div{padding:12px 0;border-bottom:1px solid var(--ig-line)}.dsh-ig-details dt{font-size:10.5px;color:#8992a4;margin-bottom:5px}.dsh-ig-details dd{margin:0;font-size:11.5px;line-height:18px;word-break:break-word}.dsh-ig-details-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;height:220px;padding:20px;color:#929bad;font-size:11px;text-align:center}\n.dsh-ig-workbench-modal-backdrop{position:fixed;inset:0;background:rgba(15,23,42,.45);backdrop-filter:blur(3px);z-index:999;display:grid;place-items:center;padding:16px}\n.dsh-ig-workbench-modal-box{width:100%;max-width:380px;background:var(--background,#fff);border-radius:12px;padding:20px;box-shadow:0 20px 48px rgba(0,0,0,.22);display:flex;flex-direction:column;gap:14px}\n.dsh-ig-workbench-modal-header{display:flex;align-items:center;gap:10px}\n.dsh-ig-workbench-modal-header strong{font-size:14px;font-weight:650;color:#b91c1c}\n.dsh-ig-workbench-modal-desc{font-size:12px;line-height:18px;color:#555f77;margin:0}\n.dsh-ig-workbench-modal-option{display:flex;align-items:center;gap:8px;font-size:11.5px;color:#4b5563;cursor:pointer}\n.dsh-ig-workbench-modal-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:4px}\n.dsh-ig-workbench-modal-actions button{height:32px;padding:0 14px;border-radius:7px;font-size:11.5px;font-weight:600;cursor:pointer}\n.dsh-ig-workbench-modal-cancel{border:1px solid var(--ig-line);background:var(--background,#fff);color:#6b7280}\n.dsh-ig-workbench-modal-cancel:hover{background:#f3f4f6}\n.dsh-ig-workbench-modal-danger{border:0;background:#dc2626;color:#fff}\n.dsh-ig-workbench-modal-danger:hover{background:#b91c1c}\n@keyframes dshIgPulse{50%{transform:scale(1.06);box-shadow:0 0 0 16px rgba(47,100,245,.025)}}\n.dsh-ig-workbench-toast{position:fixed;bottom:28px;left:50%;transform:translateX(-50%);background:rgba(15,23,42,0.88);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);color:#fff;padding:8px 18px;border-radius:10px;font-size:12.5px;font-weight:500;box-shadow:0 12px 32px rgba(0,0,0,0.3);z-index:99999;animation:dshIgFade .15s ease-out;pointer-events:none}\n@keyframes dshIgFade{from{opacity:0;transform:translate(-50%,6px)}to{opacity:1;transform:translate(-50%,0)}}\n@media(max-width:1120px){.dsh-ig-workbench-grid{grid-template-columns:190px minmax(360px,1fr) 300px}.dsh-ig-result-actions button,.dsh-ig-result-strip button{padding:0 7px;font-size:10px;gap:4px}.dsh-ig-result-actions>div,.dsh-ig-result-strip>div{gap:5px}}\n@media(max-width:900px){.dsh-ig-gallery-page-body.is-workbench{height:auto;overflow:auto}.dsh-ig-workbench{height:auto;min-height:100%;overflow:visible;padding:12px}.dsh-ig-workbench-heading{height:auto;padding-bottom:12px;align-items:center}.dsh-ig-provider-quick>span{display:none}.dsh-ig-workbench-grid{height:auto;display:flex;flex:none;flex-direction:column;overflow:visible}.dsh-ig-recent-panel{height:auto;overflow:hidden;border-right:0;border-bottom:1px solid var(--ig-line)}.dsh-ig-recent-scroll{height:auto;display:flex;overflow-x:auto;overflow-y:hidden;padding:8px}.dsh-ig-recent-item{min-width:220px}.dsh-ig-canvas-column{height:auto;min-height:560px}.dsh-ig-generate-panel{height:auto;border-left:0;border-top:1px solid var(--ig-line);min-height:560px}.dsh-ig-generator-form{height:auto;overflow:visible}.dsh-ig-canvas{height:auto;min-height:360px}}\n@media(max-width:560px){.dsh-ig-workbench-heading>div{display:block}.dsh-ig-workbench-heading h1{font-size:15px}.dsh-ig-provider-quick select{min-width:128px;max-width:150px}.dsh-ig-canvas{padding:12px;min-height:300px}.dsh-ig-result-strip,.dsh-ig-result-actions{align-items:flex-start;flex-direction:column}.dsh-ig-result-strip>div,.dsh-ig-result-actions>div{width:100%}.dsh-ig-result-strip button,.dsh-ig-result-actions button{flex:1;justify-content:center}.dsh-ig-result-actions button span{display:inline}.dsh-ig-field-grid{grid-template-columns:1fr}.dsh-ig-result-meta span+span:before{display:none}}\n@media(prefers-reduced-motion:reduce){.dsh-ig-workbench *{scroll-behavior:auto!important;animation-duration:.01ms!important;transition-duration:.01ms!important}}\n.dsh-ig-field-label>span{display:flex;align-items:center;gap:5px}.dsh-ig-field-label .dsh-ig-find-inspiration{display:inline-flex;align-items:center;gap:3px;color:var(--ig-blue);font-weight:600}.dsh-ig-field-label .dsh-ig-find-inspiration:hover{color:#1644c1}\n.dsh-ig-workspace-filter-label{height:30px;display:inline-flex;align-items:center;gap:6px;padding:0 10px;border:1px solid var(--ig-line,rgba(0,0,0,.1));border-radius:7px;background:var(--background,#fff);font-size:11.5px;color:var(--foreground,#242f44);cursor:pointer;user-select:none;transition:border-color .15s,background .15s}\n.dsh-ig-workspace-filter-label:hover{border-color:#9bb4f5;background:rgba(47,100,245,.04)}\n.dsh-ig-workspace-checkbox{cursor:pointer;accent-color:#2f64f5;width:13.5px;height:13.5px;margin:0}\n.dsh-ig-workspace-filter-text{font-weight:500;white-space:nowrap}\n.dsh-ig-workspace-filter-badge{font-size:10px;font-weight:600;padding:1px 6px;border-radius:999px;background:color-mix(in srgb,currentColor 7%,transparent);color:#64748b;font-variant-numeric:tabular-nums}\n.dsh-ig-canvas-cluster{display:grid;gap:16px;align-items:center;justify-content:center;user-select:none;pointer-events:auto;flex-shrink:0}\n.dsh-ig-canvas-cluster[data-count=\"2\"]{grid-template-columns:repeat(2,1fr);max-width:880px}\n.dsh-ig-canvas-cluster[data-count=\"3\"],.dsh-ig-canvas-cluster[data-count=\"4\"]{grid-template-columns:repeat(2,1fr);max-width:760px}\n.dsh-ig-canvas-item{position:relative;display:flex;align-items:center;justify-content:center;border-radius:10px;cursor:pointer;transition:transform .12s ease-out}\n.dsh-ig-canvas-item img{display:block;max-width:100%;max-height:360px;width:auto;height:auto;object-fit:contain;border-radius:10px;box-shadow:0 10px 30px rgba(25,35,63,.16);user-select:none;-webkit-user-drag:none;pointer-events:auto;transition:box-shadow .15s,outline .15s}\n.dsh-ig-canvas-item:hover img{box-shadow:0 14px 40px rgba(47,100,245,.2)}\n.dsh-ig-canvas-item.is-active img{box-shadow:0 14px 40px rgba(47,100,245,.28)}\n.dsh-ig-canvas-item.is-checked img{outline:3px solid var(--ig-blue);outline-offset:2px;box-shadow:0 14px 40px rgba(47,100,245,.35)}\n.dsh-ig-canvas-badge{position:absolute;top:10px;left:10px;background:rgba(15,23,42,.7);color:#fff;font-size:11px;font-weight:700;padding:2px 7px;border-radius:5px;backdrop-filter:blur(4px);pointer-events:none;transition:background .15s;z-index:2}\n.dsh-ig-canvas-badge.is-model{max-width:calc(100% - 20px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600}\n.dsh-ig-canvas-item.is-checked .dsh-ig-canvas-badge{background:var(--ig-blue)}\n.dsh-ig-canvas-check{position:absolute;top:10px;right:10px;width:22px;height:22px;border:1.5px solid rgba(255,255,255,.85);border-radius:50%;display:grid;place-items:center;background:rgba(15,23,42,.48);color:#fff;box-shadow:0 2px 8px rgba(15,23,42,.18);backdrop-filter:blur(4px);z-index:2;pointer-events:none}.dsh-ig-canvas-item.is-checked .dsh-ig-canvas-check{border-color:#fff;background:var(--ig-blue)}\n.dsh-ig-canvas-item-loading{width:260px;height:260px;display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,.45);border:1px solid var(--ig-line);border-radius:10px;color:#929bad}\n.dsh-ig-lightbox-nav{position:absolute;top:50%;transform:translateY(-50%);width:42px;height:42px;border-radius:50%;border:0;background:rgba(15,23,42,.65);color:#fff;display:grid;place-items:center;cursor:pointer;transition:background .15s,transform .15s;z-index:10;backdrop-filter:blur(4px)}\n.dsh-ig-lightbox-nav:hover{background:rgba(47,100,245,.85);transform:translateY(-50%) scale(1.08)}\n.dsh-ig-lightbox-nav.is-prev{left:18px}\n.dsh-ig-lightbox-nav.is-next{right:18px}\n.dsh-ig-save-gallery-btn{color:var(--ig-blue)!important;border-color:rgba(47,100,245,.35)!important;background:rgba(47,100,245,.06)!important}\n.dsh-ig-save-gallery-btn:hover{background:rgba(47,100,245,.12)!important}\n.dsh-ig-save-gallery-btn.is-saved{color:#64748b!important;border-color:var(--ig-line)!important;background:transparent!important}\n";
|
package/lib/types/config.d.ts
CHANGED
|
@@ -1,17 +1,9 @@
|
|
|
1
1
|
/** User-facing configuration for supported image providers. */
|
|
2
2
|
import z from '@deepseek-ai/schemastery';
|
|
3
|
-
import { DEFAULT_DASHSCOPE_ENDPOINT, DEFAULT_DASHSCOPE_MODEL, DEFAULT_COMFYUI_BASE_URL, DEFAULT_COMFYUI_TIMEOUT_MS, DEFAULT_COMFYUI_WORKFLOW_LABEL, DEFAULT_GOOGLE_ENDPOINT, DEFAULT_GOOGLE_MODEL, DEFAULT_OPENAI_BASE_URL, DEFAULT_OPENAI_MODEL, DEFAULT_SEEDREAM_BASE_URL, DEFAULT_SEEDREAM_MODEL, IMAGE_PROVIDERS, activeComfyUIWorkflow, resolveComfyUIWorkflows, type ComfyUIWorkflowEntry, type ImageProvider } from './shared.js';
|
|
4
|
-
export { DEFAULT_DASHSCOPE_ENDPOINT, DEFAULT_DASHSCOPE_MODEL, DEFAULT_COMFYUI_BASE_URL, DEFAULT_COMFYUI_TIMEOUT_MS, DEFAULT_COMFYUI_WORKFLOW_LABEL, DEFAULT_GOOGLE_ENDPOINT, DEFAULT_GOOGLE_MODEL, DEFAULT_OPENAI_BASE_URL, DEFAULT_OPENAI_MODEL, DEFAULT_SEEDREAM_BASE_URL, DEFAULT_SEEDREAM_MODEL, IMAGE_PROVIDERS, activeComfyUIWorkflow, resolveComfyUIWorkflows, type ComfyUIWorkflowEntry, type ImageProvider, };
|
|
3
|
+
import { DEFAULT_DASHSCOPE_ENDPOINT, DEFAULT_DASHSCOPE_MODEL, DEFAULT_COMFYUI_BASE_URL, DEFAULT_COMFYUI_TIMEOUT_MS, DEFAULT_COMFYUI_WORKFLOW_LABEL, DEFAULT_GOOGLE_ENDPOINT, DEFAULT_GOOGLE_MODEL, DEFAULT_OPENAI_BASE_URL, DEFAULT_OPENAI_MODEL, DEFAULT_SEEDREAM_BASE_URL, DEFAULT_SEEDREAM_MODEL, DEFAULT_XAI_BASE_URL, DEFAULT_XAI_MODEL, DEFAULT_ZHIPU_BASE_URL, DEFAULT_ZHIPU_MODEL, DASHSCOPE_API_KEY_ENV, GOOGLE_API_KEY_ENV, IMAGE_PROVIDERS, OPENAI_API_KEY_ENV, OPENAI_COMPAT_API_KEY_ENV, SEEDREAM_API_KEY_ENV, XAI_API_KEY_ENV, ZHIPU_API_KEY_ENV, activeComfyUIWorkflow, resolveComfyUIWorkflows, type ComfyUIWorkflowEntry, type ImageProvider } from './shared.js';
|
|
4
|
+
export { DEFAULT_DASHSCOPE_ENDPOINT, DEFAULT_DASHSCOPE_MODEL, DEFAULT_COMFYUI_BASE_URL, DEFAULT_COMFYUI_TIMEOUT_MS, DEFAULT_COMFYUI_WORKFLOW_LABEL, DEFAULT_GOOGLE_ENDPOINT, DEFAULT_GOOGLE_MODEL, DEFAULT_OPENAI_BASE_URL, DEFAULT_OPENAI_MODEL, DEFAULT_SEEDREAM_BASE_URL, DEFAULT_SEEDREAM_MODEL, DEFAULT_XAI_BASE_URL, DEFAULT_XAI_MODEL, DEFAULT_ZHIPU_BASE_URL, DEFAULT_ZHIPU_MODEL, DASHSCOPE_API_KEY_ENV, GOOGLE_API_KEY_ENV, IMAGE_PROVIDERS, OPENAI_API_KEY_ENV, OPENAI_COMPAT_API_KEY_ENV, SEEDREAM_API_KEY_ENV, XAI_API_KEY_ENV, ZHIPU_API_KEY_ENV, activeComfyUIWorkflow, resolveComfyUIWorkflows, type ComfyUIWorkflowEntry, type ImageProvider, };
|
|
5
5
|
/** Default workspace subfolder that receives generated image files. */
|
|
6
6
|
export declare const DEFAULT_WORKSPACE_FOLDER = "dsh-image-gen";
|
|
7
|
-
/** Google API credential reference. */
|
|
8
|
-
export declare const GOOGLE_API_KEY_ENV = "GEMINI_API_KEY";
|
|
9
|
-
/** OpenAI Platform or compatible relay credential reference. */
|
|
10
|
-
export declare const OPENAI_API_KEY_ENV = "OPENAI_API_KEY";
|
|
11
|
-
/** Volcengine Ark credential reference. */
|
|
12
|
-
export declare const SEEDREAM_API_KEY_ENV = "ARK_API_KEY";
|
|
13
|
-
/** DashScope credential reference. */
|
|
14
|
-
export declare const DASHSCOPE_API_KEY_ENV = "DASHSCOPE_API_KEY";
|
|
15
7
|
/** Google tool-level controls. */
|
|
16
8
|
export declare const ASPECT_RATIOS: readonly ["1:1", "3:2", "2:3", "4:3", "3:4", "16:9", "9:16"];
|
|
17
9
|
export declare const IMAGE_SIZES: readonly ["1K", "2K", "4K"];
|
|
@@ -24,10 +16,17 @@ export interface Config {
|
|
|
24
16
|
googleEndpoint?: string;
|
|
25
17
|
openaiBaseURL?: string;
|
|
26
18
|
openaiModel?: string;
|
|
19
|
+
/** OpenAI-compatible relay settings; independent from the official OpenAI row. */
|
|
20
|
+
openaiCompatBaseURL?: string;
|
|
21
|
+
openaiCompatModel?: string;
|
|
27
22
|
seedreamBaseURL?: string;
|
|
28
23
|
seedreamModel?: string;
|
|
29
24
|
dashscopeEndpoint?: string;
|
|
30
25
|
dashscopeModel?: string;
|
|
26
|
+
xaiBaseURL?: string;
|
|
27
|
+
xaiModel?: string;
|
|
28
|
+
zhipuBaseURL?: string;
|
|
29
|
+
zhipuModel?: string;
|
|
31
30
|
comfyuiBaseURL?: string;
|
|
32
31
|
/** Named ComfyUI workflows managed by the Web settings page. */
|
|
33
32
|
comfyuiWorkflows?: ComfyUIWorkflowEntry[];
|
|
@@ -59,6 +58,12 @@ export declare function resolveProvider(config: Config): {
|
|
|
59
58
|
model: string;
|
|
60
59
|
baseURL: string;
|
|
61
60
|
imageSize: string;
|
|
61
|
+
} | {
|
|
62
|
+
provider: 'openai-compat';
|
|
63
|
+
apiKeyEnv: string;
|
|
64
|
+
model: string;
|
|
65
|
+
baseURL: string;
|
|
66
|
+
imageSize: string;
|
|
62
67
|
} | {
|
|
63
68
|
provider: 'seedream';
|
|
64
69
|
apiKeyEnv: string;
|
|
@@ -71,6 +76,18 @@ export declare function resolveProvider(config: Config): {
|
|
|
71
76
|
model: string;
|
|
72
77
|
endpoint: string;
|
|
73
78
|
imageSize: string;
|
|
79
|
+
} | {
|
|
80
|
+
provider: 'xai';
|
|
81
|
+
apiKeyEnv: string;
|
|
82
|
+
model: string;
|
|
83
|
+
baseURL: string;
|
|
84
|
+
imageSize: string;
|
|
85
|
+
} | {
|
|
86
|
+
provider: 'zhipu';
|
|
87
|
+
apiKeyEnv: string;
|
|
88
|
+
model: string;
|
|
89
|
+
baseURL: string;
|
|
90
|
+
imageSize: string;
|
|
74
91
|
} | {
|
|
75
92
|
provider: 'comfyui';
|
|
76
93
|
baseURL: string;
|
|
@@ -78,6 +95,18 @@ export declare function resolveProvider(config: Config): {
|
|
|
78
95
|
workflow?: ComfyUIWorkflowEntry;
|
|
79
96
|
timeoutMs: number;
|
|
80
97
|
};
|
|
98
|
+
/**
|
|
99
|
+
* Apply a per-call provider and/or model override on top of the saved config.
|
|
100
|
+
* `model` is ignored for ComfyUI, whose per-call equivalent is `workflow`.
|
|
101
|
+
*/
|
|
102
|
+
export declare function withProviderOverrides(config: Config, provider?: ImageProvider, model?: string): Config;
|
|
103
|
+
/**
|
|
104
|
+
* One-time migration: when the legacy single OpenAI slot points at a relay
|
|
105
|
+
* (non-official base URL) and the compat row is empty, move the relay config
|
|
106
|
+
* to the compat row so both can coexist. Returns the input untouched when
|
|
107
|
+
* nothing needs moving.
|
|
108
|
+
*/
|
|
109
|
+
export declare function migrateOpenAICompatConfig(config: Config): Config;
|
|
81
110
|
/** The workflow a ComfyUI call runs: the requested name when given, else the active one. */
|
|
82
111
|
export declare function selectComfyUIWorkflow(active: {
|
|
83
112
|
workflows: ComfyUIWorkflowEntry[];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import { type CloudImageProvider } from './shared.js';
|
|
3
|
+
/**
|
|
4
|
+
* Resolve one provider's stored API key to a non-blank value. Blank values
|
|
5
|
+
* never count as configured: the host treats an empty stored value as absent,
|
|
6
|
+
* and a whitespace-only key is never sent to a provider.
|
|
7
|
+
*/
|
|
8
|
+
export declare function resolveApiKey(ctx: Context, provider: CloudImageProvider): Promise<string | undefined>;
|
|
9
|
+
/**
|
|
10
|
+
* Resolve one provider's API key or fail with a user-facing message that says
|
|
11
|
+
* where to configure it. Passing `tool` selects the Agent-facing English
|
|
12
|
+
* wording; without it the message is the browser-facing Chinese one used by
|
|
13
|
+
* the Studio route.
|
|
14
|
+
*/
|
|
15
|
+
export declare function requireApiKey(ctx: Context, provider: CloudImageProvider, tool?: string): Promise<string>;
|
package/lib/types/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export { Config } from './config.js';
|
|
|
5
5
|
export { IMAGE_ROUTE, DELETE_ROUTE, SAVE_WORKSPACE_ROUTE, imageAttachmentFromMeta } from './image-route.js';
|
|
6
6
|
export { STUDIO_ROUTE } from './shared.js';
|
|
7
7
|
export { INSPIRATION_ROUTE } from './shared.js';
|
|
8
|
+
export { TEST_CONNECTION_ROUTE } from './shared.js';
|
|
8
9
|
export declare const name = "dsh-image-gen";
|
|
9
10
|
export declare const inject: string[];
|
|
10
11
|
export declare function apply(ctx: Context, config?: Config): void;
|
|
@@ -9,7 +9,7 @@ export interface CompatibleReferenceImage {
|
|
|
9
9
|
mediaType: ImageMediaType;
|
|
10
10
|
}
|
|
11
11
|
export declare function generateOpenAICompatibleImage(input: {
|
|
12
|
-
provider: 'openai' | 'seedream';
|
|
12
|
+
provider: 'openai' | 'openai-compat' | 'seedream' | 'xai' | 'zhipu';
|
|
13
13
|
apiKey: string;
|
|
14
14
|
baseURL: string;
|
|
15
15
|
model: string;
|
package/lib/types/shared.d.ts
CHANGED
|
@@ -10,14 +10,45 @@ export declare const STUDIO_ROUTE = "/plugins/dsh-image-gen/studio";
|
|
|
10
10
|
export declare const INSPIRATION_ROUTE = "/plugins/dsh-image-gen/inspiration";
|
|
11
11
|
/** Browser route used for saving generated images to workspace on demand. */
|
|
12
12
|
export declare const SAVE_WORKSPACE_ROUTE = "/plugins/dsh-image-gen/save-workspace";
|
|
13
|
+
/** Browser route the settings card probes provider connectivity through. */
|
|
14
|
+
export declare const TEST_CONNECTION_ROUTE = "/plugins/dsh-image-gen/test";
|
|
13
15
|
/** Namespace persisted through DSH Settings. */
|
|
14
16
|
export declare const IMAGE_GENERATION_NAMESPACE = "image-generation";
|
|
15
17
|
/** Supported providers. */
|
|
16
|
-
export declare const IMAGE_PROVIDERS: readonly ["google", "openai", "seedream", "dashscope", "comfyui"];
|
|
18
|
+
export declare const IMAGE_PROVIDERS: readonly ["google", "openai", "openai-compat", "seedream", "dashscope", "xai", "zhipu", "comfyui"];
|
|
17
19
|
export type ImageProvider = typeof IMAGE_PROVIDERS[number];
|
|
18
20
|
/** Providers supported by the first browser workbench release. */
|
|
19
|
-
export declare const CLOUD_IMAGE_PROVIDERS: readonly ["google", "openai", "seedream", "dashscope"];
|
|
21
|
+
export declare const CLOUD_IMAGE_PROVIDERS: readonly ["google", "openai", "openai-compat", "seedream", "dashscope", "xai", "zhipu"];
|
|
20
22
|
export type CloudImageProvider = typeof CLOUD_IMAGE_PROVIDERS[number];
|
|
23
|
+
/**
|
|
24
|
+
* Credential references resolved through the DSH Credentials service (BYOK).
|
|
25
|
+
* These are POSIX-style reference names, not environment variables: the host
|
|
26
|
+
* layers the process environment and its managed store behind them, so a name
|
|
27
|
+
* like OPENAI_API_KEY is shared with any other plugin resolving the same ref.
|
|
28
|
+
*/
|
|
29
|
+
export declare const GOOGLE_API_KEY_ENV = "GEMINI_API_KEY";
|
|
30
|
+
/** OpenAI Platform credential reference. */
|
|
31
|
+
export declare const OPENAI_API_KEY_ENV = "OPENAI_API_KEY";
|
|
32
|
+
/**
|
|
33
|
+
* OpenAI-compatible relay credential reference. Deliberately distinct from
|
|
34
|
+
* OPENAI_API_KEY so an official key and a relay key can coexist without
|
|
35
|
+
* overwriting each other.
|
|
36
|
+
*/
|
|
37
|
+
export declare const OPENAI_COMPAT_API_KEY_ENV = "DSH_IMAGE_GEN_OPENAI_COMPAT_KEY";
|
|
38
|
+
/** Volcengine Ark credential reference. */
|
|
39
|
+
export declare const SEEDREAM_API_KEY_ENV = "ARK_API_KEY";
|
|
40
|
+
/** DashScope credential reference. */
|
|
41
|
+
export declare const DASHSCOPE_API_KEY_ENV = "DASHSCOPE_API_KEY";
|
|
42
|
+
/** xAI credential reference; matches the official xAI SDK environment name. */
|
|
43
|
+
export declare const XAI_API_KEY_ENV = "XAI_API_KEY";
|
|
44
|
+
/** Zhipu credential reference; matches the official Zhipu SDK environment name. */
|
|
45
|
+
export declare const ZHIPU_API_KEY_ENV = "ZHIPUAI_API_KEY";
|
|
46
|
+
/** The credential reference each cloud provider's API key is stored under. */
|
|
47
|
+
export declare const CLOUD_CREDENTIAL_REFS: Record<CloudImageProvider, string>;
|
|
48
|
+
/** The credential reference storing this provider's API key, when it uses one. */
|
|
49
|
+
export declare function cloudCredentialRef(provider: ImageProvider): string | undefined;
|
|
50
|
+
/** Locale-neutral provider names for user-facing errors and status lines. */
|
|
51
|
+
export declare const PROVIDER_DISPLAY_NAMES: Record<ImageProvider, string>;
|
|
21
52
|
/** One selectable output option exposed by a provider profile. */
|
|
22
53
|
export interface StudioOption {
|
|
23
54
|
value: string;
|
|
@@ -99,6 +130,8 @@ export declare const DEFAULT_GOOGLE_ENDPOINT = "https://generativelanguage.googl
|
|
|
99
130
|
export declare const DEFAULT_OPENAI_BASE_URL = "https://api.openai.com/v1";
|
|
100
131
|
export declare const DEFAULT_SEEDREAM_BASE_URL = "https://ark.cn-beijing.volces.com/api/v3";
|
|
101
132
|
export declare const DEFAULT_DASHSCOPE_ENDPOINT = "https://dashscope.aliyuncs.com/api/v1";
|
|
133
|
+
export declare const DEFAULT_XAI_BASE_URL = "https://api.x.ai/v1";
|
|
134
|
+
export declare const DEFAULT_ZHIPU_BASE_URL = "https://open.bigmodel.cn/api/paas/v4";
|
|
102
135
|
export declare const DEFAULT_COMFYUI_BASE_URL = "http://127.0.0.1:8188";
|
|
103
136
|
export declare const DEFAULT_COMFYUI_TIMEOUT_MS = 300000;
|
|
104
137
|
export declare const DEFAULT_COMFYUI_WORKFLOW_LABEL = "API workflow";
|
|
@@ -108,6 +141,8 @@ export declare const DEFAULT_GOOGLE_MODEL = "gemini-3.1-flash-image";
|
|
|
108
141
|
export declare const DEFAULT_OPENAI_MODEL = "gpt-image-2";
|
|
109
142
|
export declare const DEFAULT_SEEDREAM_MODEL = "doubao-seedream-5-0-260128";
|
|
110
143
|
export declare const DEFAULT_DASHSCOPE_MODEL = "qwen-image-3.0";
|
|
144
|
+
export declare const DEFAULT_XAI_MODEL = "grok-imagine-image";
|
|
145
|
+
export declare const DEFAULT_ZHIPU_MODEL = "glm-image";
|
|
111
146
|
/** One named ComfyUI API-format workflow imported through settings. */
|
|
112
147
|
export interface ComfyUIWorkflowEntry {
|
|
113
148
|
/** Unique human-readable label; used as the result model and by tool calls. */
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/** Same-origin connection probe the settings card runs per provider. */
|
|
2
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
3
|
+
import type { Config, ImageProvider } from './config.js';
|
|
4
|
+
import { type CloudImageProvider } from './shared.js';
|
|
5
|
+
export { TEST_CONNECTION_ROUTE } from './shared.js';
|
|
6
|
+
/** One probe target a provider resolves to: a URL plus its auth headers. */
|
|
7
|
+
export interface ProbeTarget {
|
|
8
|
+
url: string;
|
|
9
|
+
headers: Record<string, string>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* The endpoint each provider is probed on. All four cloud providers expose a
|
|
13
|
+
* model-list GET that authenticates with the same credential image generation
|
|
14
|
+
* uses; ComfyUI exposes its standard `system_stats` health endpoint.
|
|
15
|
+
*/
|
|
16
|
+
export declare function probeTarget(provider: ImageProvider, config: Config, apiKey?: string | undefined): ProbeTarget;
|
|
17
|
+
/** Structured probe outcome the settings card maps onto localized text. */
|
|
18
|
+
export type ProbeResult = {
|
|
19
|
+
ok: true;
|
|
20
|
+
} | {
|
|
21
|
+
ok: false;
|
|
22
|
+
reason: 'missing-key' | 'unauthorized' | 'error';
|
|
23
|
+
message?: string;
|
|
24
|
+
};
|
|
25
|
+
/** Model-pull outcome: a filtered list of image-capable model ids on success. */
|
|
26
|
+
export type ModelsResult = {
|
|
27
|
+
ok: true;
|
|
28
|
+
models: string[];
|
|
29
|
+
} | {
|
|
30
|
+
ok: false;
|
|
31
|
+
reason: 'missing-key' | 'unauthorized' | 'error';
|
|
32
|
+
message?: string;
|
|
33
|
+
};
|
|
34
|
+
/** Extract bare model ids from a Google `list models` payload (`models/{id}`). */
|
|
35
|
+
export declare function parseGoogleModelIds(payload: unknown): string[];
|
|
36
|
+
/** Heuristic filter: Gemini image models carry `image`/`imagen` in the id. */
|
|
37
|
+
export declare function filterImageModelIds(ids: readonly string[]): string[];
|
|
38
|
+
/** Narrow filter for the official OpenAI catalog: gpt-image and DALL·E families. */
|
|
39
|
+
export declare function filterOpenAIImageModelIds(ids: readonly string[]): string[];
|
|
40
|
+
/** Broad filter for relays: common image-model id fragments across vendors. */
|
|
41
|
+
export declare function filterRelayImageModelIds(ids: readonly string[]): string[];
|
|
42
|
+
/** Ark catalog filter: the Seedream (generation) and SeedEdit (editing) families. */
|
|
43
|
+
export declare function filterSeedreamImageModelIds(ids: readonly string[]): string[];
|
|
44
|
+
/** Zhipu catalog filter: GLM-Image and CogView families. */
|
|
45
|
+
export declare function filterZhipuImageModelIds(ids: readonly string[]): string[];
|
|
46
|
+
/** Extract model ids from an OpenAI-style `{data:[{id}]}` or xAI-style `{models:[{id}]}` payload. */
|
|
47
|
+
export declare function parseOpenAIModelIds(payload: unknown): string[];
|
|
48
|
+
/**
|
|
49
|
+
* Extract image-capable model ids from a DashScope native
|
|
50
|
+
* `{output:{models:[{model,capabilities}]}}` payload. The `capabilities`
|
|
51
|
+
* array marks image generation as `IG`; name fragments are a fallback for
|
|
52
|
+
* payloads that omit the field.
|
|
53
|
+
*/
|
|
54
|
+
export declare function parseDashScopeImageModelIds(payload: unknown): string[];
|
|
55
|
+
/** Pull and filter the image-capable models from the Google endpoint. */
|
|
56
|
+
export declare function fetchGoogleImageModels(config: Config, apiKey: string | undefined, signal?: AbortSignal | undefined): Promise<ModelsResult>;
|
|
57
|
+
/** Pull and filter image-capable models from an OpenAI-compatible endpoint (official, relay, Ark, xAI, Zhipu). */
|
|
58
|
+
export declare function fetchOpenAIImageModels(provider: 'openai' | 'openai-compat' | 'seedream' | 'xai' | 'zhipu', config: Config, apiKey: string | undefined, signal?: AbortSignal | undefined): Promise<ModelsResult>;
|
|
59
|
+
/** Pull and filter image-capable models from the DashScope native model list (`capabilities=IG`). */
|
|
60
|
+
export declare function fetchDashScopeImageModels(config: Config, apiKey: string | undefined, signal?: AbortSignal | undefined): Promise<ModelsResult>;
|
|
61
|
+
/** Run one provider probe and classify the outcome; secrets never leave redacted. */
|
|
62
|
+
export declare function probeProviderConnection(provider: CloudImageProvider, config: Config, apiKey: string | undefined, signal?: AbortSignal | undefined): Promise<ProbeResult>;
|
|
63
|
+
/** Probe the local ComfyUI service without any credential. */
|
|
64
|
+
export declare function probeComfyUIConnection(config: Config, signal?: AbortSignal | undefined): Promise<ProbeResult>;
|
|
65
|
+
/** Dependencies the test route needs from the plugin entry. */
|
|
66
|
+
export interface TestRouteDeps {
|
|
67
|
+
/** The credential each cloud provider probes with, when one is stored. */
|
|
68
|
+
resolveKey(provider: CloudImageProvider): Promise<string | undefined>;
|
|
69
|
+
/** The currently authoritative config, including unsaved defaults. */
|
|
70
|
+
config(): Config;
|
|
71
|
+
}
|
|
72
|
+
/** Serve the settings card's per-provider connectivity probe. */
|
|
73
|
+
export declare function serveTestConnection(req: IncomingMessage, res: ServerResponse, deps: TestRouteDeps): Promise<void>;
|