@dickpy/dsh-imagegen 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +270 -124
  3. package/cordis.patch.yml +8 -8
  4. package/docs/images/ecommerce-mode.png +0 -0
  5. package/docs/images/image-generation-studio-three-column.png +0 -0
  6. package/docs/images/imagegen-overview.png +0 -0
  7. package/docs/videos/agent-chat-edit.gif +0 -0
  8. package/docs/videos/agent-chat-edit.mp4 +0 -0
  9. package/lib/client.js +1859 -420
  10. package/lib/client.js.map +1 -1
  11. package/lib/index.js +327 -112
  12. package/package.json +69 -68
  13. package/src/agent-image-tools.ts +447 -418
  14. package/src/client/ImageGenPanel.tsx +1242 -348
  15. package/src/client/SettingsCard.tsx +936 -936
  16. package/src/client/TemplateLibrary.tsx +336 -336
  17. package/src/client/api.ts +203 -193
  18. package/src/client/channels-form.ts +263 -263
  19. package/src/client/controller.ts +46 -46
  20. package/src/client/conversation-sync.ts +14 -14
  21. package/src/client/css-modules.d.ts +5 -5
  22. package/src/client/helpers.ts +33 -33
  23. package/src/client/image-toolview.module.css +73 -73
  24. package/src/client/image-toolview.tsx +18 -18
  25. package/src/client/index.ts +22 -22
  26. package/src/client/locales.ts +156 -28
  27. package/src/client/mount.tsx +117 -117
  28. package/src/client/panel.module.css +1243 -455
  29. package/src/client/settings-card.module.css +1023 -1023
  30. package/src/client/settings-form.ts +336 -336
  31. package/src/client/settings-scope.ts +298 -298
  32. package/src/client/sidebar-entry.ts +190 -190
  33. package/src/client/templates.module.css +453 -453
  34. package/src/edit-image-command.ts +110 -0
  35. package/src/engine.ts +520 -520
  36. package/src/gallery-store.ts +306 -286
  37. package/src/generation-runtime.ts +84 -79
  38. package/src/history-store.ts +270 -250
  39. package/src/image-format.ts +11 -11
  40. package/src/image-models.ts +19 -19
  41. package/src/index.ts +337 -318
  42. package/src/model-catalog.ts +115 -115
  43. package/src/presets.ts +71 -71
  44. package/src/prompt-enhancer.ts +137 -137
  45. package/src/protocol.ts +380 -338
  46. package/src/routes.ts +964 -916
  47. package/src/task-queue.ts +113 -113
  48. package/src/templates/cases.json +10196 -10196
  49. package/src/templates-store.ts +278 -278
  50. package/src/updater.ts +117 -117
  51. package/docs/images/agent-chat-edit.png +0 -0
  52. package/docs/images/agent-chat-generate.png +0 -0
  53. package/docs/images/agent-chat-poster-workflow.png +0 -0
