@dickpy/dsh-imagegen 1.3.0 → 1.4.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.
Files changed (45) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +203 -182
  3. package/cordis.patch.yml +8 -8
  4. package/docs/images/multi-model-comparison.png +0 -0
  5. package/lib/client.js +1103 -837
  6. package/lib/client.js.map +1 -1
  7. package/lib/index.js +265 -135
  8. package/package.json +70 -68
  9. package/src/agent-image-tools.ts +418 -418
  10. package/src/client/ImageGenPanel.tsx +1699 -1508
  11. package/src/client/SettingsCard.tsx +936 -957
  12. package/src/client/TemplateLibrary.tsx +336 -336
  13. package/src/client/api.ts +193 -193
  14. package/src/client/channels-form.ts +263 -263
  15. package/src/client/controller.ts +46 -46
  16. package/src/client/conversation-sync.ts +14 -0
  17. package/src/client/css-modules.d.ts +5 -5
  18. package/src/client/helpers.ts +33 -33
  19. package/src/client/image-toolview.module.css +73 -73
  20. package/src/client/image-toolview.tsx +169 -158
  21. package/src/client/index.ts +32 -22
  22. package/src/client/locales.ts +610 -594
  23. package/src/client/mount.tsx +185 -96
  24. package/src/client/panel.module.css +1713 -1445
  25. package/src/client/settings-card.module.css +1023 -1023
  26. package/src/client/settings-form.ts +336 -336
  27. package/src/client/settings-scope.ts +298 -298
  28. package/src/client/sidebar-entry.ts +148 -102
  29. package/src/client/templates.module.css +453 -453
  30. package/src/engine.ts +520 -478
  31. package/src/gallery-store.ts +286 -286
  32. package/src/generation-runtime.ts +79 -75
  33. package/src/history-store.ts +250 -244
  34. package/src/image-format.ts +11 -11
  35. package/src/image-models.ts +19 -19
  36. package/src/index.ts +318 -318
  37. package/src/model-catalog.ts +115 -98
  38. package/src/presets.ts +71 -63
  39. package/src/prompt-enhancer.ts +137 -79
  40. package/src/protocol.ts +338 -326
  41. package/src/routes.ts +916 -906
  42. package/src/task-queue.ts +113 -103
  43. package/src/templates/cases.json +10196 -10196
  44. package/src/templates-store.ts +278 -278
  45. package/src/updater.ts +117 -117
