dsh-image-gen 0.6.7 → 0.6.9
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/LICENSE +201 -21
- package/README.en.md +391 -375
- package/README.md +391 -375
- package/README.zh-CN.md +3 -3
- package/docs/assets/readme/chat-generate.webp +0 -0
- package/docs/assets/readme/other-features.webp +0 -0
- package/lib/client.js +315 -49
- package/lib/client.js.map +1 -1
- package/lib/index.js +259 -49
- package/lib/types/client/conversation-image-revisions.d.ts +2 -2
- package/lib/types/client/gallery-view.d.ts +4 -0
- package/lib/types/client/index.d.ts +7 -1
- package/lib/types/client/multi-model-compare.d.ts +3 -3
- package/lib/types/client/provider-pill.d.ts +1 -1
- package/lib/types/client/studio-chat-panel.d.ts +23 -0
- package/lib/types/client/studio-view.d.ts +4 -0
- package/lib/types/client/tl/diagram-landing.d.ts +75 -0
- package/lib/types/client/tl/diagram-layout.d.ts +76 -0
- package/lib/types/client/tl/diagram-measure.d.ts +40 -0
- package/lib/types/config.d.ts +19 -2
- package/lib/types/diagram.d.ts +42 -0
- package/lib/types/openai-compatible.d.ts +3 -0
- package/lib/types/seedream.d.ts +7 -0
- package/lib/types/shared.d.ts +55 -4
- package/lib/types/studio-chat.d.ts +48 -0
- package/lib/types/studio.d.ts +3 -2
- package/lib/types/subscription/manager.d.ts +15 -0
- package/lib/types/subscription/vendors/antigravity.d.ts +10 -1
- package/lib/types/subscription/vendors/codex.d.ts +2 -0
- package/lib/types/subscription/vendors/grok.d.ts +2 -0
- package/lib/types/subscription.d.ts +7 -5
- package/package.json +11 -9
- package/skills/install-dsh-image-gen/SKILL.md +22 -22
- package/lib/types/client/inspiration-api.d.ts +0 -10
- package/lib/types/client/inspiration-detail.d.ts +0 -14
- package/lib/types/client/tldraw/generated/tldraw-assets.d.ts +0 -12
- package/lib/types/client/tldraw/generated/tldraw-css.d.ts +0 -1
- package/lib/types/client/tldraw/tldraw-style.d.ts +0 -1
- package/lib/types/client/tldraw/tldraw-workspace.d.ts +0 -1
- package/lib/types/inspiration/cache.d.ts +0 -20
- package/lib/types/inspiration/downloader.d.ts +0 -27
- package/lib/types/inspiration/routes.d.ts +0 -13
- package/lib/types/inspiration/sources.d.ts +0 -33
- package/lib/types/inspiration/types.d.ts +0 -65
- package/lib/types/inspiration/updater.d.ts +0 -7
|
@@ -28,6 +28,12 @@ interface ImageSettings {
|
|
|
28
28
|
openaiCompatEditExtra?: Record<string, unknown>;
|
|
29
29
|
seedreamBaseURL?: string;
|
|
30
30
|
seedreamModel?: string;
|
|
31
|
+
/** Ark `output_format`; `png` is lossless and keeps an alpha channel. */
|
|
32
|
+
seedreamOutputFormat?: 'png' | 'jpeg';
|
|
33
|
+
/** Ark `watermark`; off removes the baked-in "AI generated" mark. */
|
|
34
|
+
seedreamWatermark?: boolean;
|
|
35
|
+
/** Ark `background`; `transparent` needs an alpha-bearing edit reference. */
|
|
36
|
+
seedreamBackground?: 'opaque' | 'transparent';
|
|
31
37
|
dashscopeEndpoint?: string;
|
|
32
38
|
dashscopeModel?: string;
|
|
33
39
|
xaiBaseURL?: string;
|
|
@@ -81,7 +87,7 @@ interface ImageCardFace {
|
|
|
81
87
|
locale?: LocaleService | undefined;
|
|
82
88
|
promoted: boolean;
|
|
83
89
|
}
|
|
84
|
-
type SettingsCardProps = PropsRuntime<'settings.
|
|
90
|
+
type SettingsCardProps = PropsRuntime<'settings.plugins.tab'> & InjectFace<SettingsFace>;
|
|
85
91
|
type ImageCardProps = PropsRuntime<'tool.call.toolview'> & InjectFace<ImageCardFace>;
|
|
86
92
|
interface ImageResultNodeProps {
|
|
87
93
|
node: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { StudioProvider, StudioProviderProfile } from '../shared.js';
|
|
2
2
|
export interface ComparisonTarget {
|
|
3
3
|
profile: StudioProviderProfile;
|
|
4
4
|
ratio: string;
|
|
@@ -6,6 +6,6 @@ export interface ComparisonTarget {
|
|
|
6
6
|
adjusted: boolean;
|
|
7
7
|
}
|
|
8
8
|
/** Map one shared output intent to settings accepted by every target model. */
|
|
9
|
-
export declare function buildComparisonTargets(profiles: readonly StudioProviderProfile[], selectedProviders: readonly
|
|
9
|
+
export declare function buildComparisonTargets(profiles: readonly StudioProviderProfile[], selectedProviders: readonly StudioProvider[], ratio: string, quality: string): ComparisonTarget[];
|
|
10
10
|
/** Start with two models, not every configured API, to avoid surprise spend. */
|
|
11
|
-
export declare function initialComparisonProviders(profiles: readonly StudioProviderProfile[], activeProvider:
|
|
11
|
+
export declare function initialComparisonProviders(profiles: readonly StudioProviderProfile[], activeProvider: StudioProvider): StudioProvider[];
|
|
@@ -45,5 +45,5 @@ export declare function pillModelOf(provider: ImageProvider, value: PillSettings
|
|
|
45
45
|
/** One fixed-position provider menu anchored to the pill button. */
|
|
46
46
|
export declare function ImageProviderPill(props: ProviderPillFace): import("react").JSX.Element | null;
|
|
47
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:
|
|
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";
|
|
49
49
|
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workbench chat panel: the right-side DSH conversation surface.
|
|
3
|
+
*
|
|
4
|
+
* A dedicated archived agent session lives on the host side (studio-chat.ts);
|
|
5
|
+
* this panel pulls its projected event feed through CHAT_ROUTE with adaptive
|
|
6
|
+
* polling (?since=<seq> increments; faster while a turn is running, slower
|
|
7
|
+
* when idle, paused while the webview is hidden) and submits user turns with
|
|
8
|
+
* POST. Tool-generated images are mirrored onto the tldraw canvas through the
|
|
9
|
+
* landing queue and upserted into the gallery (the recent list refreshes via
|
|
10
|
+
* its subscription). The panel is intentionally unmount-friendly: re-pulls
|
|
11
|
+
* from seq 0 on remount, and both landing and gallery writes are deduped by
|
|
12
|
+
* attachmentId, so tab switches are safe.
|
|
13
|
+
*/
|
|
14
|
+
import { type FC } from 'react';
|
|
15
|
+
/** Workspace scoping mirrored onto gallery records; shape-compatible with StudioWorkspaceProps. */
|
|
16
|
+
export interface ChatWorkspaceScope {
|
|
17
|
+
workspaceId?: string | undefined;
|
|
18
|
+
path?: string | undefined;
|
|
19
|
+
}
|
|
20
|
+
export declare const StudioChatPanel: FC<{
|
|
21
|
+
lang: 'zh' | 'en';
|
|
22
|
+
workspace?: ChatWorkspaceScope | null | undefined;
|
|
23
|
+
}>;
|
|
@@ -15,6 +15,10 @@ export interface StudioWorkspaceProps {
|
|
|
15
15
|
}
|
|
16
16
|
export declare const StudioView: FC<{
|
|
17
17
|
locale?: LocaleService | undefined;
|
|
18
|
+
/** Host credential-change notifier; re-reads provider sign-in state silently. */
|
|
19
|
+
credentialEvents?: {
|
|
20
|
+
listen(callback: () => void): () => void;
|
|
21
|
+
} | undefined;
|
|
18
22
|
workspace?: StudioWorkspaceProps | null | undefined;
|
|
19
23
|
initialPrompt?: string | undefined;
|
|
20
24
|
/**
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Land one create_diagram result onto a tldraw page.
|
|
3
|
+
*
|
|
4
|
+
* Shapes and their arrow bindings are created in a single editor.run
|
|
5
|
+
* transaction, and a history stopping point is marked BEFORE the batch:
|
|
6
|
+
* tldraw's HistoryManager pops diffs until the next stop mark on undo, so
|
|
7
|
+
* without the mark two diagrams landing back-to-back would undo together.
|
|
8
|
+
* With it, each diagram is one independent undo step (undo/redo verified
|
|
9
|
+
* against the HistoryManager source and on the real canvas).
|
|
10
|
+
*
|
|
11
|
+
* Arrows are ELBOW connectors with BOTH terminals bound. Each terminal's
|
|
12
|
+
* binding side is derived from dagre's polyline: the first/last segment's
|
|
13
|
+
* dominant axis says which node edge the route uses (back edges leave the
|
|
14
|
+
* source's top and re-enter the target's bottom through the corridor dagre
|
|
15
|
+
* reserved, instead of tldraw guessing a center-to-center route). tldraw
|
|
16
|
+
* then re-routes the middle segments itself from the bindings — the
|
|
17
|
+
* polyline is a per-terminal side hint, not a full path contract. Whether
|
|
18
|
+
* the final arrows avoid crossing nodes and whether labels sit clear of
|
|
19
|
+
* geometry is validated on the real canvas, not assumed here.
|
|
20
|
+
*
|
|
21
|
+
* Derived anchors are clamped to the middle band (0.2–0.8) of their edge:
|
|
22
|
+
* tldraw's getEdgeFromNormalizedAnchor resolves the side via |x-0.5| vs
|
|
23
|
+
* |y-0.5|, and a corner-ish anchor could resolve to the wrong side.
|
|
24
|
+
*
|
|
25
|
+
* Edge labels set labelPosition from dagre's arc-length ratio — a
|
|
26
|
+
* best-effort estimate, since tldraw applies the ratio to its own routed
|
|
27
|
+
* path.
|
|
28
|
+
*
|
|
29
|
+
* Self loops (empty dagre polyline) fall back to center bindings: tldraw
|
|
30
|
+
* draws bound self-loop arrows natively.
|
|
31
|
+
*
|
|
32
|
+
* Every created shape carries meta.diagramId, the same dedupe identity the
|
|
33
|
+
* landing reconcile uses for images' meta.galleryId.
|
|
34
|
+
*/
|
|
35
|
+
import { type Editor } from 'tldraw';
|
|
36
|
+
import { type DiagramLayout, type DiagramLayoutEdge, type DiagramLayoutNode, type DiagramPoint } from './diagram-layout.js';
|
|
37
|
+
import type { TlDiagramLanding } from './tl-canvas-bridge.js';
|
|
38
|
+
/** Terminal binding plan: the precise anchor, or a center fallback. */
|
|
39
|
+
export interface TerminalPlan {
|
|
40
|
+
anchor: {
|
|
41
|
+
x: number;
|
|
42
|
+
y: number;
|
|
43
|
+
};
|
|
44
|
+
precise: boolean;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Derive one terminal's binding side + precise anchor from dagre's
|
|
48
|
+
* polyline. The boundary point sits ON the node outline (dagre guarantees
|
|
49
|
+
* this via its node-intersection pass), so the binding side is the OUTLINE
|
|
50
|
+
* EDGE CLOSEST TO THE BOUNDARY POINT — not the segment direction. The last
|
|
51
|
+
* segment often enters at an angle because dagre projects the corridor
|
|
52
|
+
* point onto the outline (e.g. a back edge entering the target's bottom
|
|
53
|
+
* with a final dx=57, dy=-48 segment), and direction-dominance would
|
|
54
|
+
* misread that as `right`. The segment direction is only used to break
|
|
55
|
+
* exact corner ties. The boundary point gives the cross-axis position,
|
|
56
|
+
* clamped to the anchor band.
|
|
57
|
+
*/
|
|
58
|
+
export declare function terminalPlan(node: Pick<DiagramLayoutNode, 'x' | 'y' | 'w' | 'h'>, boundary: DiagramPoint, next: DiagramPoint): TerminalPlan;
|
|
59
|
+
/**
|
|
60
|
+
* Binding plans for one edge's two terminals. Self loops (no dagre
|
|
61
|
+
* polyline) get center plans: tldraw renders bound self loops natively.
|
|
62
|
+
*/
|
|
63
|
+
export declare function edgeTerminalPlans(edge: DiagramLayoutEdge, fromNode: DiagramLayoutNode, toNode: DiagramLayoutNode): {
|
|
64
|
+
start: TerminalPlan;
|
|
65
|
+
end: TerminalPlan;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Land one diagram with its top-left at `origin`. The caller passes the
|
|
69
|
+
* precomputed layout (it needs the layout bounds to pick the origin, so the
|
|
70
|
+
* layout is computed once and shared). No-op on empty layouts.
|
|
71
|
+
*/
|
|
72
|
+
export declare function landDiagram(editor: Editor, landing: TlDiagramLanding, layout: DiagramLayout, origin: {
|
|
73
|
+
x: number;
|
|
74
|
+
y: number;
|
|
75
|
+
}): void;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { DiagramNodeShape, DiagramSpec } from '../../shared.js';
|
|
2
|
+
/** One laid-out node: local id, label, outline, top-left position, size. */
|
|
3
|
+
export interface DiagramLayoutNode {
|
|
4
|
+
id: string;
|
|
5
|
+
label: string;
|
|
6
|
+
shape: DiagramNodeShape;
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
w: number;
|
|
10
|
+
h: number;
|
|
11
|
+
}
|
|
12
|
+
/** A point in graph space (same origin as the layout nodes). */
|
|
13
|
+
export interface DiagramPoint {
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
}
|
|
17
|
+
/** One laid-out edge between node local ids, with dagre's routing hint. */
|
|
18
|
+
export interface DiagramLayoutEdge {
|
|
19
|
+
from: string;
|
|
20
|
+
to: string;
|
|
21
|
+
label?: string;
|
|
22
|
+
/**
|
|
23
|
+
* dagre's polyline in graph space. points[0] lies on the source node's
|
|
24
|
+
* outline and points[last] on the target's. Self loops carry an empty
|
|
25
|
+
* array: dagre cannot route them, and the landing layer falls back to
|
|
26
|
+
* center bindings (tldraw draws bound self loops natively).
|
|
27
|
+
*/
|
|
28
|
+
points: DiagramPoint[];
|
|
29
|
+
/**
|
|
30
|
+
* Where the label sits along the polyline, as an arc-length ratio in
|
|
31
|
+
* [0, 1] (tldraw's arrow labelPosition shares the ratio semantics). This
|
|
32
|
+
* is a best-effort initial estimate: tldraw applies the ratio to its own
|
|
33
|
+
* routed path, which may differ from dagre's polyline in the middle
|
|
34
|
+
* segments. The final label position is validated on the real canvas.
|
|
35
|
+
*/
|
|
36
|
+
labelPosition?: number;
|
|
37
|
+
}
|
|
38
|
+
export interface DiagramLayout {
|
|
39
|
+
nodes: DiagramLayoutNode[];
|
|
40
|
+
edges: DiagramLayoutEdge[];
|
|
41
|
+
width: number;
|
|
42
|
+
height: number;
|
|
43
|
+
/** Growth direction of the layout, needed by the landing layer to pick
|
|
44
|
+
* binding anchors (TB connects bottom→top edges, LR right→left edges). */
|
|
45
|
+
direction: 'TB' | 'LR';
|
|
46
|
+
}
|
|
47
|
+
/** Node size in canvas units (top-left anchored, like tldraw shape props). */
|
|
48
|
+
export interface DiagramSize {
|
|
49
|
+
w: number;
|
|
50
|
+
h: number;
|
|
51
|
+
}
|
|
52
|
+
/** Measured sizes fed into the pure layout function. */
|
|
53
|
+
export interface DiagramMeasurements {
|
|
54
|
+
/** node id → measured node size. Missing entries fall back to the default. */
|
|
55
|
+
nodes: ReadonlyMap<string, DiagramSize>;
|
|
56
|
+
/**
|
|
57
|
+
* edge list index → measured label size. Only edges carrying a label are
|
|
58
|
+
* present; dagre reserves rank space for these labels.
|
|
59
|
+
*/
|
|
60
|
+
edgeLabels?: ReadonlyMap<number, DiagramSize>;
|
|
61
|
+
}
|
|
62
|
+
/** Fallback size for nodes the caller did not measure (defensive only). */
|
|
63
|
+
export declare const DEFAULT_NODE_SIZE: DiagramSize;
|
|
64
|
+
/**
|
|
65
|
+
* Where a point sits along a polyline, as an arc-length ratio in [0, 1].
|
|
66
|
+
* The point is projected onto the nearest polyline segment. Degenerate
|
|
67
|
+
* polylines return 0.5.
|
|
68
|
+
*/
|
|
69
|
+
export declare function arcRatioAlongPolyline(points: readonly DiagramPoint[], target: DiagramPoint): number;
|
|
70
|
+
/**
|
|
71
|
+
* Lay out a diagram spec with coordinates relative to (0, 0). The layout is
|
|
72
|
+
* deterministic: same spec + same measurements always produce the same
|
|
73
|
+
* coordinates (dagre is seeded by insertion order, which we keep stable by
|
|
74
|
+
* iterating the spec's arrays as given).
|
|
75
|
+
*/
|
|
76
|
+
export declare function layoutDiagram(diagram: DiagramSpec, measurements: DiagramMeasurements): DiagramLayout;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Measure diagram node/edge-label sizes with tldraw's own DOM text measuring.
|
|
3
|
+
*
|
|
4
|
+
* This is the "real" half of the measurement/layout split: the editor's
|
|
5
|
+
* TextManager renders text with the same font family, size, line height and
|
|
6
|
+
* wrap width the landed geo shapes will use, so RECTANGLE node sizes track
|
|
7
|
+
* the rendered label 1:1 (no character-width heuristics).
|
|
8
|
+
*
|
|
9
|
+
* The measure parameters mirror tldraw's internal geo-shape constants for
|
|
10
|
+
* our landed shapes (font 'sans', size 'm'): theme.fontSize * 1.375,
|
|
11
|
+
* theme.lineHeight, label padding 16.
|
|
12
|
+
*
|
|
13
|
+
* Non-rectangular outlines are APPROXIMATE, not 1:1. tldraw re-wraps the
|
|
14
|
+
* label against the SHAPE's width (shape w - padding), and we size the
|
|
15
|
+
* shape from the text measured at the pre-inflation wrap width — so after
|
|
16
|
+
* inflation the label re-wraps into fewer, wider lines. For short labels
|
|
17
|
+
* (single line at the wrap width) the geometry below is exact. For long
|
|
18
|
+
* wrapped labels the re-wrapped block can grow past the outline's inscribed
|
|
19
|
+
* rectangle and crowd the diamond's slanted edges / the ellipse's arc:
|
|
20
|
+
* greedy text wrapping scales with shape width while the inscribed rectangle
|
|
21
|
+
* only halves it, so there is no closed-form fix. The create_diagram tool
|
|
22
|
+
* prompt steers long text to rectangles and keeps diamond labels short;
|
|
23
|
+
* whether a real label fits is ultimately a visual check on the real canvas
|
|
24
|
+
* (see the diagram-verify harness), not something this module can promise.
|
|
25
|
+
* - diamond: a single-line text rect (tw, th) fits exactly when
|
|
26
|
+
* tw/w + th/h <= 1, so doubling the text size (+ padding) is exact for
|
|
27
|
+
* unwrapped labels.
|
|
28
|
+
* - ellipse: a single-line corner point fits exactly when
|
|
29
|
+
* tw²/w² + th²/h² <= 1, so a √2 factor (+ padding) is exact for
|
|
30
|
+
* unwrapped labels.
|
|
31
|
+
*/
|
|
32
|
+
import type { Editor } from 'tldraw';
|
|
33
|
+
import type { DiagramSpec } from '../../shared.js';
|
|
34
|
+
import type { DiagramMeasurements } from './diagram-layout.js';
|
|
35
|
+
/**
|
|
36
|
+
* Measure every node and edge label of a spec against the editor's live
|
|
37
|
+
* theme and fonts. Node sizes carry the outline inflation for diamond and
|
|
38
|
+
* ellipse; edge-label sizes let dagre reserve rank space for labels.
|
|
39
|
+
*/
|
|
40
|
+
export declare function measureDiagram(editor: Editor, diagram: DiagramSpec): DiagramMeasurements;
|
package/lib/types/config.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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, 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, };
|
|
3
|
+
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';
|
|
4
|
+
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, };
|
|
5
5
|
/** Default workspace subfolder that receives generated image files. */
|
|
6
6
|
export declare const DEFAULT_WORKSPACE_FOLDER = "dsh-image-gen";
|
|
7
7
|
/** Google tool-level controls. */
|
|
@@ -34,6 +34,22 @@ export interface Config {
|
|
|
34
34
|
openaiCompatEditExtra?: Record<string, unknown>;
|
|
35
35
|
seedreamBaseURL?: string;
|
|
36
36
|
seedreamModel?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Ark `output_format`. Ark defaults to `jpeg`, which is lossy and cannot
|
|
39
|
+
* carry an alpha channel; `png` is lossless, so it survives later editing
|
|
40
|
+
* (e.g. background removal) without JPEG ringing around the subject.
|
|
41
|
+
*/
|
|
42
|
+
seedreamOutputFormat?: ArkOutputFormat;
|
|
43
|
+
/**
|
|
44
|
+
* Ark `watermark`. Ark defaults to `true`, which bakes an "AI generated"
|
|
45
|
+
* mark into the bottom-right corner.
|
|
46
|
+
*/
|
|
47
|
+
seedreamWatermark?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Ark `background`. Only the edit path can honour `transparent`, and only
|
|
50
|
+
* when every reference image already carries an alpha channel.
|
|
51
|
+
*/
|
|
52
|
+
seedreamBackground?: ArkBackgroundMode;
|
|
37
53
|
dashscopeEndpoint?: string;
|
|
38
54
|
dashscopeModel?: string;
|
|
39
55
|
xaiBaseURL?: string;
|
|
@@ -85,6 +101,7 @@ export declare function resolveProvider(config: Config): {
|
|
|
85
101
|
model: string;
|
|
86
102
|
baseURL: string;
|
|
87
103
|
imageSize: string;
|
|
104
|
+
arkOptions: ArkOutputOptions;
|
|
88
105
|
} | {
|
|
89
106
|
provider: 'dashscope';
|
|
90
107
|
apiKeyEnv: string;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* create_diagram: a structure-only tool whose results land on the workbench
|
|
3
|
+
* infinite canvas.
|
|
4
|
+
*
|
|
5
|
+
* The model outputs a declarative DSL (nodes + edges with local ids, never
|
|
6
|
+
* coordinates). The tool call succeeds immediately — exactly like image
|
|
7
|
+
* generation — and the diagram rides the same landing bus: an open canvas
|
|
8
|
+
* renders it at once, a closed one renders it the moment it opens. The canvas
|
|
9
|
+
* computes the layered layout, creates geo shapes, and binds every arrow to
|
|
10
|
+
* its endpoints so the user can drag nodes around with arrows following.
|
|
11
|
+
*/
|
|
12
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
13
|
+
import { type DiagramDirection, type DiagramEdgeSpec, type DiagramNodeSpec } from './shared.js';
|
|
14
|
+
/** Value returned by create_diagram and echoed into the tool-result schema. */
|
|
15
|
+
export interface CreateDiagramValue {
|
|
16
|
+
diagramId: string;
|
|
17
|
+
title: string;
|
|
18
|
+
direction: DiagramDirection;
|
|
19
|
+
nodeCount: number;
|
|
20
|
+
edgeCount: number;
|
|
21
|
+
}
|
|
22
|
+
/** Untrusted create_diagram arguments as they arrive from the model. */
|
|
23
|
+
export interface CreateDiagramArgs {
|
|
24
|
+
title?: unknown;
|
|
25
|
+
direction?: unknown;
|
|
26
|
+
nodes?: unknown;
|
|
27
|
+
edges?: unknown;
|
|
28
|
+
}
|
|
29
|
+
/** Register the create_diagram tool on a host context. */
|
|
30
|
+
export declare function registerDiagramTool(ctx: Context): void;
|
|
31
|
+
/**
|
|
32
|
+
* Validate untrusted create_diagram arguments into a DiagramSpec. Returns
|
|
33
|
+
* undefined for anything structurally unusable (no nodes, duplicate ids,
|
|
34
|
+
* edges pointing at unknown nodes, over the caps) — the tool then fails with
|
|
35
|
+
* an actionable message and the model can retry with a corrected diagram.
|
|
36
|
+
*/
|
|
37
|
+
export declare function diagramSpecFromArgs(args: CreateDiagramArgs): {
|
|
38
|
+
title?: string;
|
|
39
|
+
direction?: DiagramDirection;
|
|
40
|
+
nodes: DiagramNodeSpec[];
|
|
41
|
+
edges: DiagramEdgeSpec[];
|
|
42
|
+
} | undefined;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/** OpenAI Images API and compatible response adapter. */
|
|
2
2
|
import type { ImageMediaType } from '@deepseek-ai/dsh-attachment';
|
|
3
|
+
import { type ArkOutputOptions } from './shared.js';
|
|
3
4
|
export interface GeneratedCompatibleImage {
|
|
4
5
|
data: Uint8Array;
|
|
5
6
|
mediaType: ImageMediaType;
|
|
@@ -17,6 +18,8 @@ export declare function generateOpenAICompatibleImage(input: {
|
|
|
17
18
|
size: string;
|
|
18
19
|
maxBytes: number;
|
|
19
20
|
signal: AbortSignal;
|
|
21
|
+
/** Ark-only output controls; ignored by every other provider. */
|
|
22
|
+
arkOptions?: ArkOutputOptions;
|
|
20
23
|
}): Promise<GeneratedCompatibleImage>;
|
|
21
24
|
/** How the edits endpoint expects its request body (#41). */
|
|
22
25
|
export type CompatEditFormat = 'multipart' | 'jsonImageUrlArray';
|
package/lib/types/seedream.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/** Volcengine Ark Seedream image-editing adapter. */
|
|
2
2
|
import type { ImageMediaType } from '@deepseek-ai/dsh-attachment';
|
|
3
3
|
import type { GeneratedCompatibleImage } from './openai-compatible.js';
|
|
4
|
+
import { type ArkOutputOptions } from './shared.js';
|
|
4
5
|
/** Edit one image through Ark ImageGenerations using a data-URL reference. */
|
|
5
6
|
export declare function editSeedreamImage(input: {
|
|
6
7
|
apiKey: string;
|
|
@@ -14,4 +15,10 @@ export declare function editSeedreamImage(input: {
|
|
|
14
15
|
size?: string;
|
|
15
16
|
maxBytes: number;
|
|
16
17
|
signal: AbortSignal;
|
|
18
|
+
/**
|
|
19
|
+
* Ark output controls. The edit path is the only one Ark lets request a
|
|
20
|
+
* transparent background, and it requires every reference image to carry an
|
|
21
|
+
* alpha channel — see `arkOutputBody`.
|
|
22
|
+
*/
|
|
23
|
+
arkOptions?: ArkOutputOptions;
|
|
17
24
|
}): Promise<GeneratedCompatibleImage>;
|
package/lib/types/shared.d.ts
CHANGED
|
@@ -117,6 +117,18 @@ export declare function isSubscriptionProvider(provider: ImageProvider): provide
|
|
|
117
117
|
/** Providers supported by the first browser workbench release. */
|
|
118
118
|
export declare const CLOUD_IMAGE_PROVIDERS: readonly ["google", "openai", "openai-compat", "seedream", "dashscope", "xai", "zhipu"];
|
|
119
119
|
export type CloudImageProvider = typeof CLOUD_IMAGE_PROVIDERS[number];
|
|
120
|
+
/**
|
|
121
|
+
* Providers the browser workbench can drive: the BYOK cloud set plus the
|
|
122
|
+
* logged-in subscription channels. ComfyUI stays out; it has its own workflow
|
|
123
|
+
* pipeline and no shared request shape.
|
|
124
|
+
*/
|
|
125
|
+
export declare const STUDIO_PROVIDERS: readonly ["google", "openai", "openai-compat", "seedream", "dashscope", "xai", "zhipu", "chatgpt-sub", "grok-sub", "google-sub"];
|
|
126
|
+
export type StudioProvider = CloudImageProvider | SubscriptionProvider;
|
|
127
|
+
/** True when the provider is selectable in the browser workbench. */
|
|
128
|
+
export declare function isStudioProvider(provider: ImageProvider): provider is StudioProvider;
|
|
129
|
+
/** Timeout for one subscription image call, shared by the tool path and the
|
|
130
|
+
* studio route so neither drifts from the other. */
|
|
131
|
+
export declare const SUBSCRIPTION_TIMEOUT_MS = 300000;
|
|
120
132
|
/**
|
|
121
133
|
* Credential references resolved through the DSH Credentials service (BYOK).
|
|
122
134
|
* These are POSIX-style reference names, not environment variables: the host
|
|
@@ -155,7 +167,7 @@ export interface StudioOption {
|
|
|
155
167
|
}
|
|
156
168
|
/** Browser-safe provider description. Credentials and endpoints never cross this boundary. */
|
|
157
169
|
export interface StudioProviderProfile {
|
|
158
|
-
provider:
|
|
170
|
+
provider: StudioProvider;
|
|
159
171
|
label: string;
|
|
160
172
|
model: string;
|
|
161
173
|
configured: boolean;
|
|
@@ -175,7 +187,7 @@ export interface StudioWorkspaceInfo {
|
|
|
175
187
|
/** Read model and capability state for the workbench without exposing secrets. */
|
|
176
188
|
export interface StudioConfigResponse {
|
|
177
189
|
providers: StudioProviderProfile[];
|
|
178
|
-
activeProvider:
|
|
190
|
+
activeProvider: StudioProvider;
|
|
179
191
|
workspaceRoot?: string | undefined;
|
|
180
192
|
workspaces?: StudioWorkspaceInfo[] | undefined;
|
|
181
193
|
}
|
|
@@ -193,7 +205,7 @@ export type StudioReference = StudioEncodedReference | StudioAttachmentReference
|
|
|
193
205
|
/** One browser workbench generation or editing request. */
|
|
194
206
|
export interface StudioGenerateRequest {
|
|
195
207
|
mode: 'generate' | 'edit';
|
|
196
|
-
provider:
|
|
208
|
+
provider: StudioProvider;
|
|
197
209
|
model: string;
|
|
198
210
|
prompt: string;
|
|
199
211
|
ratio: string;
|
|
@@ -211,7 +223,7 @@ export interface StudioGeneratedItem {
|
|
|
211
223
|
}
|
|
212
224
|
/** One completed workbench request. */
|
|
213
225
|
export interface StudioGenerateResponse extends StudioGeneratedItem {
|
|
214
|
-
provider:
|
|
226
|
+
provider: StudioProvider;
|
|
215
227
|
model: string;
|
|
216
228
|
prompt: string;
|
|
217
229
|
createdAt: number;
|
|
@@ -235,6 +247,45 @@ export declare const DEFAULT_COMFYUI_BASE_URL = "http://127.0.0.1:8188";
|
|
|
235
247
|
export declare const DEFAULT_COMFYUI_TIMEOUT_MS = 300000;
|
|
236
248
|
export declare const DEFAULT_COMFYUI_WORKFLOW_LABEL = "API workflow";
|
|
237
249
|
export declare const MAX_COMFYUI_WORKFLOW_BYTES: number;
|
|
250
|
+
/** Content types Ark's Seedream endpoint can return. */
|
|
251
|
+
export declare const ARK_OUTPUT_FORMATS: readonly ["png", "jpeg"];
|
|
252
|
+
/** Whether Ark stamps an "AI generated" watermark on the result. */
|
|
253
|
+
export declare const ARK_BACKGROUND_MODES: readonly ["opaque", "transparent"];
|
|
254
|
+
export type ArkOutputFormat = typeof ARK_OUTPUT_FORMATS[number];
|
|
255
|
+
export type ArkBackgroundMode = typeof ARK_BACKGROUND_MODES[number];
|
|
256
|
+
/**
|
|
257
|
+
* Ark (Seedream) output controls, shared by the generate and edit paths.
|
|
258
|
+
*
|
|
259
|
+
* Every field mirrors an Ark request-body field of the same meaning, and every
|
|
260
|
+
* default below reproduces Ark's own default — so an untouched configuration
|
|
261
|
+
* sends exactly what it sent before these options existed.
|
|
262
|
+
*/
|
|
263
|
+
export interface ArkOutputOptions {
|
|
264
|
+
/** `output_format`. Ark defaults to `jpeg`; `png` is lossless and keeps an alpha channel. */
|
|
265
|
+
outputFormat?: ArkOutputFormat;
|
|
266
|
+
/** `watermark`. Ark defaults to `true`, which bakes an "AI generated" mark into the image. */
|
|
267
|
+
watermark?: boolean;
|
|
268
|
+
/** `background`. Ark defaults to `opaque`. */
|
|
269
|
+
background?: ArkBackgroundMode;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Map the Ark output controls onto request-body fields.
|
|
273
|
+
*
|
|
274
|
+
* `background` is opt-in per call site because Ark restricts `transparent` to
|
|
275
|
+
* image-to-image with a single alpha-bearing reference and rejects the whole
|
|
276
|
+
* request otherwise:
|
|
277
|
+
*
|
|
278
|
+
* text-to-image + transparent → 400 InvalidParameter
|
|
279
|
+
* "transparent background requires exactly one input image"
|
|
280
|
+
*
|
|
281
|
+
* So the generation endpoint must never carry it, and that caller passes
|
|
282
|
+
* `{ background: false }`. `background: opaque` is never emitted anywhere: it
|
|
283
|
+
* is already Ark's default, so sending it would change nothing while adding a
|
|
284
|
+
* field only the edit path can act on.
|
|
285
|
+
*/
|
|
286
|
+
export declare function arkOutputBody(options: ArkOutputOptions | undefined, { background }?: {
|
|
287
|
+
background?: boolean;
|
|
288
|
+
}): Record<string, unknown>;
|
|
238
289
|
/** Default model names. */
|
|
239
290
|
export declare const DEFAULT_GOOGLE_MODEL = "gemini-3.1-flash-image";
|
|
240
291
|
export declare const DEFAULT_OPENAI_MODEL = "gpt-image-2";
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dedicated DSH agent session backing the workbench chat panel.
|
|
3
|
+
*
|
|
4
|
+
* The panel is a real DSH conversation driven from the plugin, not a parallel
|
|
5
|
+
* chat implementation: on first use the host creates an agent through
|
|
6
|
+
* ctx.agents.create (the same factory the sidebar uses), then archives the
|
|
7
|
+
* session through ctx.workspaceRegistry so it never appears in the sidebar
|
|
8
|
+
* history list while remaining fully usable. The plugin never calls
|
|
9
|
+
* sessions.open - archiving the selected session would clear the user's
|
|
10
|
+
* current selection - and drives turns purely through agent.followup().
|
|
11
|
+
*
|
|
12
|
+
* Session events are projected into a small lossless-enough StudioChatEvent
|
|
13
|
+
* feed (text turns, tool summaries, generated-image references) and served to
|
|
14
|
+
* the browser through CHAT_ROUTE. The browser pulls increments with
|
|
15
|
+
* ?since=<seq>; images land on the tldraw canvas from the browser side via
|
|
16
|
+
* the existing IMAGE_ROUTE + landing-queue path.
|
|
17
|
+
*/
|
|
18
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
19
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
20
|
+
import { type StudioChatEvent } from './shared.js';
|
|
21
|
+
/** Wire responses for CHAT_ROUTE. */
|
|
22
|
+
export interface StudioChatStateResponse {
|
|
23
|
+
ok: true;
|
|
24
|
+
latestSeq: number;
|
|
25
|
+
events: StudioChatEvent[];
|
|
26
|
+
/** Why the backing agent is missing, when creation failed; absent otherwise. */
|
|
27
|
+
unavailable?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface StudioChatSendResponse {
|
|
30
|
+
ok: true;
|
|
31
|
+
}
|
|
32
|
+
export interface StudioChatErrorResponse {
|
|
33
|
+
error: string;
|
|
34
|
+
}
|
|
35
|
+
export interface StudioChatDeps {
|
|
36
|
+
maxBodyBytes: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Install the studio chat: ensure the dedicated agent session, subscribe to
|
|
40
|
+
* its events, and return the CHAT_ROUTE handler plus a disposer. Creation
|
|
41
|
+
* failures never break the plugin load - the route reports the error and the
|
|
42
|
+
* panel shows it, so a host without agent services degrades visibly instead
|
|
43
|
+
* of fatally.
|
|
44
|
+
*/
|
|
45
|
+
export declare function createStudioChat(ctx: Context, deps: StudioChatDeps): {
|
|
46
|
+
serve: (req: IncomingMessage, res: ServerResponse) => Promise<void>;
|
|
47
|
+
dispose(): void;
|
|
48
|
+
};
|
package/lib/types/studio.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { Context } from '@deepseek-ai/cordis';
|
|
2
2
|
import { type Config } from './config.js';
|
|
3
|
+
import { type SubscriptionManager } from './subscription.js';
|
|
3
4
|
import { type CloudImageProvider, type StudioConfigResponse, type StudioGenerateRequest, type StudioGenerateResponse, type StudioProviderProfile } from './shared.js';
|
|
4
5
|
/** Return only browser-safe capability data. */
|
|
5
|
-
export declare function describeStudio(ctx: Context, config: Config): Promise<StudioConfigResponse>;
|
|
6
|
+
export declare function describeStudio(ctx: Context, config: Config, subscriptions?: SubscriptionManager | undefined): Promise<StudioConfigResponse>;
|
|
6
7
|
/** Execute one validated browser workbench request using the existing provider adapters. */
|
|
7
|
-
export declare function generateFromStudio(ctx: Context, config: Config, input: StudioGenerateRequest, signal: AbortSignal, fallbackWorkspaceRoot?: string | undefined): Promise<StudioGenerateResponse>;
|
|
8
|
+
export declare function generateFromStudio(ctx: Context, config: Config, input: StudioGenerateRequest, signal: AbortSignal, fallbackWorkspaceRoot?: string | undefined, subscriptions?: SubscriptionManager | undefined): Promise<StudioGenerateResponse>;
|
|
8
9
|
export declare function runPool<T>(tasks: Array<() => Promise<T>>, concurrency?: number): Promise<PromiseSettledResult<T>[]>;
|
|
9
10
|
export declare function studioProfile(config: Config, provider: CloudImageProvider, configured: boolean): StudioProviderProfile;
|
|
@@ -21,12 +21,26 @@ import { type SubscriptionBlob } from './blob.js';
|
|
|
21
21
|
import { type SubscriptionProvider } from '../shared.js';
|
|
22
22
|
/** Vendor ids used by the credential refs and the wire calls. */
|
|
23
23
|
export type SubscriptionVendor = 'codex' | 'grok' | 'antigravity';
|
|
24
|
+
/**
|
|
25
|
+
* Reference image passed to edit calls. Structural so callers can pass their
|
|
26
|
+
* own resolved types without importing from the plugin root.
|
|
27
|
+
*/
|
|
28
|
+
export interface SubscriptionReferenceImage {
|
|
29
|
+
data: Uint8Array;
|
|
30
|
+
mediaType: string;
|
|
31
|
+
}
|
|
24
32
|
/** The vendor each dsh-image-gen subscription provider maps onto. */
|
|
25
33
|
export declare function vendorOf(provider: SubscriptionProvider): SubscriptionVendor;
|
|
26
34
|
/** Credential ref one vendor's OAuth blob is stored under (index fixed at 1). */
|
|
27
35
|
export declare function subscriptionOauthRef(vendor: SubscriptionVendor): CredentialRef;
|
|
28
36
|
/** Sizes both vendors understand. */
|
|
29
37
|
export declare const SUBSCRIPTION_SIZES: readonly ["1024x1024", "1024x1536", "1536x1024", "auto"];
|
|
38
|
+
/**
|
|
39
|
+
* Reference images per edit call. Every subscription channel accepts at
|
|
40
|
+
* least this many (Codex edits up to 16, Grok up to 5, Antigravity up to 10),
|
|
41
|
+
* so 5 keeps one shared guard in line with the Studio UI's upload cap.
|
|
42
|
+
*/
|
|
43
|
+
export declare const SUBSCRIPTION_MAX_REFERENCE_IMAGES = 5;
|
|
30
44
|
/** Login status the settings card renders as a badge. */
|
|
31
45
|
export type SubscriptionLoginStatus = {
|
|
32
46
|
state: 'logged-in';
|
|
@@ -80,6 +94,7 @@ export declare class SubscriptionManager {
|
|
|
80
94
|
prompt: string;
|
|
81
95
|
size?: string;
|
|
82
96
|
quality?: string;
|
|
97
|
+
referenceImages?: ReadonlyArray<SubscriptionReferenceImage>;
|
|
83
98
|
signal?: AbortSignal;
|
|
84
99
|
}): Promise<Array<{
|
|
85
100
|
b64_json: string;
|
|
@@ -37,12 +37,17 @@ export declare function antigravityResolveProject(blob: SubscriptionBlob): Promi
|
|
|
37
37
|
* Build the streamGenerateContent request body for one image generation.
|
|
38
38
|
* Ported from the reference buildImageRequest + the wrapping envelope: no
|
|
39
39
|
* tools, no systemInstruction, no thinkingConfig; responseModalities asks
|
|
40
|
-
* for TEXT+IMAGE.
|
|
40
|
+
* for TEXT+IMAGE. Reference images (edits) ride along as inlineData parts
|
|
41
|
+
* before the text part, mirroring the reference implementation.
|
|
41
42
|
*/
|
|
42
43
|
export declare function antigravityImageBody(options: {
|
|
43
44
|
prompt: string;
|
|
44
45
|
aspectRatio?: string;
|
|
45
46
|
hd?: boolean;
|
|
47
|
+
referenceImages?: ReadonlyArray<{
|
|
48
|
+
data: Uint8Array;
|
|
49
|
+
mediaType: string;
|
|
50
|
+
}>;
|
|
46
51
|
}): Record<string, unknown>;
|
|
47
52
|
/** Wrap the inner request in the Antigravity agent envelope. */
|
|
48
53
|
export declare function antigravityEnvelope(projectId: string, request: Record<string, unknown>): Record<string, unknown>;
|
|
@@ -62,5 +67,9 @@ export declare function antigravityGenerateImage(options: {
|
|
|
62
67
|
prompt: string;
|
|
63
68
|
aspectRatio?: string;
|
|
64
69
|
hd?: boolean;
|
|
70
|
+
referenceImages?: ReadonlyArray<{
|
|
71
|
+
data: Uint8Array;
|
|
72
|
+
mediaType: string;
|
|
73
|
+
}>;
|
|
65
74
|
signal?: AbortSignal;
|
|
66
75
|
}): Promise<AntigravityImageResult>;
|
|
@@ -12,6 +12,8 @@ export declare const CODEX_AUTH = "https://auth.openai.com/oauth/authorize";
|
|
|
12
12
|
export declare const CODEX_TOKEN = "https://auth.openai.com/oauth/token";
|
|
13
13
|
/** Where the ChatGPT subscription image request goes. */
|
|
14
14
|
export declare const CODEX_IMAGE_URL = "https://chatgpt.com/backend-api/codex/images/generations";
|
|
15
|
+
/** Where the ChatGPT subscription image edit request goes. */
|
|
16
|
+
export declare const CODEX_IMAGE_EDIT_URL = "https://chatgpt.com/backend-api/codex/images/edits";
|
|
15
17
|
/** The model served by this endpoint (probed live: gpt-image-2.5-flare works
|
|
16
18
|
* on the ChatGPT internal generations route as of 2026-09-14). */
|
|
17
19
|
export declare const CODEX_IMAGE_MODEL = "gpt-image-2.5-flare";
|