@dickpy/dsh-imagegen 1.2.3 → 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 -181
  3. package/cordis.patch.yml +8 -8
  4. package/docs/images/multi-model-comparison.png +0 -0
  5. package/lib/client.js +2711 -1318
  6. package/lib/client.js.map +1 -1
  7. package/lib/index.js +830 -155
  8. package/package.json +70 -68
  9. package/src/agent-image-tools.ts +418 -316
  10. package/src/client/ImageGenPanel.tsx +1703 -1476
  11. package/src/client/SettingsCard.tsx +936 -648
  12. package/src/client/TemplateLibrary.tsx +336 -336
  13. package/src/client/api.ts +193 -193
  14. package/src/client/channels-form.ts +263 -0
  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 +170 -152
  21. package/src/client/index.ts +32 -22
  22. package/src/client/locales.ts +610 -484
  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 -536
  26. package/src/client/settings-form.ts +336 -336
  27. package/src/client/settings-scope.ts +298 -250
  28. package/src/client/sidebar-entry.ts +148 -102
  29. package/src/client/templates.module.css +453 -453
  30. package/src/engine.ts +520 -464
  31. package/src/gallery-store.ts +286 -280
  32. package/src/generation-runtime.ts +79 -48
  33. package/src/history-store.ts +250 -238
  34. package/src/image-format.ts +11 -0
  35. package/src/image-models.ts +19 -19
  36. package/src/index.ts +318 -212
  37. package/src/model-catalog.ts +115 -0
  38. package/src/presets.ts +71 -0
  39. package/src/prompt-enhancer.ts +137 -79
  40. package/src/protocol.ts +338 -253
  41. package/src/routes.ts +916 -738
  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,253 +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.2.3'
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-resident generation queue endpoints. */
34
- export const TASK_API = {
35
- submit: '/api/dsh-imagegen/tasks/submit',
36
- list: '/api/dsh-imagegen/tasks/list',
37
- cancel: '/api/dsh-imagegen/tasks/cancel',
38
- retry: '/api/dsh-imagegen/tasks/retry',
39
- } as const
40
-
41
- /** Host-mediated GitHub Release update routes. */
42
- export const UPDATE_API = {
43
- check: '/api/dsh-imagegen/update/check',
44
- apply: '/api/dsh-imagegen/update/apply',
45
- } as const
46
-
47
- /**
48
- * Same-origin route family for the host-persisted generation history. Images
49
- * live as files under ~/.dsh/dsh-imagegen/images/ and are served back through
50
- * the `image` prefix route, so list responses carry metadata only (never
51
- * base64) and the browser loads thumbnails/previews lazily.
52
- */
53
- export const HISTORY_API = {
54
- list: '/api/dsh-imagegen/history/list',
55
- append: '/api/dsh-imagegen/history/append',
56
- remove: '/api/dsh-imagegen/history/remove',
57
- clear: '/api/dsh-imagegen/history/clear',
58
- image: '/api/dsh-imagegen/history/image',
59
- } as const
60
-
61
- /**
62
- * Same-origin route family for the user-curated gallery (favorites). Entries
63
- * reuse the history wire shape and persist under ~/.dsh/dsh-imagegen/gallery/;
64
- * unlike history there is no size cap 鈥?the user adds images on purpose.
65
- */
66
- export const GALLERY_API = {
67
- list: '/api/dsh-imagegen/gallery/list',
68
- append: '/api/dsh-imagegen/gallery/append',
69
- remove: '/api/dsh-imagegen/gallery/remove',
70
- clear: '/api/dsh-imagegen/gallery/clear',
71
- tags: '/api/dsh-imagegen/gallery/tags',
72
- image: '/api/dsh-imagegen/gallery/image',
73
- } as const
74
-
75
- /** Maximum number of history entries retained host-side (oldest evicted). */
76
- export const HISTORY_MAX = 50
77
-
78
- /**
79
- * Same-origin route family for the bundled prompt-template library
80
- * (awesome-gpt-image-2 mirror). The case list ships inside the package and is
81
- * served by the host; reference images are proxied through the `image` prefix
82
- * route and cached on disk so repeated views never hit the network again.
83
- */
84
- export const TEMPLATES_API = {
85
- list: '/api/dsh-imagegen/templates/list',
86
- refresh: '/api/dsh-imagegen/templates/refresh',
87
- image: '/api/dsh-imagegen/templates/image',
88
- } as const
89
-
90
- /** One prompt-library case as the browser consumes it. */
91
- export interface TemplateCase {
92
- /** Upstream case number (stable across refreshes). */
93
- id: number
94
- /** Short case title. */
95
- title: string
96
- /** Full reusable prompt text. */
97
- prompt: string
98
- /** English category name (grouping key). */
99
- category: string
100
- /** Chinese category display name. */
101
- categoryZh: string
102
- /** Style tags. */
103
- styles: string[]
104
- /** Scene tags. */
105
- scenes: string[]
106
- /** Original author handle, e.g. @vista8. */
107
- sourceLabel: string
108
- /** Original author link. */
109
- sourceUrl: string
110
- /** awesome-gpt-image-2 repo anchor link. */
111
- githubUrl: string
112
- /** Reference-image file name served through the image route ('' when none). */
113
- image: string
114
- /** Whether the source gallery featured the case. */
115
- featured: boolean
116
- }
117
-
118
- /** Template-library list payload. */
119
- export interface TemplateListResult {
120
- cases: TemplateCase[]
121
- total: number
122
- /** Where the served list came from. */
123
- origin: 'bundled' | 'refreshed'
124
- /** Upstream repository the library mirrors. */
125
- repository: string
126
- /** ISO time of the last successful refresh / bundle snapshot. */
127
- fetchedAt: string
128
- }
129
-
130
- /** Template-library refresh outcome. */
131
- export interface TemplateRefreshResult {
132
- total: number
133
- fetchedAt: string
134
- }
135
-
136
- /** Generation modes. */
137
- export type GenerateMode = 'text' | 'edit'
138
-
139
- /** A client 鈫?host generate request (what the panel collects). */
140
- export interface GenerateRequest {
141
- /** text-to-image (images/generations) or image-to-image (images/edits). */
142
- mode: GenerateMode
143
- /** Upstream model name, e.g. gpt-image-2. */
144
- model: string
145
- /** The prompt. Upstream providers may impose their own length limits. */
146
- prompt: string
147
- /** Canvas size as an aspect ratio: 'auto' or e.g. '1:1' / '16:9' / '21:9'.
148
- * The host maps it onto each model's own vocabulary (aspect_ratio for Grok
149
- * and Nano Banana, size-aspect for Seedream, the closest pixel size for
150
- * OpenAI-compatible endpoints). */
151
- size: string
152
- /** Clarity tier: 'auto' | '1k' | '2k' | '4k'. The host maps it onto the
153
- * model's own vocabulary (resolution for Grok / Seedream, image_size for
154
- * Nano Banana, quality for OpenAI). */
155
- quality: string
156
- /** Number of images, 1-4. */
157
- n: number
158
- /**
159
- * Passthrough detail parameter: '' (omit), 'standard', or 'high'. Some
160
- * gpt-image-2 gateways expose it; official OpenAI endpoints reject unknown
161
- * parameters, so the UI defaults to '' (omit).
162
- */
163
- detail: string
164
- /** Reference image as a data URL (edit mode only). */
165
- image?: string
166
- /** Original reference-image name, retained in the history entry. */
167
- refName?: string
168
- }
169
-
170
- /** One generated image, normalized host-side to base64 so the browser never
171
- * has to fetch the upstream (no CORS, no key exposure). */
172
- export interface GeneratedImage {
173
- /** Raw base64 payload (no data: prefix). */
174
- b64: string
175
- /** MIME type of the payload, e.g. image/png. */
176
- mime: string
177
- /** Upstream revised prompt, when provided. */
178
- revisedPrompt?: string
179
- }
180
-
181
- /** Successful generate outcome. */
182
- export interface GenerateResult {
183
- images: GeneratedImage[]
184
- /** Updated host-persisted history, when returned by the generate route. */
185
- history?: HistoryEntry[]
186
- /** Persistence failure after images were successfully generated. */
187
- historyError?: string
188
- }
189
-
190
- export type GenerationTaskStatus = 'queued' | 'running' | 'completed' | 'failed' | 'cancelled'
191
-
192
- export interface GenerationTask {
193
- id: string
194
- request: GenerateRequest
195
- status: GenerationTaskStatus
196
- createdAt: number
197
- startedAt?: number
198
- finishedAt?: number
199
- result?: GenerateResult
200
- error?: string
201
- }
202
-
203
- /** GitHub Release update information shown by the client. */
204
- export interface UpdateInfo {
205
- currentVersion: string
206
- latestVersion: string
207
- updateAvailable: boolean
208
- releaseUrl: string
209
- publishedAt?: string
210
- }
211
-
212
- /** One history image reference as the browser consumes it (a served URL). */
213
- export interface HistoryImageRef {
214
- /** Same-origin URL: `${HISTORY_API.image}/<file>`. */
215
- url: string
216
- /** MIME type, e.g. image/png. */
217
- mime: string
218
- /** Upstream revised prompt, when provided. */
219
- revisedPrompt?: string
220
- }
221
-
222
- /** A saved generation as the browser consumes it (metadata + served images). */
223
- export interface HistoryEntry {
224
- id: string
225
- createdAt: number
226
- mode: GenerateMode
227
- model: string
228
- prompt: string
229
- size: string
230
- quality: string
231
- detail: string
232
- n: number
233
- images: HistoryImageRef[]
234
- /** Reference-image filename (edit mode), kept for display only. */
235
- refName?: string
236
- /** User-managed gallery labels (unused by history entries). */
237
- tags?: string[]
238
- }
239
-
240
- /** A history entry the client submits for persistence (images still carry base64). */
241
- export interface HistoryEntryInput {
242
- id: string
243
- createdAt: number
244
- mode: GenerateMode
245
- model: string
246
- prompt: string
247
- size: string
248
- quality: string
249
- detail: string
250
- n: number
251
- images: GeneratedImage[]
252
- refName?: string
253
- }
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
+ }