dsh-image-gen 0.9.2 → 0.10.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 +454 -452
- package/README.md +454 -452
- package/lib/client.js +984 -366
- package/lib/index.js +506 -194
- package/lib/types/client/conversation-image-revisions.d.ts +1 -0
- package/lib/types/client/conversation-regenerate.d.ts +1 -0
- package/lib/types/client/gallery-store.d.ts +1 -0
- package/lib/types/client/image-result-node.d.ts +1 -0
- package/lib/types/client/index.d.ts +8 -2
- package/lib/types/client/multi-model-compare.d.ts +3 -3
- package/lib/types/client/provider-pill.d.ts +9 -3
- package/lib/types/config.d.ts +15 -4
- package/lib/types/credentials.d.ts +2 -2
- package/lib/types/generation-timeout.d.ts +5 -0
- package/lib/types/image-tool-context.d.ts +3 -0
- package/lib/types/openai-compatible.d.ts +1 -1
- package/lib/types/shared.d.ts +57 -0
- package/lib/types/studio-route.d.ts +1 -0
- package/lib/types/studio.d.ts +1 -1
- package/lib/types/test-route.d.ts +3 -3
- package/package.json +139 -139
- package/skills/install-dsh-image-gen/SKILL.md +22 -22
|
@@ -11,6 +11,7 @@ export interface GalleryItem {
|
|
|
11
11
|
prompt: string;
|
|
12
12
|
/** Generation provider, or 'import' for user-uploaded images. */
|
|
13
13
|
provider: ImageProvider | 'import';
|
|
14
|
+
channel?: string | undefined;
|
|
14
15
|
model: string;
|
|
15
16
|
createdAt: number;
|
|
16
17
|
aspectRatio?: string | undefined;
|
|
@@ -9,27 +9,33 @@ export interface SettingsScope<T> {
|
|
|
9
9
|
set(field: string, value: unknown): Promise<boolean | void>;
|
|
10
10
|
}
|
|
11
11
|
import type { InjectFace, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
12
|
-
import { type ComfyUIWorkflowEntry, type ImageProvider } from '../shared.js';
|
|
12
|
+
import { type ComfyUIWorkflowEntry, type OpenAICompatChannel, type ImageProvider } from '../shared.js';
|
|
13
13
|
import { type LocaleService } from './gallery-view.js';
|
|
14
14
|
import { type ImageResultPresentation } from './image-result-node.js';
|
|
15
15
|
type Provider = ImageProvider;
|
|
16
16
|
interface ImageSettings {
|
|
17
17
|
provider?: Provider;
|
|
18
|
+
cloudTimeoutMs?: number;
|
|
18
19
|
googleModel?: string;
|
|
19
20
|
googleEndpoint?: string;
|
|
20
21
|
googleNative?: boolean;
|
|
21
22
|
openaiBaseURL?: string;
|
|
22
23
|
openaiModel?: string;
|
|
23
24
|
openaiSizes?: Record<string, Record<string, string>>;
|
|
25
|
+
openaiCompatLabel?: string;
|
|
24
26
|
openaiCompatBaseURL?: string;
|
|
25
27
|
openaiCompatModel?: string;
|
|
28
|
+
openaiCompatModels?: string[];
|
|
29
|
+
openaiCompatChannels?: OpenAICompatChannel[];
|
|
30
|
+
openaiCompatActiveChannel?: string;
|
|
31
|
+
openaiCompatEditModel?: string;
|
|
26
32
|
openaiCompatSizes?: Record<string, Record<string, string>>;
|
|
27
33
|
openaiCompatQuality?: string;
|
|
28
34
|
openaiCompatQualityOptions?: string[];
|
|
29
35
|
openaiCompatExtraBody?: Record<string, unknown>;
|
|
30
36
|
openaiCompatEditSizeMode?: 'auto' | 'selected';
|
|
31
37
|
/** Edit-request shape for the openai-compat relay (#41); see src/config.ts. */
|
|
32
|
-
openaiCompatEditFormat?: 'multipart' | 'jsonImageUrlArray' | 'formReferenceImages';
|
|
38
|
+
openaiCompatEditFormat?: 'multipart' | 'jsonImageUrlArray' | 'formReferenceImages' | 'siliconflowJson';
|
|
33
39
|
/** Extra JSON fields merged into the JSON edit body; ignored in multipart mode. */
|
|
34
40
|
openaiCompatEditExtra?: Record<string, unknown>;
|
|
35
41
|
seedreamBaseURL?: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type StudioOption, type StudioProvider, type StudioProviderProfile } from '../shared.js';
|
|
2
2
|
export interface ComparisonTarget {
|
|
3
3
|
profile: StudioProviderProfile;
|
|
4
4
|
ratio: string;
|
|
@@ -8,13 +8,13 @@ export interface ComparisonTarget {
|
|
|
8
8
|
generationQuality?: string;
|
|
9
9
|
}
|
|
10
10
|
/** Map one shared output intent to settings accepted by every target model. */
|
|
11
|
-
export declare function buildComparisonTargets(profiles: readonly StudioProviderProfile[],
|
|
11
|
+
export declare function buildComparisonTargets(profiles: readonly StudioProviderProfile[], selectedTargets: readonly string[], ratio: string, quality: string, output?: {
|
|
12
12
|
resolution: string;
|
|
13
13
|
generationQuality: string;
|
|
14
14
|
}): ComparisonTarget[];
|
|
15
15
|
/** Keep pixel tiers separate from upstream quality values in comparison mode. */
|
|
16
16
|
export declare function comparisonOutputOptions(profiles: readonly StudioProviderProfile[], ratio: string, kind: 'resolution' | 'generationQuality'): StudioOption[];
|
|
17
17
|
/** Start with two models, not every configured API, to avoid surprise spend. */
|
|
18
|
-
export declare function initialComparisonProviders(profiles: readonly StudioProviderProfile[], activeProvider: StudioProvider):
|
|
18
|
+
export declare function initialComparisonProviders(profiles: readonly StudioProviderProfile[], activeProvider: StudioProvider, activeChannel?: string): string[];
|
|
19
19
|
/** Union of every configured profile's options, for the shared comparison pickers. */
|
|
20
20
|
export declare function comparisonOptionUnion(profiles: readonly StudioProviderProfile[], key: 'ratioOptions' | 'qualityOptions'): StudioOption[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ComfyUIWorkflowEntry, type ImageProvider } from '../shared.js';
|
|
1
|
+
import { type ComfyUIWorkflowEntry, type OpenAICompatChannel, type ImageProvider } from '../shared.js';
|
|
2
2
|
import type { SettingsScope } from './index.js';
|
|
3
3
|
import type { LocaleService } from './gallery-view.js';
|
|
4
4
|
/** Settings fields the pill reads; a structural subset of the full settings shape. */
|
|
@@ -6,7 +6,11 @@ export interface PillSettings {
|
|
|
6
6
|
provider?: ImageProvider;
|
|
7
7
|
googleModel?: string;
|
|
8
8
|
openaiModel?: string;
|
|
9
|
+
openaiCompatLabel?: string;
|
|
9
10
|
openaiCompatModel?: string;
|
|
11
|
+
openaiCompatModels?: readonly string[];
|
|
12
|
+
openaiCompatChannels?: readonly OpenAICompatChannel[];
|
|
13
|
+
openaiCompatActiveChannel?: string;
|
|
10
14
|
seedreamModel?: string;
|
|
11
15
|
dashscopeModel?: string;
|
|
12
16
|
xaiModel?: string;
|
|
@@ -41,9 +45,11 @@ export interface ProviderPillFace {
|
|
|
41
45
|
/** Whether the user opted into the composer pill; hidden (not merely inert) when off. */
|
|
42
46
|
export declare function pillVisible(value: PillSettings | undefined): boolean;
|
|
43
47
|
/** Model (or ComfyUI workflow) a provider row will use with the persisted settings. */
|
|
44
|
-
export declare function pillModelOf(provider: ImageProvider, value: PillSettings | undefined): string;
|
|
48
|
+
export declare function pillModelOf(provider: ImageProvider, value: PillSettings | undefined, channelId?: string): string;
|
|
49
|
+
/** Optional model choices exposed by a provider; single-model providers return an empty list. */
|
|
50
|
+
export declare function pillModelOptionsOf(provider: ImageProvider, value: PillSettings | undefined, channelId?: string): string[];
|
|
45
51
|
/** One fixed-position provider menu anchored to the pill button. */
|
|
46
52
|
export declare function ImageProviderPill(props: ProviderPillFace): import("react").JSX.Element | null;
|
|
47
53
|
/** 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:28px}\n.dsh-ig-pill-button{display:inline-flex;align-items:center;gap:5px;height:28px;padding:0 9px 0 8px;border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:14px;background:var(--dsw-alias-bg-layer-3,#fff);color:var(--dsw-alias-label-secondary,#4b5563);font:inherit;font-size:13px;line-height:20px;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:150px;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@container (max-width:700px){\n .dsh-ig-pill-caret{display:none}\n .dsh-ig-pill-button{padding:0 7px 0 6px}\n}\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:#9ca3af}\n.dsh-ig-pill-dot-neutral{background:#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";
|
|
54
|
+
export declare const PROVIDER_PILL_STYLE = "\n.dsh-ig-pill-root{position:relative;display:inline-flex;align-items:center;height:28px}\n.dsh-ig-pill-button{display:inline-flex;align-items:center;gap:5px;height:28px;padding:0 9px 0 8px;border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:14px;background:var(--dsw-alias-bg-layer-3,#fff);color:var(--dsw-alias-label-secondary,#4b5563);font:inherit;font-size:13px;line-height:20px;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:150px;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@container (max-width:700px){\n .dsh-ig-pill-caret{display:none}\n .dsh-ig-pill-button{padding:0 7px 0 6px}\n}\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:#9ca3af}\n.dsh-ig-pill-dot-neutral{background:#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-model-option{padding-left:24px}\n.dsh-ig-pill-model-name{flex:1;min-width:0;font-size:12px;color:var(--dsw-alias-label-secondary,#4b5563);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
55
|
export {};
|
package/lib/types/config.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/** User-facing configuration for supported image providers. */
|
|
2
2
|
import z from '@deepseek-ai/schemastery';
|
|
3
3
|
import type { CompatEditFormat } from './openai-compatible.js';
|
|
4
|
-
import { ARK_BACKGROUND_MODES, ARK_OUTPUT_FORMATS, 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 ArkBackgroundMode, type ArkOutputFormat, type ArkOutputOptions, type ComfyUIWorkflowEntry, type ImageProvider } from './shared.js';
|
|
5
|
-
export { ARK_BACKGROUND_MODES, ARK_OUTPUT_FORMATS, 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 ArkBackgroundMode, type ArkOutputFormat, type ArkOutputOptions, type ComfyUIWorkflowEntry, type ImageProvider, };
|
|
4
|
+
import { ARK_BACKGROUND_MODES, ARK_OUTPUT_FORMATS, DEFAULT_CLOUD_TIMEOUT_MS, 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 OpenAICompatChannel, type ArkBackgroundMode, type ArkOutputFormat, type ArkOutputOptions, type ComfyUIWorkflowEntry, type ImageProvider } from './shared.js';
|
|
5
|
+
export { ARK_BACKGROUND_MODES, ARK_OUTPUT_FORMATS, DEFAULT_CLOUD_TIMEOUT_MS, 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 ArkBackgroundMode, type ArkOutputFormat, type ArkOutputOptions, type ComfyUIWorkflowEntry, type ImageProvider, };
|
|
6
6
|
/** Default workspace subfolder that receives generated image files. */
|
|
7
7
|
export declare const DEFAULT_WORKSPACE_FOLDER = "dsh-image-gen";
|
|
8
8
|
/** Google tool-level controls. Aligned with gemini-3.1-flash-image's common set. */
|
|
@@ -13,6 +13,7 @@ export type ImageSize = typeof IMAGE_SIZES[number];
|
|
|
13
13
|
/** Bundle configuration from the profile patch and the Web settings page. */
|
|
14
14
|
export interface Config {
|
|
15
15
|
provider?: ImageProvider;
|
|
16
|
+
cloudTimeoutMs?: number;
|
|
16
17
|
googleModel?: string;
|
|
17
18
|
googleEndpoint?: string;
|
|
18
19
|
/** Use Gemini generateContent instead of Interactions; opt-in for native-only gateways. */
|
|
@@ -22,8 +23,16 @@ export interface Config {
|
|
|
22
23
|
/** Official model size table: ratio -> resolution tier -> pixels. Empty uses model presets. */
|
|
23
24
|
openaiSizes?: Record<string, Record<string, string>>;
|
|
24
25
|
/** OpenAI-compatible relay settings; independent from the official OpenAI row. */
|
|
26
|
+
openaiCompatLabel?: string;
|
|
25
27
|
openaiCompatBaseURL?: string;
|
|
26
28
|
openaiCompatModel?: string;
|
|
29
|
+
/** Models offered by the workbench for the legacy default channel. */
|
|
30
|
+
openaiCompatModels?: string[];
|
|
31
|
+
/** Additional named relay channels; the flat fields above remain the default channel. */
|
|
32
|
+
openaiCompatChannels?: OpenAICompatChannel[];
|
|
33
|
+
openaiCompatActiveChannel?: string;
|
|
34
|
+
/** Editing model; empty reuses the generation model. */
|
|
35
|
+
openaiCompatEditModel?: string;
|
|
27
36
|
/** Default quality; empty preserves the upstream default by omitting the field. */
|
|
28
37
|
openaiCompatQuality?: string;
|
|
29
38
|
/** Quality values accepted by this relay; independent of resolution tiers. */
|
|
@@ -40,7 +49,7 @@ export interface Config {
|
|
|
40
49
|
* `reference_images` field is a JSON array of base64 strings. Defaults to
|
|
41
50
|
* `multipart`.
|
|
42
51
|
*/
|
|
43
|
-
openaiCompatEditFormat?: 'multipart' | 'jsonImageUrlArray' | 'formReferenceImages';
|
|
52
|
+
openaiCompatEditFormat?: 'multipart' | 'jsonImageUrlArray' | 'formReferenceImages' | 'siliconflowJson';
|
|
44
53
|
/**
|
|
45
54
|
* Extra JSON fields merged into the JSON edit body last (can override the
|
|
46
55
|
* built-in defaults), e.g. SenseNova's `watermark`/`prompt_extend`.
|
|
@@ -169,11 +178,13 @@ export declare function resolveProvider(config: Config): {
|
|
|
169
178
|
provider: 'google-sub';
|
|
170
179
|
model: string;
|
|
171
180
|
};
|
|
181
|
+
/** Project one named relay channel onto the legacy flat fields used by all provider adapters. */
|
|
182
|
+
export declare function withOpenAICompatChannel(config: Config, channelId?: string): Config;
|
|
172
183
|
/**
|
|
173
184
|
* Apply a per-call provider and/or model override on top of the saved config.
|
|
174
185
|
* `model` is ignored for ComfyUI, whose per-call equivalent is `workflow`.
|
|
175
186
|
*/
|
|
176
|
-
export declare function withProviderOverrides(config: Config, provider?: ImageProvider, model?: string): Config;
|
|
187
|
+
export declare function withProviderOverrides(config: Config, provider?: ImageProvider, model?: string, mode?: 'generate' | 'edit'): Config;
|
|
177
188
|
/**
|
|
178
189
|
* One-time migration: when the legacy single OpenAI slot points at a relay
|
|
179
190
|
* (non-official base URL) and the compat row is empty, move the relay config
|
|
@@ -5,11 +5,11 @@ import { type CloudImageProvider } from './shared.js';
|
|
|
5
5
|
* never count as configured: the host treats an empty stored value as absent,
|
|
6
6
|
* and a whitespace-only key is never sent to a provider.
|
|
7
7
|
*/
|
|
8
|
-
export declare function resolveApiKey(ctx: Context, provider: CloudImageProvider): Promise<string | undefined>;
|
|
8
|
+
export declare function resolveApiKey(ctx: Context, provider: CloudImageProvider, keyRef?: string): Promise<string | undefined>;
|
|
9
9
|
/**
|
|
10
10
|
* Resolve one provider's API key or fail with a user-facing message that says
|
|
11
11
|
* where to configure it. Passing `tool` selects the Agent-facing English
|
|
12
12
|
* wording; without it the message is the browser-facing Chinese one used by
|
|
13
13
|
* the Studio route.
|
|
14
14
|
*/
|
|
15
|
-
export declare function requireApiKey(ctx: Context, provider: CloudImageProvider, tool?: string): Promise<string>;
|
|
15
|
+
export declare function requireApiKey(ctx: Context, provider: CloudImageProvider, tool?: string, keyRef?: string): Promise<string>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const UPSTREAM_TIMEOUT_HINT = "\u4E0A\u6E38\u53EF\u80FD\u5DF2\u6263\u8D39\u6216\u4ECD\u5728\u751F\u6210\uFF0C\u8BF7\u5230\u670D\u52A1\u5546\u540E\u53F0\u786E\u8BA4";
|
|
2
|
+
export declare class GenerationTimeoutError extends Error {
|
|
3
|
+
constructor(timeoutMs: number);
|
|
4
|
+
}
|
|
5
|
+
export declare function withGenerationTimeout<T>(timeoutMs: number, signal: AbortSignal, operation: (signal: AbortSignal) => Promise<T>): Promise<T>;
|
|
@@ -32,7 +32,7 @@ export declare function generateOpenAICompatibleImage(input: {
|
|
|
32
32
|
arkOptions?: ArkOutputOptions;
|
|
33
33
|
}): Promise<GeneratedCompatibleImage>;
|
|
34
34
|
/** How the edits endpoint expects its request body (#41). */
|
|
35
|
-
export type CompatEditFormat = 'multipart' | 'jsonImageUrlArray' | 'formReferenceImages' | 'xaiJson' | 'qwenJson';
|
|
35
|
+
export type CompatEditFormat = 'multipart' | 'jsonImageUrlArray' | 'formReferenceImages' | 'siliconflowJson' | 'xaiJson' | 'qwenJson';
|
|
36
36
|
export declare function editOpenAICompatibleImage(input: {
|
|
37
37
|
apiKey: string;
|
|
38
38
|
baseURL: string;
|
package/lib/types/shared.d.ts
CHANGED
|
@@ -141,6 +141,48 @@ export declare function isSubscriptionProvider(provider: ImageProvider): provide
|
|
|
141
141
|
/** Providers supported by the first browser workbench release. */
|
|
142
142
|
export declare const CLOUD_IMAGE_PROVIDERS: readonly ["google", "openai", "openai-compat", "seedream", "dashscope", "xai", "zhipu"];
|
|
143
143
|
export type CloudImageProvider = typeof CLOUD_IMAGE_PROVIDERS[number];
|
|
144
|
+
/** Normalize the relay model list while keeping the legacy default model selectable. */
|
|
145
|
+
export declare function resolveOpenAICompatModels(config: {
|
|
146
|
+
openaiCompatModel?: string;
|
|
147
|
+
openaiCompatModels?: readonly string[];
|
|
148
|
+
}): string[];
|
|
149
|
+
export declare const DEFAULT_OPENAI_COMPAT_CHANNEL_ID = "default";
|
|
150
|
+
export interface OpenAICompatChannel {
|
|
151
|
+
id: string;
|
|
152
|
+
label: string;
|
|
153
|
+
keyRef: string;
|
|
154
|
+
baseURL: string;
|
|
155
|
+
model: string;
|
|
156
|
+
models?: string[];
|
|
157
|
+
editModel?: string;
|
|
158
|
+
quality?: string;
|
|
159
|
+
qualityOptions?: string[];
|
|
160
|
+
extraBody?: Record<string, unknown>;
|
|
161
|
+
editSizeMode?: 'auto' | 'selected';
|
|
162
|
+
editFormat?: 'multipart' | 'jsonImageUrlArray' | 'formReferenceImages' | 'siliconflowJson';
|
|
163
|
+
editExtra?: Record<string, unknown>;
|
|
164
|
+
sizes?: Record<string, Record<string, string>>;
|
|
165
|
+
}
|
|
166
|
+
export interface OpenAICompatChannelSource {
|
|
167
|
+
openaiCompatLabel?: string;
|
|
168
|
+
openaiCompatBaseURL?: string;
|
|
169
|
+
openaiCompatModel?: string;
|
|
170
|
+
openaiCompatModels?: readonly string[];
|
|
171
|
+
openaiCompatEditModel?: string;
|
|
172
|
+
openaiCompatQuality?: string;
|
|
173
|
+
openaiCompatQualityOptions?: readonly string[];
|
|
174
|
+
openaiCompatExtraBody?: Record<string, unknown>;
|
|
175
|
+
openaiCompatEditSizeMode?: 'auto' | 'selected';
|
|
176
|
+
openaiCompatEditFormat?: 'multipart' | 'jsonImageUrlArray' | 'formReferenceImages' | 'siliconflowJson';
|
|
177
|
+
openaiCompatEditExtra?: Record<string, unknown>;
|
|
178
|
+
openaiCompatSizes?: Record<string, Record<string, string>>;
|
|
179
|
+
openaiCompatChannels?: readonly OpenAICompatChannel[];
|
|
180
|
+
openaiCompatActiveChannel?: string;
|
|
181
|
+
}
|
|
182
|
+
export declare function openAICompatKeyRef(channelId: string): string;
|
|
183
|
+
/** The legacy flat fields remain the first channel; additional entries are fully independent. */
|
|
184
|
+
export declare function resolveOpenAICompatChannels(source: OpenAICompatChannelSource): OpenAICompatChannel[];
|
|
185
|
+
export declare function resolveOpenAICompatChannel(source: OpenAICompatChannelSource, channelId?: string): OpenAICompatChannel;
|
|
144
186
|
/**
|
|
145
187
|
* Providers the browser workbench can drive: the BYOK cloud set plus the
|
|
146
188
|
* logged-in subscription channels. ComfyUI stays out; it has its own workflow
|
|
@@ -148,8 +190,11 @@ export type CloudImageProvider = typeof CLOUD_IMAGE_PROVIDERS[number];
|
|
|
148
190
|
*/
|
|
149
191
|
export declare const STUDIO_PROVIDERS: readonly ["google", "openai", "openai-compat", "seedream", "dashscope", "xai", "zhipu", "chatgpt-sub", "grok-sub", "google-sub"];
|
|
150
192
|
export type StudioProvider = CloudImageProvider | SubscriptionProvider;
|
|
193
|
+
export declare function studioTargetKey(provider: StudioProvider, channel?: string): string;
|
|
151
194
|
/** True when the provider is selectable in the browser workbench. */
|
|
152
195
|
export declare function isStudioProvider(provider: ImageProvider): provider is StudioProvider;
|
|
196
|
+
/** Default timeout for API-key cloud generation in the browser workbench. */
|
|
197
|
+
export declare const DEFAULT_CLOUD_TIMEOUT_MS = 150000;
|
|
153
198
|
/** Timeout for one subscription image call, shared by the tool path and the
|
|
154
199
|
* studio route so neither drifts from the other. */
|
|
155
200
|
export declare const SUBSCRIPTION_TIMEOUT_MS = 300000;
|
|
@@ -198,8 +243,14 @@ export interface StudioWatermarkCapability {
|
|
|
198
243
|
/** Browser-safe provider description. Credentials and endpoints never cross this boundary. */
|
|
199
244
|
export interface StudioProviderProfile {
|
|
200
245
|
provider: StudioProvider;
|
|
246
|
+
/** OpenAI-compatible channel id; absent for every other provider. */
|
|
247
|
+
channel?: string;
|
|
201
248
|
label: string;
|
|
202
249
|
model: string;
|
|
250
|
+
/** Separate configured edit model; absent preserves the generation model. */
|
|
251
|
+
editModel?: string;
|
|
252
|
+
/** Selectable generation models; absent means the single default model. */
|
|
253
|
+
modelOptions?: StudioOption[];
|
|
203
254
|
configured: boolean;
|
|
204
255
|
supportsEditing: boolean;
|
|
205
256
|
ratioOptions: StudioOption[];
|
|
@@ -216,6 +267,9 @@ export interface StudioProviderProfile {
|
|
|
216
267
|
watermarkOptions?: StudioOption[];
|
|
217
268
|
watermarkCapabilities?: Record<'generate' | 'edit', StudioWatermarkCapability>;
|
|
218
269
|
}
|
|
270
|
+
/** A model picker/request must use the same operation-specific default. */
|
|
271
|
+
export declare function studioModelForMode(profile: StudioProviderProfile, mode: 'generate' | 'edit'): string;
|
|
272
|
+
export declare function studioModelOptionsForMode(profile: StudioProviderProfile, mode: 'generate' | 'edit'): StudioOption[];
|
|
219
273
|
export declare function studioWatermarkCapability(profile: StudioProviderProfile | undefined, mode: 'generate' | 'edit'): StudioWatermarkCapability;
|
|
220
274
|
/** Lightweight workspace description exposed to the client for scoping. */
|
|
221
275
|
export interface StudioWorkspaceInfo {
|
|
@@ -228,6 +282,7 @@ export interface StudioWorkspaceInfo {
|
|
|
228
282
|
export interface StudioConfigResponse {
|
|
229
283
|
providers: StudioProviderProfile[];
|
|
230
284
|
activeProvider: StudioProvider;
|
|
285
|
+
activeChannel?: string;
|
|
231
286
|
workspaceRoot?: string | undefined;
|
|
232
287
|
workspaces?: StudioWorkspaceInfo[] | undefined;
|
|
233
288
|
}
|
|
@@ -246,6 +301,7 @@ export type StudioReference = StudioEncodedReference | StudioAttachmentReference
|
|
|
246
301
|
export interface StudioGenerateRequest {
|
|
247
302
|
mode: 'generate' | 'edit';
|
|
248
303
|
provider: StudioProvider;
|
|
304
|
+
channel?: string;
|
|
249
305
|
model: string;
|
|
250
306
|
prompt: string;
|
|
251
307
|
ratio: string;
|
|
@@ -268,6 +324,7 @@ export interface StudioGeneratedItem {
|
|
|
268
324
|
/** One completed workbench request. */
|
|
269
325
|
export interface StudioGenerateResponse extends StudioGeneratedItem {
|
|
270
326
|
provider: StudioProvider;
|
|
327
|
+
channel?: string;
|
|
271
328
|
model: string;
|
|
272
329
|
prompt: string;
|
|
273
330
|
createdAt: number;
|
|
@@ -5,6 +5,7 @@ export interface StudioRouteDeps {
|
|
|
5
5
|
describe(): Promise<StudioConfigResponse>;
|
|
6
6
|
generate(input: StudioGenerateRequest, signal: AbortSignal): Promise<StudioGenerateResponse>;
|
|
7
7
|
maxBodyBytes: number;
|
|
8
|
+
timeoutMs?: number;
|
|
8
9
|
/** Heartbeat cadence for the streaming generation response; tests shrink it. */
|
|
9
10
|
heartbeatMs?: number;
|
|
10
11
|
}
|
package/lib/types/studio.d.ts
CHANGED
|
@@ -31,4 +31,4 @@ export declare function describeStudio(ctx: Context, config: Config, subscriptio
|
|
|
31
31
|
/** Execute one validated browser workbench request using the existing provider adapters. */
|
|
32
32
|
export declare function generateFromStudio(ctx: Context, config: Config, input: StudioGenerateRequest, signal: AbortSignal, fallbackWorkspaceRoot?: string | undefined, subscriptions?: SubscriptionManager | undefined): Promise<StudioGenerateResponse>;
|
|
33
33
|
export declare function runPool<T>(tasks: Array<() => Promise<T>>, concurrency?: number): Promise<PromiseSettledResult<T>[]>;
|
|
34
|
-
export declare function studioProfile(config: Config, provider: CloudImageProvider, configured: boolean): StudioProviderProfile;
|
|
34
|
+
export declare function studioProfile(config: Config, provider: CloudImageProvider, configured: boolean, channelId?: string): StudioProviderProfile;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Same-origin connection probe the settings card runs per provider. */
|
|
2
2
|
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
3
|
-
import type
|
|
3
|
+
import { type Config, type ImageProvider } from './config.js';
|
|
4
4
|
import type { SubscriptionManager } from './subscription.js';
|
|
5
5
|
import { type CloudImageProvider } from './shared.js';
|
|
6
6
|
export { TEST_CONNECTION_ROUTE } from './shared.js';
|
|
@@ -71,8 +71,8 @@ export declare function probeComfyUIConnection(config: Config, signal?: AbortSig
|
|
|
71
71
|
export declare function probeSubscriptionConnection(provider: 'chatgpt-sub' | 'grok-sub' | 'google-sub', manager: SubscriptionManager): Promise<ProbeResult>;
|
|
72
72
|
/** Dependencies the test route needs from the plugin entry. */
|
|
73
73
|
export interface TestRouteDeps {
|
|
74
|
-
/** The credential each cloud provider probes with, when one is stored. */
|
|
75
|
-
resolveKey(provider: CloudImageProvider): Promise<string | undefined>;
|
|
74
|
+
/** The credential each cloud provider or named relay channel probes with, when one is stored. */
|
|
75
|
+
resolveKey(provider: CloudImageProvider, channel?: string): Promise<string | undefined>;
|
|
76
76
|
/** The currently authoritative config, including unsaved defaults. */
|
|
77
77
|
config(): Config;
|
|
78
78
|
/** The internal subscription account manager for the login-state probes. */
|