package/src/protocol.ts CHANGED
@@ -1,326 +1,338 @@
1
- /**
2
- * Wire contract shared by the host and client halves of dsh-imagegen: the
3
- * settings namespace, the route paths, and the generate payload/result shapes.
4
- * Pure types + constants 鈥?safe for the client bundle to inline.
5
- */
6
-
7
- /** Settings namespace this plugin owns (host settings seam + bridge). */
8
- export const IMAGEGEN_SETTINGS_NAMESPACE = 'dsh-imagegen'
9
-
10
- /** Published package version shared by the host updater and the client UI. */
11
- export const PLUGIN_VERSION = '1.3.0'
12
-
13
- /** Same-origin route family (loopback-only, mirroring the dsh-ssh fence). */
14
- export const SETTINGS_API = {
15
- describe: '/api/dsh-imagegen/settings/describe',
16
- mutate: '/api/dsh-imagegen/settings/mutate',
17
- } as const
18
-
19
- /** The image-generation proxy route. */
20
- export const GENERATE_API = '/api/dsh-imagegen/generate'
21
-
22
- /** Host-mediated OpenAI-compatible prompt enhancement endpoints. */
23
- export const PROMPT_ENHANCE_API = {
24
- models: '/api/dsh-imagegen/prompt-enhance/models',
25
- enhance: '/api/dsh-imagegen/prompt-enhance',
26
- } as const
27
-
28
- /** Host-mediated candidate discovery for the configured image API. */
29
- export const IMAGE_MODEL_API = {
30
- models: '/api/dsh-imagegen/image-models',
31
- } as const
32
-
33
- /** Host-served built-in provider catalog (channels the user can instantiate). */
34
- export const PRESETS_API = '/api/dsh-imagegen/presets' as const
35
-
36
- /** Loopback-only image reader for Agent tool-result previews. */
37
- export const AGENT_IMAGE_API = '/api/dsh-imagegen/agent-image' as const
38
-
39
- /**
40
- * Host-computed per-channel usage counters (generation-count badges in the
41
- * settings card): entries are tallied from the persisted history and gallery
42
- * by channel + model alias.
43
- */
44
- export const USAGE_API = '/api/dsh-imagegen/usage' as const
45
-
46
- /** Host-resident generation queue endpoints. */
47
- export const TASK_API = {
48
- submit: '/api/dsh-imagegen/tasks/submit',
49
- list: '/api/dsh-imagegen/tasks/list',
50
- cancel: '/api/dsh-imagegen/tasks/cancel',
51
- retry: '/api/dsh-imagegen/tasks/retry',
52
- } as const
53
-
54
- /** Host-mediated GitHub Release update routes. */
55
- export const UPDATE_API = {
56
- check: '/api/dsh-imagegen/update/check',
57
- apply: '/api/dsh-imagegen/update/apply',
58
- } as const
59
-
60
- /**
61
- * Same-origin route family for the host-persisted generation history. Images
62
- * live as files under ~/.dsh/dsh-imagegen/images/ and are served back through
63
- * the `image` prefix route, so list responses carry metadata only (never
64
- * base64) and the browser loads thumbnails/previews lazily.
65
- */
66
- export const HISTORY_API = {
67
- list: '/api/dsh-imagegen/history/list',
68
- append: '/api/dsh-imagegen/history/append',
69
- remove: '/api/dsh-imagegen/history/remove',
70
- clear: '/api/dsh-imagegen/history/clear',
71
- image: '/api/dsh-imagegen/history/image',
72
- } as const
73
-
74
- /**
75
- * Same-origin route family for the user-curated gallery (favorites). Entries
76
- * reuse the history wire shape and persist under ~/.dsh/dsh-imagegen/gallery/;
77
- * unlike history there is no size cap 鈥?the user adds images on purpose.
78
- */
79
- export const GALLERY_API = {
80
- list: '/api/dsh-imagegen/gallery/list',
81
- append: '/api/dsh-imagegen/gallery/append',
82
- remove: '/api/dsh-imagegen/gallery/remove',
83
- clear: '/api/dsh-imagegen/gallery/clear',
84
- tags: '/api/dsh-imagegen/gallery/tags',
85
- image: '/api/dsh-imagegen/gallery/image',
86
- } as const
87
-
88
- /** Maximum number of history entries retained host-side (oldest evicted). */
89
- export const HISTORY_MAX = 50
90
-
91
- /**
92
- * Same-origin route family for the bundled prompt-template library
93
- * (awesome-gpt-image-2 mirror). The case list ships inside the package and is
94
- * served by the host; reference images are proxied through the `image` prefix
95
- * route and cached on disk so repeated views never hit the network again.
96
- */
97
- export const TEMPLATES_API = {
98
- list: '/api/dsh-imagegen/templates/list',
99
- refresh: '/api/dsh-imagegen/templates/refresh',
100
- image: '/api/dsh-imagegen/templates/image',
101
- } as const
102
-
103
- /** One prompt-library case as the browser consumes it. */
104
- export interface TemplateCase {
105
- /** Upstream case number (stable across refreshes). */
106
- id: number
107
- /** Short case title. */
108
- title: string
109
- /** Full reusable prompt text. */
110
- prompt: string
111
- /** English category name (grouping key). */
112
- category: string
113
- /** Chinese category display name. */
114
- categoryZh: string
115
- /** Style tags. */
116
- styles: string[]
117
- /** Scene tags. */
118
- scenes: string[]
119
- /** Original author handle, e.g. @vista8. */
120
- sourceLabel: string
121
- /** Original author link. */
122
- sourceUrl: string
123
- /** awesome-gpt-image-2 repo anchor link. */
124
- githubUrl: string
125
- /** Reference-image file name served through the image route ('' when none). */
126
- image: string
127
- /** Whether the source gallery featured the case. */
128
- featured: boolean
129
- }
130
-
131
- /** Template-library list payload. */
132
- export interface TemplateListResult {
133
- cases: TemplateCase[]
134
- total: number
135
- /** Where the served list came from. */
136
- origin: 'bundled' | 'refreshed'
137
- /** Upstream repository the library mirrors. */
138
- repository: string
139
- /** ISO time of the last successful refresh / bundle snapshot. */
140
- fetchedAt: string
141
- }
142
-
143
- /** Template-library refresh outcome. */
144
- export interface TemplateRefreshResult {
145
- total: number
146
- fetchedAt: string
147
- }
148
-
149
- /** Generation modes. */
150
- export type GenerateMode = 'text' | 'edit'
151
-
152
- /** A client → host generate request (what the panel collects). */
153
- export interface GenerateRequest {
154
- /** text-to-image (images/generations) or image-to-image (images/edits). */
155
- mode: GenerateMode
156
- /**
157
- * User-facing model name (an alias from the channel's model catalog). The
158
- * host maps it onto the configured channel and fills `upstream` with the
159
- * real id before the engine sees it.
160
- */
161
- model: string
162
- /** The prompt. Upstream providers may impose their own length limits. */
163
- prompt: string
164
- /** Canvas size as an aspect ratio: 'auto' or e.g. '1:1' / '16:9' / '21:9'.
165
- * The host maps it onto each model's own vocabulary (aspect_ratio for Grok
166
- * and Nano Banana, resolution-tier size for Seedream, the closest pixel size for
167
- * OpenAI-compatible endpoints). */
168
- size: string
169
- /** Clarity tier: 'auto' | '1k' | '2k' | '4k'. The host maps it onto the
170
- * model's own vocabulary (resolution for Grok, image_size for Nano Banana,
171
- * and size for Seedream,
172
- * Nano Banana, quality for OpenAI). */
173
- quality: string
174
- /** Number of images, 1-4. */
175
- n: number
176
- /**
177
- * Passthrough detail parameter: '' (omit), 'standard', or 'high'. Some
178
- * gpt-image-2 gateways expose it; official OpenAI endpoints reject unknown
179
- * parameters, so the UI defaults to '' (omit).
180
- */
181
- detail: string
182
- /** Reference image as a data URL (edit mode only). */
183
- image?: string
184
- /** Original reference-image name, retained in the history entry. */
185
- refName?: string
186
- /** Channel this request targets (the host falls back to the default when
187
- * absent, and re-routes by model alias when the alias lives elsewhere). */
188
- channelId?: string
189
- /** Channel display name snapshot, kept on the history entry (host-filled). */
190
- channel?: string
191
- /** Upstream model id actually sent to the gateway (host-filled from the
192
- * alias mapping; defaults to `model` when absent). */
193
- upstream?: string
194
- }
195
-
196
- /** One generated image, normalized host-side to base64 so the browser never
197
- * has to fetch the upstream (no CORS, no key exposure). */
198
- export interface GeneratedImage {
199
- /** Raw base64 payload (no data: prefix). */
200
- b64: string
201
- /** MIME type of the payload, e.g. image/png. */
202
- mime: string
203
- /** Upstream revised prompt, when provided. */
204
- revisedPrompt?: string
205
- }
206
-
207
- /** Successful generate outcome. */
208
- export interface GenerateResult {
209
- images: GeneratedImage[]
210
- /** Updated host-persisted history, when returned by the generate route. */
211
- history?: HistoryEntry[]
212
- /** Persistence failure after images were successfully generated. */
213
- historyError?: string
214
- }
215
-
216
- /**
217
- * One model mapping in a channel's catalog: the display alias the user, the
218
- * panel, and the Agent see, and the upstream model id actually sent to the
219
- * gateway. The alias defaults to the upstream id but can be renamed freely.
220
- */
221
- export interface ModelMapping {
222
- /** User-facing model name (defaults to the upstream id). */
223
- alias: string
224
- /** Upstream model id sent to the gateway. */
225
- id: string
226
- }
227
-
228
- /**
229
- * One configured image channel (provider). Secrets never live here — the API
230
- * key is stored at `channelSecrets.<channelId>` in the settings document so
231
- * whole-array writes can never clobber keys the user did not re-enter.
232
- */
233
- export interface ChannelConfig {
234
- /** Stable channel id (the channelSecrets dict is keyed by it). */
235
- id: string
236
- /** Preset provider id this channel was created from ('' = custom). */
237
- preset: string
238
- /** Display name shown in the list, the panel, and Agent guidance. */
239
- name: string
240
- /** OpenAI-compatible base URL. */
241
- apiUrl: string
242
- /** The channel's model catalog (alias upstream id). */
243
- models: ModelMapping[]
244
- }
245
-
246
- /** One built-in provider as the settings card consumes it. */
247
- export interface PresetProviderView {
248
- id: string
249
- name: string
250
- apiUrl: string
251
- hint: string
252
- models: ModelMapping[]
253
- }
254
-
255
- export type GenerationTaskStatus = 'queued' | 'running' | 'completed' | 'failed' | 'cancelled'
256
-
257
- export interface GenerationTask {
258
- id: string
259
- request: GenerateRequest
260
- status: GenerationTaskStatus
261
- createdAt: number
262
- startedAt?: number
263
- finishedAt?: number
264
- result?: GenerateResult
265
- error?: string
266
- }
267
-
268
- /** GitHub Release update information shown by the client. */
269
- export interface UpdateInfo {
270
- currentVersion: string
271
- latestVersion: string
272
- updateAvailable: boolean
273
- releaseUrl: string
274
- publishedAt?: string
275
- }
276
-
277
- /** One history image reference as the browser consumes it (a served URL). */
278
- export interface HistoryImageRef {
279
- /** Same-origin URL: `${HISTORY_API.image}/<file>`. */
280
- url: string
281
- /** MIME type, e.g. image/png. */
282
- mime: string
283
- /** Upstream revised prompt, when provided. */
284
- revisedPrompt?: string
285
- }
286
-
287
- /** A saved generation as the browser consumes it (metadata + served images). */
288
- export interface HistoryEntry {
289
- id: string
290
- createdAt: number
291
- mode: GenerateMode
292
- model: string
293
- prompt: string
294
- size: string
295
- quality: string
296
- detail: string
297
- n: number
298
- images: HistoryImageRef[]
299
- /** Reference-image filename (edit mode), kept for display only. */
300
- refName?: string
301
- /** User-managed gallery labels (unused by history entries). */
302
- tags?: string[]
303
- /** Channel id snapshot (usage counters key by it for new entries). */
304
- channelId?: string
305
- /** Channel display name snapshot (survives channel deletion). */
306
- channel?: string
307
- }
308
-
309
- /** A history entry the client submits for persistence (images still carry base64). */
310
- export interface HistoryEntryInput {
311
- id: string
312
- createdAt: number
313
- mode: GenerateMode
314
- model: string
315
- prompt: string
316
- size: string
317
- quality: string
318
- detail: string
319
- n: number
320
- images: GeneratedImage[]
321
- refName?: string
322
- /** Channel id snapshot, tallied by the usage endpoint. */
323
- channelId?: string
324
- /** Channel display name snapshot (survives channel deletion). */
325
- channel?: string
326
- }
1
+ /**
2
+ * Wire contract shared by the host and client halves of dsh-imagegen: the
3
+ * settings namespace, the route paths, and the generate payload/result shapes.
4
+ * Pure types + constants 鈥?safe for the client bundle to inline.
5
+ */
6
+
7
+ /** Settings namespace this plugin owns (host settings seam + bridge). */
8
+ export const IMAGEGEN_SETTINGS_NAMESPACE = 'dsh-imagegen'
9
+
10
+ /** Published package version shared by the host updater and the client UI. */
11
+ export const PLUGIN_VERSION = '1.3.1'
12
+
13
+ /** Same-origin route family (loopback-only, mirroring the dsh-ssh fence). */
14
+ export const SETTINGS_API = {
15
+ describe: '/api/dsh-imagegen/settings/describe',
16
+ mutate: '/api/dsh-imagegen/settings/mutate',
17
+ } as const
18
+
19
+ /** The image-generation proxy route. */
20
+ export const GENERATE_API = '/api/dsh-imagegen/generate'
21
+
22
+ /** Host-mediated OpenAI-compatible prompt enhancement endpoints. */
23
+ export const PROMPT_ENHANCE_API = {
24
+ models: '/api/dsh-imagegen/prompt-enhance/models',
25
+ enhance: '/api/dsh-imagegen/prompt-enhance',
26
+ } as const
27
+
28
+ /** Host-mediated candidate discovery for the configured image API. */
29
+ export const IMAGE_MODEL_API = {
30
+ models: '/api/dsh-imagegen/image-models',
31
+ } as const
32
+
33
+ /** Host-served built-in provider catalog (channels the user can instantiate). */
34
+ export const PRESETS_API = '/api/dsh-imagegen/presets' as const
35
+
36
+ /** Loopback-only image reader for Agent tool-result previews. */
37
+ export const AGENT_IMAGE_API = '/api/dsh-imagegen/agent-image' as const
38
+
39
+ /**
40
+ * Host-computed per-channel usage counters (generation-count badges in the
41
+ * settings card): entries are tallied from the persisted history and gallery
42
+ * by channel + model alias.
43
+ */
44
+ export const USAGE_API = '/api/dsh-imagegen/usage' as const
45
+
46
+ /** Host-resident generation queue endpoints. */
47
+ export const TASK_API = {
48
+ submit: '/api/dsh-imagegen/tasks/submit',
49
+ list: '/api/dsh-imagegen/tasks/list',
50
+ cancel: '/api/dsh-imagegen/tasks/cancel',
51
+ retry: '/api/dsh-imagegen/tasks/retry',
52
+ } as const
53
+
54
+ /** Host-mediated GitHub Release update routes. */
55
+ export const UPDATE_API = {
56
+ check: '/api/dsh-imagegen/update/check',
57
+ apply: '/api/dsh-imagegen/update/apply',
58
+ } as const
59
+
60
+ /**
61
+ * Same-origin route family for the host-persisted generation history. Images
62
+ * live as files under ~/.dsh/dsh-imagegen/images/ and are served back through
63
+ * the `image` prefix route, so list responses carry metadata only (never
64
+ * base64) and the browser loads thumbnails/previews lazily.
65
+ */
66
+ export const HISTORY_API = {
67
+ list: '/api/dsh-imagegen/history/list',
68
+ append: '/api/dsh-imagegen/history/append',
69
+ remove: '/api/dsh-imagegen/history/remove',
70
+ clear: '/api/dsh-imagegen/history/clear',
71
+ image: '/api/dsh-imagegen/history/image',
72
+ } as const
73
+
74
+ /**
75
+ * Same-origin route family for the user-curated gallery (favorites). Entries
76
+ * reuse the history wire shape and persist under ~/.dsh/dsh-imagegen/gallery/;
77
+ * unlike history there is no size cap 鈥?the user adds images on purpose.
78
+ */
79
+ export const GALLERY_API = {
80
+ list: '/api/dsh-imagegen/gallery/list',
81
+ append: '/api/dsh-imagegen/gallery/append',
82
+ remove: '/api/dsh-imagegen/gallery/remove',
83
+ clear: '/api/dsh-imagegen/gallery/clear',
84
+ tags: '/api/dsh-imagegen/gallery/tags',
85
+ image: '/api/dsh-imagegen/gallery/image',
86
+ } as const
87
+
88
+ /** Maximum number of history entries retained host-side (oldest evicted). */
89
+ export const HISTORY_MAX = 50
90
+
91
+ /**
92
+ * Same-origin route family for the bundled prompt-template library
93
+ * (awesome-gpt-image-2 mirror). The case list ships inside the package and is
94
+ * served by the host; reference images are proxied through the `image` prefix
95
+ * route and cached on disk so repeated views never hit the network again.
96
+ */
97
+ export const TEMPLATES_API = {
98
+ list: '/api/dsh-imagegen/templates/list',
99
+ refresh: '/api/dsh-imagegen/templates/refresh',
100
+ image: '/api/dsh-imagegen/templates/image',
101
+ } as const
102
+
103
+ /** One prompt-library case as the browser consumes it. */
104
+ export interface TemplateCase {
105
+ /** Upstream case number (stable across refreshes). */
106
+ id: number
107
+ /** Short case title. */
108
+ title: string
109
+ /** Full reusable prompt text. */
110
+ prompt: string
111
+ /** English category name (grouping key). */
112
+ category: string
113
+ /** Chinese category display name. */
114
+ categoryZh: string
115
+ /** Style tags. */
116
+ styles: string[]
117
+ /** Scene tags. */
118
+ scenes: string[]
119
+ /** Original author handle, e.g. @vista8. */
120
+ sourceLabel: string
121
+ /** Original author link. */
122
+ sourceUrl: string
123
+ /** awesome-gpt-image-2 repo anchor link. */
124
+ githubUrl: string
125
+ /** Reference-image file name served through the image route ('' when none). */
126
+ image: string
127
+ /** Whether the source gallery featured the case. */
128
+ featured: boolean
129
+ }
130
+
131
+ /** Template-library list payload. */
132
+ export interface TemplateListResult {
133
+ cases: TemplateCase[]
134
+ total: number
135
+ /** Where the served list came from. */
136
+ origin: 'bundled' | 'refreshed'
137
+ /** Upstream repository the library mirrors. */
138
+ repository: string
139
+ /** ISO time of the last successful refresh / bundle snapshot. */
140
+ fetchedAt: string
141
+ }
142
+
143
+ /** Template-library refresh outcome. */
144
+ export interface TemplateRefreshResult {
145
+ total: number
146
+ fetchedAt: string
147
+ }
148
+
149
+ /** Generation modes. */
150
+ export type GenerateMode = 'text' | 'edit'
151
+
152
+ /** A client → host generate request (what the panel collects). */
153
+ export interface GenerateRequest {
154
+ /** text-to-image (images/generations) or image-to-image (images/edits). */
155
+ mode: GenerateMode
156
+ /**
157
+ * User-facing model name (an alias from the channel's model catalog). The
158
+ * host maps it onto the configured channel and fills `upstream` with the
159
+ * real id before the engine sees it.
160
+ */
161
+ model: string
162
+ /** The prompt. Upstream providers may impose their own length limits. */
163
+ prompt: string
164
+ /** Canvas size as an aspect ratio: 'auto' or e.g. '1:1' / '16:9' / '21:9'.
165
+ * The host maps it onto each model's own vocabulary (aspect_ratio for Grok
166
+ * and Nano Banana, resolution-tier size for Seedream, the closest pixel size for
167
+ * OpenAI-compatible endpoints). */
168
+ size: string
169
+ /** Clarity tier: 'auto' | '1k' | '2k' | '4k'. The host maps it onto the
170
+ * model's own vocabulary (resolution for Grok, image_size for Nano Banana,
171
+ * and size for Seedream,
172
+ * Nano Banana, quality for OpenAI). */
173
+ quality: string
174
+ /** Number of images, 1-4. */
175
+ n: number
176
+ /**
177
+ * Passthrough detail parameter: '' (omit), 'standard', or 'high'. Some
178
+ * gpt-image-2 gateways expose it; official OpenAI endpoints reject unknown
179
+ * parameters, so the UI defaults to '' (omit).
180
+ */
181
+ detail: string
182
+ /** Reference image as a data URL (edit mode only). */
183
+ image?: string
184
+ /** Original reference-image name, retained in the history entry. */
185
+ refName?: string
186
+ /** Channel this request targets (the host falls back to the default when
187
+ * absent, and re-routes by model alias when the alias lives elsewhere). */
188
+ channelId?: string
189
+ /** Channel display name snapshot, kept on the history entry (host-filled). */
190
+ channel?: string
191
+ /** Upstream model id actually sent to the gateway (host-filled from the
192
+ * alias mapping; defaults to `model` when absent). */
193
+ upstream?: string
194
+ /** Stable client-created id shared by the tasks in one comparison run. */
195
+ comparisonId?: string
196
+ /** All model aliases selected for one comparison run. */
197
+ comparisonModels?: string[]
198
+ }
199
+
200
+ /** One generated image, normalized host-side to base64 so the browser never
201
+ * has to fetch the upstream (no CORS, no key exposure). */
202
+ export interface GeneratedImage {
203
+ /** Raw base64 payload (no data: prefix). */
204
+ b64: string
205
+ /** MIME type of the payload, e.g. image/png. */
206
+ mime: string
207
+ /** Upstream revised prompt, when provided. */
208
+ revisedPrompt?: string
209
+ }
210
+
211
+ /** Successful generate outcome. */
212
+ export interface GenerateResult {
213
+ images: GeneratedImage[]
214
+ /** Updated host-persisted history, when returned by the generate route. */
215
+ history?: HistoryEntry[]
216
+ /** Persistence failure after images were successfully generated. */
217
+ historyError?: string
218
+ }
219
+
220
+ /**
221
+ * One model mapping in a channel's catalog: the display alias the user, the
222
+ * panel, and the Agent see, and the upstream model id actually sent to the
223
+ * gateway. The alias defaults to the upstream id but can be renamed freely.
224
+ */
225
+ export interface ModelMapping {
226
+ /** User-facing model name (defaults to the upstream id). */
227
+ alias: string
228
+ /** Upstream model id sent to the gateway. */
229
+ id: string
230
+ }
231
+
232
+ /**
233
+ * One configured image channel (provider). Secrets never live here — the API
234
+ * key is stored at `channelSecrets.<channelId>` in the settings document so
235
+ * whole-array writes can never clobber keys the user did not re-enter.
236
+ */
237
+ export interface ChannelConfig {
238
+ /** Stable channel id (the channelSecrets dict is keyed by it). */
239
+ id: string
240
+ /** Preset provider id this channel was created from ('' = custom). */
241
+ preset: string
242
+ /** Display name shown in the list, the panel, and Agent guidance. */
243
+ name: string
244
+ /** OpenAI-compatible base URL. */
245
+ apiUrl: string
246
+ /** The channel's model catalog (alias upstream id). */
247
+ models: ModelMapping[]
248
+ }
249
+
250
+ /** One built-in provider as the settings card consumes it. */
251
+ export interface PresetProviderView {
252
+ id: string
253
+ name: string
254
+ apiUrl: string
255
+ hint: string
256
+ models: ModelMapping[]
257
+ }
258
+
259
+ export type GenerationTaskStatus = 'queued' | 'running' | 'completed' | 'failed' | 'cancelled'
260
+
261
+ export interface GenerationTask {
262
+ id: string
263
+ request: GenerateRequest
264
+ status: GenerationTaskStatus
265
+ createdAt: number
266
+ startedAt?: number
267
+ finishedAt?: number
268
+ result?: GenerateResult
269
+ error?: string
270
+ }
271
+
272
+ /** GitHub Release update information shown by the client. */
273
+ export interface UpdateInfo {
274
+ currentVersion: string
275
+ latestVersion: string
276
+ updateAvailable: boolean
277
+ releaseUrl: string
278
+ publishedAt?: string
279
+ }
280
+
281
+ /** One history image reference as the browser consumes it (a served URL). */
282
+ export interface HistoryImageRef {
283
+ /** Same-origin URL: `${HISTORY_API.image}/<file>`. */
284
+ url: string
285
+ /** MIME type, e.g. image/png. */
286
+ mime: string
287
+ /** Upstream revised prompt, when provided. */
288
+ revisedPrompt?: string
289
+ }
290
+
291
+ /** A saved generation as the browser consumes it (metadata + served images). */
292
+ export interface HistoryEntry {
293
+ id: string
294
+ createdAt: number
295
+ mode: GenerateMode
296
+ model: string
297
+ prompt: string
298
+ size: string
299
+ quality: string
300
+ detail: string
301
+ n: number
302
+ images: HistoryImageRef[]
303
+ /** Reference-image filename (edit mode), kept for display only. */
304
+ refName?: string
305
+ /** User-managed gallery labels (unused by history entries). */
306
+ tags?: string[]
307
+ /** Channel id snapshot (usage counters key by it for new entries). */
308
+ channelId?: string
309
+ /** Channel display name snapshot (survives channel deletion). */
310
+ channel?: string
311
+ /** Stable id shared by the history entries in one comparison run. */
312
+ comparisonId?: string
313
+ /** Model aliases included in the comparison run. */
314
+ comparisonModels?: string[]
315
+ }
316
+
317
+ /** A history entry the client submits for persistence (images still carry base64). */
318
+ export interface HistoryEntryInput {
319
+ id: string
320
+ createdAt: number
321
+ mode: GenerateMode
322
+ model: string
323
+ prompt: string
324
+ size: string
325
+ quality: string
326
+ detail: string
327
+ n: number
328
+ images: GeneratedImage[]
329
+ refName?: string
330
+ /** Channel id snapshot, tallied by the usage endpoint. */
331
+ channelId?: string
332
+ /** Channel display name snapshot (survives channel deletion). */
333
+ channel?: string
334
+ /** Stable id shared by the history entries in one comparison run. */
335
+ comparisonId?: string
336
+ /** Model aliases included in the comparison run. */
337
+ comparisonModels?: string[]
338
+ }