@goodandready/dsh-image-gen 0.10.28 → 0.10.29
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/lib/index.js +1 -1
- package/lib/providers/backends/gemini.js +7 -1
- package/lib/providers/backends/seedream.js +8 -2
- package/lib/tools/editing.js +7 -6
- package/lib/tools/frontend.js +0 -7
- package/lib/tools/inspect.js +0 -6
- package/lib/tools/pattern.js +1 -1
- package/lib/tools/processing-advanced.js +0 -7
- package/lib/tools/processing-basic.js +0 -7
- package/lib/tools/responsive.js +1 -0
- package/lib/tools/sketch.js +1 -0
- package/lib/tools/spritesheet.js +1 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -469,7 +469,7 @@ export function apply(ctx, config) {
|
|
|
469
469
|
// Content-addressed: the bytes behind an id never change.
|
|
470
470
|
'Cache-Control': 'public, max-age=31536000, immutable',
|
|
471
471
|
})
|
|
472
|
-
res.end(Buffer.from(stored.data))
|
|
472
|
+
res.end(Buffer.isBuffer(stored.data) ? stored.data : Buffer.from(stored.data))
|
|
473
473
|
} catch (error) {
|
|
474
474
|
res.writeHead(404, { 'Content-Type': 'application/json' })
|
|
475
475
|
res.end(JSON.stringify({ error: 'image not found or reference mismatch' }))
|
|
@@ -15,6 +15,12 @@ export function createGeminiGenerator(deps, job) {
|
|
|
15
15
|
async function gemini(seedArg = seed, promptArg = prompt) {
|
|
16
16
|
const key = await resolveKey(cfg.geminiKeyEnv)
|
|
17
17
|
const model = cfg.geminiModel || 'gemini-2.0-flash-exp-image-generation'
|
|
18
|
+
const timeoutSignal = typeof AbortSignal !== 'undefined' && AbortSignal.timeout
|
|
19
|
+
? AbortSignal.timeout(cfg.timeoutMs || 120000)
|
|
20
|
+
: undefined
|
|
21
|
+
const effectiveSignal = signal && timeoutSignal && AbortSignal.any
|
|
22
|
+
? AbortSignal.any([signal, timeoutSignal])
|
|
23
|
+
: (signal || timeoutSignal)
|
|
18
24
|
const res = await fetchImpl(`https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${encodeURIComponent(key)}`, {
|
|
19
25
|
method: 'POST',
|
|
20
26
|
headers: { 'Content-Type': 'application/json' },
|
|
@@ -22,7 +28,7 @@ export function createGeminiGenerator(deps, job) {
|
|
|
22
28
|
contents: [{ parts: [{ text: promptArg }] }],
|
|
23
29
|
generationConfig: { responseModalities: ['IMAGE'], ...(quality !== undefined ? { imageConfig: { imageQuality: quality } } : {}), ...(style !== undefined ? { imageConfig: { imageStyle: style } } : {}) },
|
|
24
30
|
}),
|
|
25
|
-
signal,
|
|
31
|
+
signal: effectiveSignal,
|
|
26
32
|
})
|
|
27
33
|
const data = await res.json().catch(() => ({}))
|
|
28
34
|
if (!res.ok) {
|
|
@@ -16,6 +16,12 @@ export function createSeedreamGenerator(deps, job) {
|
|
|
16
16
|
async function seedream(seedArg = seed, promptArg = prompt) {
|
|
17
17
|
const key = await resolveKey(cfg.seedreamKeyEnv)
|
|
18
18
|
const base = (cfg.seedreamBaseURL || 'https://api.bytedanceapi.com/v1').replace(/\/+$/, '')
|
|
19
|
+
const timeoutSignal = typeof AbortSignal !== 'undefined' && AbortSignal.timeout
|
|
20
|
+
? AbortSignal.timeout(cfg.timeoutMs || 120000)
|
|
21
|
+
: undefined
|
|
22
|
+
const effectiveSignal = signal && timeoutSignal && AbortSignal.any
|
|
23
|
+
? AbortSignal.any([signal, timeoutSignal])
|
|
24
|
+
: (signal || timeoutSignal)
|
|
19
25
|
const res = await fetchImpl(`${base}/images/generations`, {
|
|
20
26
|
method: 'POST',
|
|
21
27
|
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${key}` },
|
|
@@ -28,7 +34,7 @@ export function createSeedreamGenerator(deps, job) {
|
|
|
28
34
|
...(quality !== undefined ? { quality } : {}),
|
|
29
35
|
...(style !== undefined ? { style } : {}),
|
|
30
36
|
}),
|
|
31
|
-
signal,
|
|
37
|
+
signal: effectiveSignal,
|
|
32
38
|
})
|
|
33
39
|
const data = await res.json().catch(() => ({}))
|
|
34
40
|
if (!res.ok) {
|
|
@@ -41,7 +47,7 @@ export function createSeedreamGenerator(deps, job) {
|
|
|
41
47
|
return { bytes: Buffer.from(item.b64_json, 'base64'), mediaType: normalizeMediaType('image/png', format), width: 0, height: 0, seed: seedArg ?? 0, sourceUrl: '' }
|
|
42
48
|
}
|
|
43
49
|
if (!item.url) throw new Error('Seedream returned neither b64_json nor url')
|
|
44
|
-
const dl = await fetchImpl(item.url, { signal })
|
|
50
|
+
const dl = await fetchImpl(item.url, { signal: effectiveSignal })
|
|
45
51
|
if (!dl.ok) throw new Error(`Seedream download failed (HTTP ${dl.status})`)
|
|
46
52
|
return { bytes: Buffer.from(await dl.arrayBuffer()), mediaType: normalizeMediaType('image/png', format), width: 0, height: 0, seed: seedArg ?? 0, sourceUrl: item.url }
|
|
47
53
|
}
|
package/lib/tools/editing.js
CHANGED
|
@@ -27,6 +27,8 @@ import {
|
|
|
27
27
|
blendImagesFal,
|
|
28
28
|
toLosslessJson,
|
|
29
29
|
saveAttachmentSafe,
|
|
30
|
+
editImageDirect,
|
|
31
|
+
varyImageDirect,
|
|
30
32
|
} from '../providers.js'
|
|
31
33
|
import { resolveConversationImage, analyzeImageWithVision, buildDualOutputMarkdown } from '../resolve-image.js'
|
|
32
34
|
import { sanitizeNegativePrompt, supportsNegativePrompt } from '../negative-sanitizer.js'
|
|
@@ -156,11 +158,10 @@ export function registerEditingTools(ctx, deps) {
|
|
|
156
158
|
mask,
|
|
157
159
|
strength,
|
|
158
160
|
provider,
|
|
161
|
+
signal: exec?.signal,
|
|
159
162
|
}
|
|
160
163
|
|
|
161
|
-
const
|
|
162
|
-
const fn = providers[provider] || providers.fal || providers.custom
|
|
163
|
-
const gen = await fn(seed, effectivePrompt)
|
|
164
|
+
const gen = await editImageDirect(deps, job)
|
|
164
165
|
|
|
165
166
|
const stem = args.output_name ? slugify(args.output_name) : `${source.name}-edit-${seed}`
|
|
166
167
|
const name = `${stem}.${format}`
|
|
@@ -287,11 +288,10 @@ export function registerEditingTools(ctx, deps) {
|
|
|
287
288
|
source,
|
|
288
289
|
strength: variationStrength,
|
|
289
290
|
provider,
|
|
291
|
+
signal: exec?.signal,
|
|
290
292
|
}
|
|
291
293
|
|
|
292
|
-
const
|
|
293
|
-
const fn = providers[provider] || providers.fal || providers.custom
|
|
294
|
-
const gen = await fn(currentSeed, promptText)
|
|
294
|
+
const gen = await varyImageDirect(deps, job)
|
|
295
295
|
|
|
296
296
|
const stem = args.output_name
|
|
297
297
|
? `${slugify(args.output_name)}-var-${i + 1}`
|
|
@@ -432,6 +432,7 @@ export function registerEditingTools(ctx, deps) {
|
|
|
432
432
|
source,
|
|
433
433
|
strength,
|
|
434
434
|
provider,
|
|
435
|
+
signal: exec?.signal,
|
|
435
436
|
}
|
|
436
437
|
|
|
437
438
|
const providers = makeProviders(deps, job)
|
package/lib/tools/frontend.js
CHANGED
|
@@ -6,13 +6,6 @@ import { mkdir, writeFile } from 'node:fs/promises'
|
|
|
6
6
|
import {
|
|
7
7
|
computeGenerationHash,
|
|
8
8
|
IMAGE_SIZES,
|
|
9
|
-
OUTPUT_FORMATS,
|
|
10
|
-
PROVIDER_KEYS,
|
|
11
|
-
buildSidecar,
|
|
12
|
-
makeProviders,
|
|
13
|
-
ASPECT_RATIOS,
|
|
14
|
-
pixelDiff,
|
|
15
|
-
normalizeCount,
|
|
16
9
|
tryGenerate,
|
|
17
10
|
fallbackOrder,
|
|
18
11
|
embedPngMetadata,
|
package/lib/tools/inspect.js
CHANGED
|
@@ -6,13 +6,7 @@ import { mkdir, writeFile } from 'node:fs/promises'
|
|
|
6
6
|
import {
|
|
7
7
|
computeGenerationHash,
|
|
8
8
|
IMAGE_SIZES,
|
|
9
|
-
OUTPUT_FORMATS,
|
|
10
|
-
PROVIDER_KEYS,
|
|
11
|
-
buildSidecar,
|
|
12
|
-
makeProviders,
|
|
13
|
-
ASPECT_RATIOS,
|
|
14
9
|
pixelDiff,
|
|
15
|
-
normalizeCount,
|
|
16
10
|
tryGenerate,
|
|
17
11
|
fallbackOrder,
|
|
18
12
|
embedPngMetadata,
|
package/lib/tools/pattern.js
CHANGED
|
@@ -76,7 +76,7 @@ export function registerPatternTools(ctx, deps) {
|
|
|
76
76
|
resolveKey: (ref) => resolveApiKey(ctx, ref),
|
|
77
77
|
cfg,
|
|
78
78
|
}
|
|
79
|
-
const job = { prompt, size, format, seed, provider }
|
|
79
|
+
const job = { prompt, size, format, seed, provider, signal: exec?.signal }
|
|
80
80
|
const providers = makeProviders(pdeps, job)
|
|
81
81
|
const fn = providers[provider] || providers.fal || providers.custom
|
|
82
82
|
const gen = await fn(seed, prompt)
|
|
@@ -8,13 +8,6 @@ import { mkdir, writeFile } from 'node:fs/promises'
|
|
|
8
8
|
import {
|
|
9
9
|
computeGenerationHash,
|
|
10
10
|
IMAGE_SIZES,
|
|
11
|
-
OUTPUT_FORMATS,
|
|
12
|
-
PROVIDER_KEYS,
|
|
13
|
-
buildSidecar,
|
|
14
|
-
makeProviders,
|
|
15
|
-
ASPECT_RATIOS,
|
|
16
|
-
pixelDiff,
|
|
17
|
-
normalizeCount,
|
|
18
11
|
tryGenerate,
|
|
19
12
|
fallbackOrder,
|
|
20
13
|
embedPngMetadata,
|
|
@@ -8,13 +8,6 @@ import { mkdir, writeFile } from 'node:fs/promises'
|
|
|
8
8
|
import {
|
|
9
9
|
computeGenerationHash,
|
|
10
10
|
IMAGE_SIZES,
|
|
11
|
-
OUTPUT_FORMATS,
|
|
12
|
-
PROVIDER_KEYS,
|
|
13
|
-
buildSidecar,
|
|
14
|
-
makeProviders,
|
|
15
|
-
ASPECT_RATIOS,
|
|
16
|
-
pixelDiff,
|
|
17
|
-
normalizeCount,
|
|
18
11
|
tryGenerate,
|
|
19
12
|
fallbackOrder,
|
|
20
13
|
embedPngMetadata,
|
package/lib/tools/responsive.js
CHANGED
|
@@ -143,6 +143,7 @@ export function registerResponsiveTools(ctx, deps) {
|
|
|
143
143
|
provider,
|
|
144
144
|
...(stylePreset ? { style: stylePreset, style_preset: stylePreset } : {}),
|
|
145
145
|
...(paletteColors ? { palette_colors: paletteColors } : {}),
|
|
146
|
+
signal: exec?.signal,
|
|
146
147
|
}
|
|
147
148
|
const providers = makeProviders(pdeps, job)
|
|
148
149
|
const generators = Object.fromEntries(PROVIDER_KEYS.map((k) => [
|
package/lib/tools/sketch.js
CHANGED
package/lib/tools/spritesheet.js
CHANGED
|
@@ -90,7 +90,7 @@ export function registerSpritesheetTools(ctx, deps) {
|
|
|
90
90
|
resolveKey: (ref) => resolveApiKey(ctx, ref),
|
|
91
91
|
cfg,
|
|
92
92
|
}
|
|
93
|
-
const job = { prompt: prompts[i], size, format, seed: seed + i, provider }
|
|
93
|
+
const job = { prompt: prompts[i], size, format, seed: seed + i, provider, signal: exec?.signal }
|
|
94
94
|
const providers = makeProviders(pdeps, job)
|
|
95
95
|
const fn = providers[provider] || providers.fal || providers.custom
|
|
96
96
|
const gen = await fn(seed + i, prompts[i])
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goodandready/dsh-image-gen",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.29",
|
|
4
4
|
"description": "Image generation for DeepSeek Harness: a generate_image tool with pluggable providers — 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",
|