@zodic/shared 0.0.86 → 0.0.88
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.
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { and, eq } from 'drizzle-orm';
|
|
1
2
|
import { inject, injectable } from 'inversify';
|
|
2
3
|
import 'reflect-metadata';
|
|
4
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
5
|
+
import { schema } from '../..';
|
|
3
6
|
import { Languages } from '../../types';
|
|
4
7
|
import { KVConcept, sizes } from '../../types/scopes/legacy';
|
|
5
8
|
import { buildConceptKVKey } from '../../utils/KVKeysBuilders';
|
|
@@ -155,31 +158,131 @@ export class ConceptService {
|
|
|
155
158
|
conceptSlug: string,
|
|
156
159
|
combinationString: string
|
|
157
160
|
): Promise<void> {
|
|
161
|
+
const drizzle = this.context.drizzle();
|
|
162
|
+
const { width, height } = sizes['alchemy']['post4:5'];
|
|
163
|
+
const { generations, conceptCombinations, concepts } = schema;
|
|
164
|
+
|
|
158
165
|
const kvKey = buildConceptKVKey(language, conceptSlug, combinationString);
|
|
159
166
|
console.log(
|
|
160
|
-
|
|
167
|
+
`🚀 Queuing image generation for concept: ${conceptSlug}, combination: ${combinationString}, language: ${language}`
|
|
161
168
|
);
|
|
162
169
|
|
|
163
170
|
const concept = await this.getKVConcept(kvKey);
|
|
164
171
|
if (!concept.leonardoPrompt) {
|
|
165
172
|
throw new Error(
|
|
166
|
-
|
|
173
|
+
`❌ Leonardo prompt must be populated before generating images for concept: ${conceptSlug}`
|
|
167
174
|
);
|
|
168
175
|
}
|
|
169
176
|
|
|
170
|
-
|
|
177
|
+
// 🔍 Fetch Concept ID using conceptSlug
|
|
178
|
+
const conceptRecord = await drizzle
|
|
179
|
+
.select({
|
|
180
|
+
id: concepts.id,
|
|
181
|
+
planet1: concepts.planet1,
|
|
182
|
+
planet2: concepts.planet2,
|
|
183
|
+
planet3: concepts.planet3,
|
|
184
|
+
})
|
|
185
|
+
.from(concepts)
|
|
186
|
+
.where(eq(concepts.slug, conceptSlug))
|
|
187
|
+
.limit(1);
|
|
188
|
+
|
|
189
|
+
if (conceptRecord.length === 0) {
|
|
190
|
+
throw new Error(`❌ No concept found for slug: ${conceptSlug}`);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const { id: conceptId, planet1, planet2, planet3 } = conceptRecord[0];
|
|
194
|
+
console.log(
|
|
195
|
+
`✅ Retrieved conceptId: ${conceptId} for slug: ${conceptSlug}`
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
const [planet1Sign, planet2Sign, planet3Sign] =
|
|
199
|
+
combinationString.split('-');
|
|
200
|
+
|
|
201
|
+
if (!planet1Sign || !planet2Sign || (planet3 && !planet3Sign)) {
|
|
202
|
+
throw new Error(
|
|
203
|
+
`❌ Invalid combinationString: ${combinationString} (Expected format: sign1-sign2-[sign3])`
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
console.log(
|
|
208
|
+
`🌌 Extracted planet signs: ${planet1} -> ${planet1Sign}, ${planet2} -> ${planet2Sign}, ${
|
|
209
|
+
planet3 || 'N/A'
|
|
210
|
+
} -> ${planet3Sign || 'N/A'}`
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
// 🔍 Ensure Concept Combination exists
|
|
214
|
+
let [conceptCombination] = await drizzle
|
|
215
|
+
.select({ id: conceptCombinations.id })
|
|
216
|
+
.from(conceptCombinations)
|
|
217
|
+
.where(
|
|
218
|
+
and(
|
|
219
|
+
eq(conceptCombinations.combinationString, combinationString),
|
|
220
|
+
eq(conceptCombinations.conceptId, conceptId)
|
|
221
|
+
)
|
|
222
|
+
)
|
|
223
|
+
.limit(1);
|
|
224
|
+
|
|
225
|
+
if (!conceptCombination) {
|
|
226
|
+
console.log(
|
|
227
|
+
`🔍 No existing conceptCombination found. Creating new entry for ${conceptSlug}:${combinationString}`
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
const [insertedCombination] = await drizzle
|
|
231
|
+
.insert(conceptCombinations)
|
|
232
|
+
.values({
|
|
233
|
+
id: uuidv4(),
|
|
234
|
+
combinationString,
|
|
235
|
+
conceptId,
|
|
236
|
+
planet1Sign,
|
|
237
|
+
planet2Sign,
|
|
238
|
+
planet3Sign, // Ensure null if planet3 is not used
|
|
239
|
+
})
|
|
240
|
+
.returning({ id: conceptCombinations.id });
|
|
241
|
+
|
|
242
|
+
conceptCombination = insertedCombination;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const conceptCombinationId = conceptCombination.id;
|
|
246
|
+
console.log(
|
|
247
|
+
`✅ Using conceptCombinationId: ${conceptCombinationId} for ${conceptSlug}:${combinationString}`
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
// 🎨 Request Leonardo AI image generation
|
|
251
|
+
console.log(`🎨 Requesting Leonardo AI image generation...`);
|
|
252
|
+
const leonardoResponse = await this.context
|
|
253
|
+
.api()
|
|
254
|
+
.callLeonardo.generateImage({
|
|
255
|
+
prompt: concept.leonardoPrompt,
|
|
256
|
+
width,
|
|
257
|
+
height,
|
|
258
|
+
});
|
|
171
259
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
260
|
+
const generationId = leonardoResponse?.sdGenerationJob?.generationId;
|
|
261
|
+
if (!generationId) {
|
|
262
|
+
throw new Error(
|
|
263
|
+
`❌ Failed to retrieve generationId from Leonardo response`
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
console.log(`✅ Leonardo Generation ID received: ${generationId}`);
|
|
268
|
+
|
|
269
|
+
// 📝 Insert Generation Record with the received generationId
|
|
270
|
+
await drizzle.insert(generations).values({
|
|
271
|
+
id: generationId, // Use the ID from Leonardo
|
|
272
|
+
conceptCombinationId,
|
|
273
|
+
type: 'concept_image',
|
|
274
|
+
status: 'pending',
|
|
275
|
+
createdAt: new Date(),
|
|
176
276
|
});
|
|
177
277
|
|
|
178
278
|
console.log(
|
|
179
|
-
|
|
279
|
+
`📝 Generation record created: ${generationId} for ${conceptSlug}:${combinationString}`
|
|
180
280
|
);
|
|
181
|
-
}
|
|
182
281
|
|
|
282
|
+
console.log(
|
|
283
|
+
`🎨 Leonardo AI image generation triggered for ${conceptSlug}:${combinationString}, tracking ID: ${generationId}`
|
|
284
|
+
);
|
|
285
|
+
}
|
|
183
286
|
/**
|
|
184
287
|
* Fetch and initialize a KVConcept object if not present.
|
|
185
288
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zodic/shared",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.88",
|
|
4
4
|
"module": "index.ts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"inversify": "^6.2.1",
|
|
33
33
|
"jose": "^5.9.6",
|
|
34
34
|
"openai": "^4.81.0",
|
|
35
|
-
"reflect-metadata": "^0.2.2"
|
|
35
|
+
"reflect-metadata": "^0.2.2",
|
|
36
|
+
"uuid": "^11.0.5"
|
|
36
37
|
}
|
|
37
38
|
}
|
package/utils/conceptPrompts.ts
CHANGED
|
@@ -171,20 +171,7 @@ Write each section with clarity, insight, and emotional resonance. Avoid mention
|
|
|
171
171
|
`;
|
|
172
172
|
|
|
173
173
|
export const PROMPT_GENERATE_CROWN_LEONARDO = `
|
|
174
|
-
You are an expert creative writer specializing in crafting vivid
|
|
175
|
-
|
|
176
|
-
Instructions:
|
|
177
|
-
• Describe the crown’s composition—its base materials (e.g., gold, platinum, obsidian, celestial metal) and how they contribute to its symbolic meaning.
|
|
178
|
-
• Detail the crown’s structure—its form, height, weight, and shape, ensuring it exudes a regal yet mystical presence.
|
|
179
|
-
• Include engravings, gemstones, and artistic patterns—these should evoke deeper symbolic meaning rather than being purely ornamental.
|
|
180
|
-
• Describe the crown’s light and aura—does it emit a soft celestial glow, a bold fiery radiance, or a shimmering spectral light? How does this reinforce its power?
|
|
181
|
-
• Explain how the crown interacts with its environment—does it rest upon an ancient pedestal, hover weightlessly in the air, or radiate energy from its wearer?
|
|
182
|
-
• Ensure the description is cinematic and photorealistic—incorporate advanced rendering details like “ultra-realistic,” “8K resolution,” “HDR lighting,” and “cinematic composition.”
|
|
183
|
-
|
|
184
|
-
Your Response Should Begin With:
|
|
185
|
-
“Create an ultra-realistic, 8K resolution, HDR image of a majestic crown symbolizing core identity, inner power, and dynamic essence.”
|
|
186
|
-
|
|
187
|
-
Avoid direct zodiac sign references, but ensure the crown’s materials, engravings, and overall aura reflect the symbolic essence of the given Sun, Ascendant, and Moon signs.
|
|
174
|
+
You are an expert creative writer specializing in crafting intricate and vivid prompts for AI image generation. Your task is to create a detailed, high-quality prompt for a majestic crown that symbolizes core identity, inner power, and essence. The design of the crown must reflect the symbolic traits of a given zodiac sign combination. Describe the crown in detail, including its materials, structure, symbolic engravings, and intricate patterns. Focus on capturing its regal and radiant essence through meaningful motifs and elegant design elements, avoiding direct references to zodiac signs. Highlight the type of light it reflects or emits, the way it sits atop its pedestal or bearer, and the aura of authority and grace it projects. Ensure the design elements convey dignity, individuality, and inner strength, while maintaining an artistic and mystical tone. Include artistic rendering details such as “ultra-realistic,” “8K resolution,” and “HDR” to guide the AI model. Keep the description concise, under 1500 characters, and ensure it can be used directly with Leonardo.ai for image generation. Respond with a single descriptive paragraph based on the given zodiac sign combination.
|
|
188
175
|
`;
|
|
189
176
|
|
|
190
177
|
export const PROMPT_GENERATE_SCEPTER_LEONARDO = `
|
|
@@ -1,25 +1,28 @@
|
|
|
1
|
-
export const mapConceptToPlanets = (
|
|
1
|
+
export const mapConceptToPlanets = (
|
|
2
|
+
conceptSlug: string,
|
|
3
|
+
combination: string
|
|
4
|
+
): string => {
|
|
2
5
|
const signs = combination.split('-');
|
|
3
6
|
|
|
4
7
|
const conceptPlanetMapping: Record<string, string[]> = {
|
|
5
8
|
crown: ['Sun', 'Ascendant', 'Moon'],
|
|
6
9
|
scepter: ['Mercury', 'Venus', 'Mars'],
|
|
7
10
|
amulet: ['Jupiter', 'Saturn', 'Chiron'],
|
|
8
|
-
lantern: ['Uranus', '
|
|
11
|
+
lantern: ['Uranus', 'Neptune', 'Pluto'],
|
|
9
12
|
orb: ['North Node', 'Midheaven', 'Pars Fortuna'],
|
|
10
13
|
};
|
|
11
14
|
|
|
12
15
|
const planets = conceptPlanetMapping[conceptSlug];
|
|
13
|
-
|
|
16
|
+
|
|
14
17
|
if (!planets) {
|
|
15
18
|
throw new Error(`Invalid conceptSlug provided: ${conceptSlug}`);
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
if (signs.length !== planets.length) {
|
|
19
|
-
throw new Error(
|
|
22
|
+
throw new Error(
|
|
23
|
+
`Combination does not match the expected number of planets for concept: ${conceptSlug}`
|
|
24
|
+
);
|
|
20
25
|
}
|
|
21
26
|
|
|
22
|
-
return signs
|
|
23
|
-
|
|
24
|
-
.join('\n');
|
|
25
|
-
};
|
|
27
|
+
return signs.map((sign, index) => `- ${planets[index]}: ${sign}`).join('\n');
|
|
28
|
+
};
|