@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
- `Queuing image generation for concept: ${conceptSlug}, combination: ${combinationString}, language: ${language}`
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
- `Leonardo prompt must be populated before generating images for concept: ${conceptSlug}`
173
+ `❌ Leonardo prompt must be populated before generating images for concept: ${conceptSlug}`
167
174
  );
168
175
  }
169
176
 
170
- const { width, height } = sizes['alchemy']['post4:5'];
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
- await this.context.api().callLeonardo.generateImage({
173
- prompt: concept.leonardoPrompt,
174
- width,
175
- height,
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
- `Post images queued for concept: ${conceptSlug}, combination: ${combinationString}, language: ${language}`
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.86",
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
  }
@@ -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, high-quality prompts for AI image generation. Your task is to generate a detailed, ultra-realistic, and artistically rich prompt for a majestic crown that symbolizes core identity, inner power, and dynamic essence.
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 = (conceptSlug: string, combination: string): string => {
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', 'Pluto', 'Neptune'],
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(`Combination does not match the expected number of planets for concept: ${conceptSlug}`);
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
- .map((sign, index) => `- ${planets[index]}: ${sign}`)
24
- .join('\n');
25
- };
27
+ return signs.map((sign, index) => `- ${planets[index]}: ${sign}`).join('\n');
28
+ };