@goodandready/dsh-image-gen 0.10.31 → 0.10.32
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/anchor-helpers.js +103 -0
- package/lib/client.js +462 -52
- package/lib/fallback-router.js +163 -0
- package/lib/index.js +4 -0
- package/lib/register-tools.js +6 -0
- package/lib/style-matrix-helpers.js +85 -0
- package/lib/tools/anchor.js +129 -0
- package/lib/tools/generation.js +21 -5
- package/lib/tools/style-matrix.js +227 -0
- package/lib/tools/ui-asset.js +238 -0
- package/lib/ui-asset-helpers.js +44 -0
- package/package.json +1 -1
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// anchor-helpers.js — Character & Style Reference Anchor manager (#283).
|
|
2
|
+
// Maintains active visual identity and style reference across multi-turn sessions.
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* In-memory registry of active visual anchors keyed by scopeId (e.g. session id).
|
|
6
|
+
* Structure: Map<string, { image: string, label: string, mode: 'character'|'style', strength: number, updatedAt: string }>
|
|
7
|
+
*/
|
|
8
|
+
const sessionAnchors = new Map()
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Normalizes anchor strength between 0.1 and 1.0.
|
|
12
|
+
*
|
|
13
|
+
* @param {number|undefined} val
|
|
14
|
+
* @returns {number}
|
|
15
|
+
*/
|
|
16
|
+
export function normalizeAnchorStrength(val) {
|
|
17
|
+
if (typeof val !== 'number' || Number.isNaN(val)) return 0.65
|
|
18
|
+
return Math.min(1.0, Math.max(0.1, Number(val.toFixed(2))))
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Sets or updates the active visual anchor for a given session or scope.
|
|
23
|
+
*
|
|
24
|
+
* @param {string} scopeId Session or workspace identifier
|
|
25
|
+
* @param {object} data
|
|
26
|
+
* @param {string} data.image Image URL, attachment ID (sha256:...), or local path
|
|
27
|
+
* @param {string} [data.label] Human-readable description of character/style
|
|
28
|
+
* @param {'character'|'style'} [data.mode='style']
|
|
29
|
+
* @param {number} [data.strength=0.65]
|
|
30
|
+
* @returns {object} The stored anchor record
|
|
31
|
+
*/
|
|
32
|
+
export function setSessionAnchor(scopeId, data = {}) {
|
|
33
|
+
const key = String(scopeId || 'default')
|
|
34
|
+
if (!data.image) {
|
|
35
|
+
throw new Error('An anchor image (URL, path, or attachment ID) is required.')
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const mode = data.mode === 'character' ? 'character' : 'style'
|
|
39
|
+
const strength = normalizeAnchorStrength(data.strength)
|
|
40
|
+
const label = String(data.label || (mode === 'character' ? 'Character Anchor' : 'Style Anchor')).trim()
|
|
41
|
+
|
|
42
|
+
const anchor = {
|
|
43
|
+
image: String(data.image).trim(),
|
|
44
|
+
label,
|
|
45
|
+
mode,
|
|
46
|
+
strength,
|
|
47
|
+
updatedAt: new Date().toISOString(),
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
sessionAnchors.set(key, anchor)
|
|
51
|
+
return anchor
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Retrieves the currently active visual anchor for a session scope.
|
|
56
|
+
*
|
|
57
|
+
* @param {string} scopeId
|
|
58
|
+
* @returns {object|null}
|
|
59
|
+
*/
|
|
60
|
+
export function getSessionAnchor(scopeId) {
|
|
61
|
+
const key = String(scopeId || 'default')
|
|
62
|
+
return sessionAnchors.get(key) || null
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Clears the active visual anchor for a session scope.
|
|
67
|
+
*
|
|
68
|
+
* @param {string} scopeId
|
|
69
|
+
* @returns {boolean} True if an anchor was present and removed
|
|
70
|
+
*/
|
|
71
|
+
export function clearSessionAnchor(scopeId) {
|
|
72
|
+
const key = String(scopeId || 'default')
|
|
73
|
+
return sessionAnchors.delete(key)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Clears all active anchors (for testing/cleanup).
|
|
78
|
+
*/
|
|
79
|
+
export function clearAllAnchors() {
|
|
80
|
+
sessionAnchors.clear()
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Injects anchor reference hints into the prompt if an anchor is active and not already included.
|
|
85
|
+
*
|
|
86
|
+
* @param {object|null} anchor
|
|
87
|
+
* @param {string} prompt
|
|
88
|
+
* @returns {string}
|
|
89
|
+
*/
|
|
90
|
+
export function applyAnchorPromptHints(anchor, prompt) {
|
|
91
|
+
if (!anchor || !anchor.label) return prompt
|
|
92
|
+
const lower = prompt.toLowerCase()
|
|
93
|
+
const labelLower = anchor.label.toLowerCase()
|
|
94
|
+
|
|
95
|
+
// Avoid duplicate injection if user already mentioned the anchor label
|
|
96
|
+
if (lower.includes(labelLower)) return prompt
|
|
97
|
+
|
|
98
|
+
if (anchor.mode === 'character') {
|
|
99
|
+
return `${prompt}, visual character anchor: ${anchor.label}, maintaining consistent facial features, costume, and physical identity`
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return `${prompt}, visual style anchor: ${anchor.label}, maintaining consistent aesthetic palette, rendering technique, and lighting`
|
|
103
|
+
}
|