@@ -1,79 +1,84 @@
1
- /**
2
- * Shared host-side generation runtime. Both the browser routes and Agent tools
3
- * submit to this one queue so persisted history and cancellation semantics stay
4
- * identical regardless of where a request originated.
5
- *
6
- * Requests carry a channel id (host-filled by the route/tool resolution); the
7
- * runtime picks that channel's upstream credentials, otherwise the default
8
- * channel, and records a channel snapshot on the history entry so usage
9
- * counters and filters survive channel deletion.
10
- */
11
-
12
- import { randomUUID } from 'node:crypto'
13
- import { generateImage, ImageGenError, type UpstreamConfig } from './engine.ts'
14
- import { appendHistory } from './history-store.ts'
15
- import { GenerationTaskQueue } from './task-queue.ts'
16
- import type { ChannelConfig, GenerateRequest, GenerateResult, HistoryEntry, HistoryEntryInput } from './protocol.ts'
17
-
18
- /** A channel with its resolved API key (the settings doc holds the key
19
- * separately so redacted reads never expose it). */
20
- export interface RuntimeChannel extends ChannelConfig {
21
- apiKey: string
22
- }
23
-
24
- /** The resolved channels view the runtime picks upstream credentials from. */
25
- export interface ChannelsView {
26
- channels: RuntimeChannel[]
27
- defaultChannelId: string
28
- }
29
-
30
- export interface HistorySink {
31
- append(entry: HistoryEntryInput): Promise<HistoryEntry[]>
32
- }
33
-
34
- export class ImageGenerationRuntime {
35
- readonly queue: GenerationTaskQueue
36
-
37
- constructor(
38
- private readonly resolve: () => ChannelsView,
39
- private readonly history: HistorySink = { append: appendHistory },
40
- ) {
41
- // A comparison can contain up to four models; let those tasks run at the
42
- // same time while still applying a small host-wide concurrency limit.
43
- this.queue = new GenerationTaskQueue((request, signal) => this.run(request, signal), 4)
44
- }
45
-
46
- async run(request: GenerateRequest, signal?: AbortSignal): Promise<GenerateResult> {
47
- const view = this.resolve()
48
- const channel = view.channels.find(candidate => candidate.id === request.channelId)
49
- ?? view.channels.find(candidate => candidate.id === view.defaultChannelId)
50
- ?? view.channels[0]
51
- if (channel === undefined) {
52
- throw new ImageGenError('尚未配置任何渠道:请先在「设置 → 插件 → AI 生图」添加渠道并填写 API 地址与密钥', 'no-channels')
53
- }
54
- const upstream: UpstreamConfig = { apiUrl: channel.apiUrl, apiKey: channel.apiKey }
55
- const result = await generateImage(upstream, request, { signal })
56
- try {
57
- const history = await this.history.append({
58
- id: randomUUID(),
59
- createdAt: Date.now(),
60
- mode: request.mode,
61
- model: request.model,
62
- prompt: request.prompt,
63
- size: request.size,
64
- quality: request.quality,
65
- detail: request.detail,
66
- n: request.n,
67
- images: result.images,
68
- ...request.refName === undefined ? {} : { refName: request.refName },
69
- ...request.channelId === undefined ? {} : { channelId: request.channelId },
70
- ...request.channel === undefined ? {} : { channel: request.channel },
71
- ...request.comparisonId === undefined ? {} : { comparisonId: request.comparisonId },
72
- ...request.comparisonModels === undefined ? {} : { comparisonModels: request.comparisonModels },
73
- })
74
- return { ...result, history }
75
- } catch (error) {
76
- return { ...result, historyError: error instanceof Error ? error.message : String(error) }
77
- }
78
- }
79
- }
1
+ /**
2
+ * Shared host-side generation runtime. Both the browser routes and Agent tools
3
+ * submit to this one queue so persisted history and cancellation semantics stay
4
+ * identical regardless of where a request originated.
5
+ *
6
+ * Requests carry a channel id (host-filled by the route/tool resolution); the
7
+ * runtime picks that channel's upstream credentials, otherwise the default
8
+ * channel, and records a channel snapshot on the history entry so usage
9
+ * counters and filters survive channel deletion.
10
+ */
11
+
12
+ import { randomUUID } from 'node:crypto'
13
+ import { generateImage, ImageGenError, type UpstreamConfig } from './engine.ts'
14
+ import { appendHistory } from './history-store.ts'
15
+ import { GenerationTaskQueue } from './task-queue.ts'
16
+ import type { ChannelConfig, GenerateRequest, GenerateResult, HistoryEntry, HistoryEntryInput } from './protocol.ts'
17
+
18
+ /** A channel with its resolved API key (the settings doc holds the key
19
+ * separately so redacted reads never expose it). */
20
+ export interface RuntimeChannel extends ChannelConfig {
21
+ apiKey: string
22
+ }
23
+
24
+ /** The resolved channels view the runtime picks upstream credentials from. */
25
+ export interface ChannelsView {
26
+ channels: RuntimeChannel[]
27
+ defaultChannelId: string
28
+ }
29
+
30
+ export interface HistorySink {
31
+ append(entry: HistoryEntryInput): Promise<HistoryEntry[]>
32
+ }
33
+
34
+ export class ImageGenerationRuntime {
35
+ readonly queue: GenerationTaskQueue
36
+
37
+ constructor(
38
+ private readonly resolve: () => ChannelsView,
39
+ private readonly history: HistorySink = { append: appendHistory },
40
+ ) {
41
+ // A comparison can contain up to four models; let those tasks run at the
42
+ // same time while still applying a small host-wide concurrency limit.
43
+ this.queue = new GenerationTaskQueue((request, signal) => this.run(request, signal), 4)
44
+ }
45
+
46
+ async run(request: GenerateRequest, signal?: AbortSignal): Promise<GenerateResult> {
47
+ const view = this.resolve()
48
+ const channel = view.channels.find(candidate => candidate.id === request.channelId)
49
+ ?? view.channels.find(candidate => candidate.id === view.defaultChannelId)
50
+ ?? view.channels[0]
51
+ if (channel === undefined) {
52
+ throw new ImageGenError('尚未配置任何渠道:请先在「设置 → 插件 → AI 生图」添加渠道并填写 API 地址与密钥', 'no-channels')
53
+ }
54
+ const upstream: UpstreamConfig = { apiUrl: channel.apiUrl, apiKey: channel.apiKey }
55
+ const result = await generateImage(upstream, request, { signal })
56
+ try {
57
+ const history = await this.history.append({
58
+ id: randomUUID(),
59
+ createdAt: Date.now(),
60
+ mode: request.mode,
61
+ model: request.model,
62
+ prompt: request.prompt,
63
+ size: request.size,
64
+ quality: request.quality,
65
+ detail: request.detail,
66
+ n: request.n,
67
+ images: result.images,
68
+ ...request.refName === undefined ? {} : { refName: request.refName },
69
+ ...request.channelId === undefined ? {} : { channelId: request.channelId },
70
+ ...request.channel === undefined ? {} : { channel: request.channel },
71
+ ...request.comparisonId === undefined ? {} : { comparisonId: request.comparisonId },
72
+ ...request.comparisonModels === undefined ? {} : { comparisonModels: request.comparisonModels },
73
+ ...request.workflow === undefined ? {} : { workflow: request.workflow },
74
+ ...request.projectId === undefined ? {} : { projectId: request.projectId },
75
+ ...request.projectName === undefined ? {} : { projectName: request.projectName },
76
+ ...request.slotKey === undefined ? {} : { slotKey: request.slotKey },
77
+ ...request.slotLabel === undefined ? {} : { slotLabel: request.slotLabel },
78
+ })
79
+ return { ...result, history }
80
+ } catch (error) {
81
+ return { ...result, historyError: error instanceof Error ? error.message : String(error) }
82
+ }
83
+ }
84
+ }