@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
@@ -1,75 +1,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
- this.queue = new GenerationTaskQueue((request, signal) => this.run(request, signal))
42
- }
43
-
44
- async run(request: GenerateRequest, signal?: AbortSignal): Promise<GenerateResult> {
45
- const view = this.resolve()
46
- const channel = view.channels.find(candidate => candidate.id === request.channelId)
47
- ?? view.channels.find(candidate => candidate.id === view.defaultChannelId)
48
- ?? view.channels[0]
49
- if (channel === undefined) {
50
- throw new ImageGenError('尚未配置任何渠道:请先在「设置 → 插件 → AI 生图」添加渠道并填写 API 地址与密钥', 'no-channels')
51
- }
52
- const upstream: UpstreamConfig = { apiUrl: channel.apiUrl, apiKey: channel.apiKey }
53
- const result = await generateImage(upstream, request, { signal })
54
- try {
55
- const history = await this.history.append({
56
- id: randomUUID(),
57
- createdAt: Date.now(),
58
- mode: request.mode,
59
- model: request.model,
60
- prompt: request.prompt,
61
- size: request.size,
62
- quality: request.quality,
63
- detail: request.detail,
64
- n: request.n,
65
- images: result.images,
66
- ...request.refName === undefined ? {} : { refName: request.refName },
67
- ...request.channelId === undefined ? {} : { channelId: request.channelId },
68
- ...request.channel === undefined ? {} : { channel: request.channel },
69
- })
70
- return { ...result, history }
71
- } catch (error) {
72
- return { ...result, historyError: error instanceof Error ? error.message : String(error) }
73
- }
74
- }
75
- }
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
+ }