@goodandready/dsh-image-gen 0.11.8 → 0.11.10
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/README.md +3 -0
- package/README.ru.md +3 -0
- package/README.zh.md +1 -0
- package/lib/providers/backends/local.js +11 -2
- package/lib/tools/generation.js +38 -2
- package/lib/tools/inspect.js +2 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -167,6 +167,9 @@
|
|
|
167
167
|
* **Cache & History Consistency**: Ensured content-addressed disk cache hits synchronize seamlessly with generation history and sidecar metadata.
|
|
168
168
|
* **Test Suite Expansion**: Added `test/batch4-hardening.test.mjs`, expanding test coverage to **128 automated unit tests (100% pass)**.
|
|
169
169
|
|
|
170
|
+
### 🚀 What's New in v0.11.9
|
|
171
|
+
* **ComfyUI Local Backend Payload Fix (#322, GitHub #7)**: Eliminated redundant nesting in `lib/providers/backends/local.js` that wrapped workflows as `{ prompt: { prompt: workflowGraph } }`, resolving `missing_node_type: Node 'ID #prompt' has no class_type` HTTP 400 errors during local ComfyUI generations. Added node shape validation before submission.
|
|
172
|
+
|
|
170
173
|
### 🚀 What's New in v0.11.8
|
|
171
174
|
* **Bounded Config Payloads (#313)**: `PUT /dsh-image-gen/config` now uses bounded request streaming (`readBoundedRequestBody`) with a 64 KB cap, returning HTTP 413 `Payload Too Large` on oversized bodies to prevent memory exhaustion DoS.
|
|
172
175
|
* **Build Parity Gate (#316)**: `scripts/build-client.mjs` supports `--check` mode, enforcing client distribution parity in `npm test`.
|
package/README.ru.md
CHANGED
|
@@ -34,6 +34,9 @@
|
|
|
34
34
|
</div>
|
|
35
35
|
|
|
36
36
|
---
|
|
37
|
+
## 🚀 Обновления v0.11.9: Исправление структуры запроса ComfyUI (#322, GitHub #7)
|
|
38
|
+
* **Устранение двойного вложения промпта в ComfyUI**: В `lib/providers/backends/local.js` устранена лишняя обёртка `{ prompt: workflow }`, приводившая к отправке `{ prompt: { prompt: workflowGraph } }` и ошибке ComfyUI `missing_node_type: Node 'ID #prompt' has no class_type`. Добавлена превентивная валидация графа нод перед отправкой.
|
|
39
|
+
|
|
37
40
|
## 🚀 Обновления v0.11.8: Защита конфигурационных маршрутов, паритет сборки и модульная архитектура
|
|
38
41
|
* **Ограничение размера тела настроек (#313)**: Маршрут `PUT /dsh-image-gen/config` защищён лимитом 64 КБ с возвратом HTTP 413 `Payload Too Large` при превышении, исключая DoS ядра через исчерпание кучи.
|
|
39
42
|
* **Контроль паритета сборки клиента (#316)**: В `scripts/build-client.mjs` добавлен режим `--check`, встроенный в `npm test` для предотвращения рассинхронизации `lib/client.js` с фрагментами `src/client/*`.
|
package/README.zh.md
CHANGED
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
## ⚡ 核心功能与架构提升 (v0.10.0)
|
|
39
39
|
|
|
40
40
|
**`@goodandready/dsh-image-gen`** 为 DeepSeek Harness 提供工业级高可用的图像生成与视觉处理工具链:
|
|
41
|
+
* **ComfyUI 本地后端工作流形状修复 (#322, GitHub #7)**:修复 `lib/providers/backends/local.js` 中多包一层 `{ prompt: workflow }` 导致 ComfyUI 报 `missing_node_type: Node 'ID #prompt' has no class_type` 的缺陷;增加节点结构自检。
|
|
41
42
|
* **8大后端全面支持**: FAL.ai、Replicate、OpenAI/SiliconFlow、ChatGPT Plus (OAuth)、Grok Imagine (OAuth)、ComfyUI/A1111 本地生成、ByteDance SeaDream 与 Google Imagen 3。
|
|
42
43
|
* **指数退避与 Jitter 队列防爆**: 针对 FAL 与 Replicate 异步队列引入智能 Backoff 轮询,彻底杜绝 429 报错。
|
|
43
44
|
* **确定性哈希缓存 (Deterministic Cache)**: 相同 Prompt 与 Seed 的重复请求直接从本地秒级返回,零 API 消耗。
|
|
@@ -97,11 +97,20 @@ export function createLocalGenerator(deps, job) {
|
|
|
97
97
|
})
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
// Validate workflow node shape before submitting to ComfyUI (GH#7)
|
|
101
|
+
if (!workflowGraph || typeof workflowGraph !== 'object' || Array.isArray(workflowGraph)) {
|
|
102
|
+
throw new Error('Local ComfyUI workflow graph must be a valid node object')
|
|
103
|
+
}
|
|
104
|
+
for (const [nodeId, node] of Object.entries(workflowGraph)) {
|
|
105
|
+
if (!node || typeof node !== 'object' || Array.isArray(node) || !node.class_type) {
|
|
106
|
+
throw new Error(`Local ComfyUI workflow node "${nodeId}" is invalid or missing required "class_type" property`)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
101
110
|
const submit = await fetchImpl(`${base}/prompt`, {
|
|
102
111
|
method: 'POST',
|
|
103
112
|
headers: { 'Content-Type': 'application/json' },
|
|
104
|
-
body: JSON.stringify({ prompt:
|
|
113
|
+
body: JSON.stringify({ prompt: workflowGraph, client_id: promptId }),
|
|
105
114
|
signal,
|
|
106
115
|
})
|
|
107
116
|
if (!submit.ok) {
|
package/lib/tools/generation.js
CHANGED
|
@@ -178,16 +178,33 @@ export function registerGenerationTools(ctx, deps) {
|
|
|
178
178
|
type: 'object',
|
|
179
179
|
additionalProperties: true,
|
|
180
180
|
properties: {
|
|
181
|
+
summary: { type: 'string' },
|
|
182
|
+
channel: { type: 'string' },
|
|
183
|
+
provider: { type: 'string' },
|
|
184
|
+
model: { type: 'string' },
|
|
185
|
+
_fallback: { type: 'string' },
|
|
181
186
|
path: { type: 'string' },
|
|
182
187
|
url: { type: 'string' },
|
|
183
188
|
width: { type: 'integer' },
|
|
184
189
|
height: { type: 'integer' },
|
|
185
190
|
seed: { type: 'integer' },
|
|
186
191
|
prompt: { type: 'string' },
|
|
192
|
+
originalPrompt: { type: 'string' },
|
|
187
193
|
format: { type: 'string' },
|
|
194
|
+
cost: { type: 'number' },
|
|
195
|
+
fromCache: { type: 'boolean' },
|
|
196
|
+
qualityReport: { type: 'object', additionalProperties: true },
|
|
197
|
+
anchor: {
|
|
198
|
+
type: 'object',
|
|
199
|
+
additionalProperties: true,
|
|
200
|
+
properties: {
|
|
201
|
+
label: { type: 'string' },
|
|
202
|
+
mode: { type: 'string' },
|
|
203
|
+
},
|
|
204
|
+
},
|
|
188
205
|
attachment: {
|
|
189
206
|
type: 'object',
|
|
190
|
-
additionalProperties:
|
|
207
|
+
additionalProperties: true,
|
|
191
208
|
properties: {
|
|
192
209
|
attachmentId: { type: 'string' },
|
|
193
210
|
mediaType: { type: 'string' },
|
|
@@ -201,7 +218,7 @@ export function registerGenerationTools(ctx, deps) {
|
|
|
201
218
|
type: 'array',
|
|
202
219
|
items: {
|
|
203
220
|
type: 'object',
|
|
204
|
-
additionalProperties:
|
|
221
|
+
additionalProperties: true,
|
|
205
222
|
properties: {
|
|
206
223
|
path: { type: 'string' },
|
|
207
224
|
url: { type: 'string' },
|
|
@@ -209,7 +226,26 @@ export function registerGenerationTools(ctx, deps) {
|
|
|
209
226
|
height: { type: 'integer' },
|
|
210
227
|
seed: { type: 'integer' },
|
|
211
228
|
prompt: { type: 'string' },
|
|
229
|
+
originalPrompt: { type: 'string' },
|
|
212
230
|
format: { type: 'string' },
|
|
231
|
+
cost: { type: 'number' },
|
|
232
|
+
fromCache: { type: 'boolean' },
|
|
233
|
+
qualityReport: { type: 'object', additionalProperties: true },
|
|
234
|
+
_fallback: { type: 'string' },
|
|
235
|
+
provider: { type: 'string' },
|
|
236
|
+
model: { type: 'string' },
|
|
237
|
+
attachment: {
|
|
238
|
+
type: 'object',
|
|
239
|
+
additionalProperties: true,
|
|
240
|
+
properties: {
|
|
241
|
+
attachmentId: { type: 'string' },
|
|
242
|
+
mediaType: { type: 'string' },
|
|
243
|
+
bytes: { type: 'integer' },
|
|
244
|
+
width: { type: 'integer' },
|
|
245
|
+
height: { type: 'integer' },
|
|
246
|
+
name: { type: 'string' },
|
|
247
|
+
},
|
|
248
|
+
},
|
|
213
249
|
},
|
|
214
250
|
},
|
|
215
251
|
},
|
package/lib/tools/inspect.js
CHANGED
|
@@ -22,7 +22,7 @@ export function registerInspectTools(ctx, deps) {
|
|
|
22
22
|
render: (_args, value) => renderToolOutput(value),
|
|
23
23
|
schema: {
|
|
24
24
|
type: 'object',
|
|
25
|
-
additionalProperties:
|
|
25
|
+
additionalProperties: true,
|
|
26
26
|
properties: {
|
|
27
27
|
diffRatio: { type: 'number' },
|
|
28
28
|
error: { type: 'string' },
|
|
@@ -50,7 +50,7 @@ export function registerInspectTools(ctx, deps) {
|
|
|
50
50
|
render: (_args, value) => renderToolOutput(value),
|
|
51
51
|
schema: {
|
|
52
52
|
type: 'object',
|
|
53
|
-
additionalProperties:
|
|
53
|
+
additionalProperties: true,
|
|
54
54
|
properties: {
|
|
55
55
|
qualityScore: { type: 'number' },
|
|
56
56
|
passed: { type: 'boolean' },
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goodandready/dsh-image-gen",
|
|
3
|
-
"version": "0.11.
|
|
4
|
-
"description": "Image generation for DeepSeek Harness: a generate_image tool with pluggable providers
|
|
3
|
+
"version": "0.11.10",
|
|
4
|
+
"description": "Image generation for DeepSeek Harness: a generate_image tool with pluggable providers \u2014 the FAL queue, any OpenAI-compatible images API, or a ChatGPT/Grok subscription with no API key at all. The picture is shown inline in the conversation; the model receives either a link (works with any chat model) or the image itself (needs dsh-vision-bridge or a vision-capable model).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"deepseek-harness",
|
|
7
7
|
"dsh",
|