@zodic/shared 0.0.372 → 0.0.373
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/app/services/ArchetypeService.ts +280 -277
- package/app/workflow/ArchetypeWorkflow.ts +179 -118
- package/package.json +1 -1
|
@@ -28,42 +28,41 @@ export class ArchetypeService {
|
|
|
28
28
|
message: string,
|
|
29
29
|
context: Record<string, any> = {}
|
|
30
30
|
) {
|
|
31
|
-
const logMessage = `[${level.toUpperCase()}] ${message}`;
|
|
32
|
-
|
|
33
|
-
console
|
|
34
|
-
// try {
|
|
35
|
-
// await db
|
|
36
|
-
// .insert(schema.logs)
|
|
37
|
-
// .values({
|
|
38
|
-
// id: logId,
|
|
39
|
-
// level,
|
|
40
|
-
// message,
|
|
41
|
-
// context: JSON.stringify(context),
|
|
42
|
-
// createdAt: new Date().getTime(),
|
|
43
|
-
// })
|
|
44
|
-
// .execute();
|
|
45
|
-
// } catch (error) {
|
|
46
|
-
// console.error('[ERROR] Failed to persist log to database:', {
|
|
47
|
-
// error,
|
|
48
|
-
// logId,
|
|
49
|
-
// message,
|
|
50
|
-
// context,
|
|
51
|
-
// });
|
|
52
|
-
// }
|
|
31
|
+
const logMessage = `[${new Date().toISOString()}] [${level.toUpperCase()}] ${message}`;
|
|
32
|
+
|
|
33
|
+
console[level](logMessage, context);
|
|
53
34
|
}
|
|
54
35
|
|
|
55
|
-
// Replace generateArchetypeNames and generateArchetypeNamesBatch
|
|
56
36
|
async generateArchetypeNames(
|
|
57
37
|
combinationString: string,
|
|
58
|
-
|
|
38
|
+
override: boolean = false,
|
|
59
39
|
indexesToGenerate: number[] = [1, 2, 3]
|
|
60
40
|
) {
|
|
61
41
|
await this.log('info', 'Starting generateArchetypeNames', {
|
|
62
42
|
combinationString,
|
|
63
|
-
|
|
43
|
+
override,
|
|
64
44
|
indexesToGenerate,
|
|
65
45
|
});
|
|
66
46
|
|
|
47
|
+
const db = this.context.drizzle();
|
|
48
|
+
const existingArchetypes = await db
|
|
49
|
+
.select()
|
|
50
|
+
.from(schema.archetypesData)
|
|
51
|
+
.where(eq(schema.archetypesData.combination, combinationString))
|
|
52
|
+
.execute();
|
|
53
|
+
|
|
54
|
+
if (
|
|
55
|
+
!override &&
|
|
56
|
+
existingArchetypes.length >= 3 * 2 * 2 && // 3 indexes * 2 genders * 2 languages
|
|
57
|
+
existingArchetypes.every((a) => a.name && a.essenceLine)
|
|
58
|
+
) {
|
|
59
|
+
await this.log('info', 'Skipping archetype names generation', {
|
|
60
|
+
reason: 'All archetypes have names and essence lines',
|
|
61
|
+
existingCount: existingArchetypes.length,
|
|
62
|
+
});
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
67
66
|
const [sun, ascendant, moon] = combinationString.split(
|
|
68
67
|
'-'
|
|
69
68
|
) as ZodiacSignSlug[];
|
|
@@ -95,8 +94,6 @@ export class ArchetypeService {
|
|
|
95
94
|
portugueseVariants,
|
|
96
95
|
});
|
|
97
96
|
|
|
98
|
-
const db = this.context.drizzle();
|
|
99
|
-
|
|
100
97
|
async function isEnglishNameDuplicate(name: string): Promise<boolean> {
|
|
101
98
|
const result = await db
|
|
102
99
|
.select({ name: schema.archetypesData.name })
|
|
@@ -121,7 +118,10 @@ export class ArchetypeService {
|
|
|
121
118
|
await this.log(
|
|
122
119
|
'debug',
|
|
123
120
|
`Skipping index ${index} as it is not in indexesToGenerate`,
|
|
124
|
-
{
|
|
121
|
+
{
|
|
122
|
+
index,
|
|
123
|
+
indexesToGenerate,
|
|
124
|
+
}
|
|
125
125
|
);
|
|
126
126
|
continue;
|
|
127
127
|
}
|
|
@@ -148,6 +148,15 @@ export class ArchetypeService {
|
|
|
148
148
|
const essenceLine =
|
|
149
149
|
lang === 'en-us' ? entry.essenceLine : ptVariant.essenceLine;
|
|
150
150
|
|
|
151
|
+
const existing = existingArchetypes.find((a) => a.id === id);
|
|
152
|
+
if (existing && !override && existing.name && existing.essenceLine) {
|
|
153
|
+
await this.log('debug', `Skipping existing archetype ${id}`, {
|
|
154
|
+
name: existing.name,
|
|
155
|
+
essenceLine: existing.essenceLine,
|
|
156
|
+
});
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
|
|
151
160
|
await this.log('debug', `Saving archetype name for ${id}`, {
|
|
152
161
|
name,
|
|
153
162
|
essenceLine,
|
|
@@ -171,6 +180,7 @@ export class ArchetypeService {
|
|
|
171
180
|
name,
|
|
172
181
|
essenceLine,
|
|
173
182
|
updatedAt: new Date().getTime(),
|
|
183
|
+
status: 'idle',
|
|
174
184
|
},
|
|
175
185
|
});
|
|
176
186
|
|
|
@@ -245,12 +255,14 @@ export class ArchetypeService {
|
|
|
245
255
|
async generateDescriptionsAndVirtues(
|
|
246
256
|
combinationString: string,
|
|
247
257
|
gender: Gender,
|
|
248
|
-
language: string
|
|
258
|
+
language: string,
|
|
259
|
+
override: boolean = false
|
|
249
260
|
): Promise<ParsedDescriptionAndVirtues[]> {
|
|
250
261
|
await this.log('info', 'Starting generateDescriptionsAndVirtues', {
|
|
251
262
|
combinationString,
|
|
252
263
|
gender,
|
|
253
264
|
language,
|
|
265
|
+
override,
|
|
254
266
|
});
|
|
255
267
|
|
|
256
268
|
const db = this.context.drizzle();
|
|
@@ -261,11 +273,27 @@ export class ArchetypeService {
|
|
|
261
273
|
and(
|
|
262
274
|
eq(schema.archetypesData.combination, combinationString),
|
|
263
275
|
eq(schema.archetypesData.gender, gender),
|
|
264
|
-
eq(schema.archetypesData.language,
|
|
276
|
+
eq(schema.archetypesData.language, language)
|
|
265
277
|
)
|
|
266
278
|
)
|
|
267
279
|
.execute();
|
|
268
280
|
|
|
281
|
+
if (
|
|
282
|
+
!override &&
|
|
283
|
+
archetypes.every((a) => a.description && a.virtues !== '[]')
|
|
284
|
+
) {
|
|
285
|
+
await this.log('info', 'Skipping descriptions and virtues generation', {
|
|
286
|
+
reason: 'Descriptions and virtues already exist for all archetypes',
|
|
287
|
+
});
|
|
288
|
+
return archetypes.map((a) => ({
|
|
289
|
+
descriptionEN: a.description || '',
|
|
290
|
+
descriptionPTM: a.description || '',
|
|
291
|
+
descriptionPTF: a.description || '',
|
|
292
|
+
virtuesEN: JSON.parse(a.virtues || '[]'),
|
|
293
|
+
virtuesPT: JSON.parse(a.virtues || '[]'),
|
|
294
|
+
}));
|
|
295
|
+
}
|
|
296
|
+
|
|
269
297
|
await this.log('info', 'Fetched archetypes for description generation', {
|
|
270
298
|
archetypesCount: archetypes.length,
|
|
271
299
|
names: archetypes.map((a) => a.name),
|
|
@@ -289,9 +317,7 @@ export class ArchetypeService {
|
|
|
289
317
|
const descVirtueResponse = await this.context
|
|
290
318
|
.api()
|
|
291
319
|
.callTogether.single(descVirtueMessages, {
|
|
292
|
-
options: {
|
|
293
|
-
temperature: 0.5,
|
|
294
|
-
},
|
|
320
|
+
options: { temperature: 0.5 },
|
|
295
321
|
});
|
|
296
322
|
if (!descVirtueResponse) {
|
|
297
323
|
await this.log('error', 'No response for descriptions and virtues', {
|
|
@@ -313,87 +339,107 @@ export class ArchetypeService {
|
|
|
313
339
|
|
|
314
340
|
for (let i = 0; i < 3; i++) {
|
|
315
341
|
const index = (i + 1).toString();
|
|
316
|
-
|
|
317
|
-
// Update English entry (en-us)
|
|
318
342
|
const enId = `${combinationString}:${gender}:${index}`;
|
|
319
|
-
|
|
320
|
-
description: parsedDescVirtues[i].descriptionEN,
|
|
321
|
-
virtues: parsedDescVirtues[i].virtuesEN,
|
|
322
|
-
});
|
|
323
|
-
await db
|
|
324
|
-
.update(schema.archetypesData)
|
|
325
|
-
.set({
|
|
326
|
-
description: parsedDescVirtues[i].descriptionEN,
|
|
327
|
-
virtues: JSON.stringify(parsedDescVirtues[i].virtuesEN),
|
|
328
|
-
updatedAt: new Date().getTime(),
|
|
329
|
-
})
|
|
330
|
-
.where(
|
|
331
|
-
and(
|
|
332
|
-
eq(schema.archetypesData.id, enId),
|
|
333
|
-
eq(schema.archetypesData.language, 'en-us')
|
|
334
|
-
)
|
|
335
|
-
)
|
|
336
|
-
.execute();
|
|
337
|
-
await this.log('info', `Updated description and virtues for ${enId}`);
|
|
343
|
+
const ptId = `${combinationString}:${gender}:${index}:pt`;
|
|
338
344
|
|
|
339
|
-
// Update
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
345
|
+
// Update English entry (en-us)
|
|
346
|
+
if (language === 'en-us') {
|
|
347
|
+
const enExisting = archetypes.find((a) => a.id === enId);
|
|
348
|
+
if (
|
|
349
|
+
!override &&
|
|
350
|
+
enExisting?.description &&
|
|
351
|
+
enExisting.virtues !== '[]'
|
|
352
|
+
) {
|
|
353
|
+
await this.log(
|
|
354
|
+
'debug',
|
|
355
|
+
`Skipping existing description and virtues for ${enId}`,
|
|
356
|
+
{
|
|
357
|
+
description: enExisting.description,
|
|
358
|
+
virtues: enExisting.virtues,
|
|
359
|
+
}
|
|
360
|
+
);
|
|
361
|
+
} else {
|
|
362
|
+
await this.log(
|
|
363
|
+
'debug',
|
|
364
|
+
`Updating description and virtues for ${enId}`,
|
|
365
|
+
{
|
|
366
|
+
description: parsedDescVirtues[i].descriptionEN,
|
|
367
|
+
virtues: parsedDescVirtues[i].virtuesEN,
|
|
368
|
+
}
|
|
369
|
+
);
|
|
370
|
+
await db
|
|
371
|
+
.update(schema.archetypesData)
|
|
372
|
+
.set({
|
|
373
|
+
description: parsedDescVirtues[i].descriptionEN,
|
|
374
|
+
virtues: JSON.stringify(parsedDescVirtues[i].virtuesEN),
|
|
375
|
+
updatedAt: new Date().getTime(),
|
|
376
|
+
})
|
|
377
|
+
.where(
|
|
378
|
+
and(
|
|
379
|
+
eq(schema.archetypesData.id, enId),
|
|
380
|
+
eq(schema.archetypesData.language, 'en-us')
|
|
381
|
+
)
|
|
382
|
+
)
|
|
383
|
+
.execute();
|
|
384
|
+
await this.log('info', `Updated description and virtues for ${enId}`);
|
|
347
385
|
}
|
|
348
|
-
|
|
349
|
-
await db
|
|
350
|
-
.update(schema.archetypesData)
|
|
351
|
-
.set({
|
|
352
|
-
description: parsedDescVirtues[i].descriptionPTM,
|
|
353
|
-
virtues: JSON.stringify(parsedDescVirtues[i].virtuesPT),
|
|
354
|
-
updatedAt: new Date().getTime(),
|
|
355
|
-
})
|
|
356
|
-
.where(
|
|
357
|
-
and(
|
|
358
|
-
eq(schema.archetypesData.id, ptIdMale),
|
|
359
|
-
eq(schema.archetypesData.language, 'pt-br'),
|
|
360
|
-
eq(schema.archetypesData.gender, 'male')
|
|
361
|
-
)
|
|
362
|
-
)
|
|
363
|
-
.execute();
|
|
364
|
-
await this.log(
|
|
365
|
-
'info',
|
|
366
|
-
`Updated description and virtues for ${ptIdMale} (male)`
|
|
367
|
-
);
|
|
386
|
+
}
|
|
368
387
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
'
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
388
|
+
// Update Portuguese entries (pt-br)
|
|
389
|
+
if (language === 'pt-br') {
|
|
390
|
+
for (const ptGender of ['male', 'female']) {
|
|
391
|
+
const ptExisting = archetypes.find(
|
|
392
|
+
(a) => a.id === ptId && a.gender === ptGender
|
|
393
|
+
);
|
|
394
|
+
if (
|
|
395
|
+
!override &&
|
|
396
|
+
ptExisting?.description &&
|
|
397
|
+
ptExisting.virtues !== '[]'
|
|
398
|
+
) {
|
|
399
|
+
await this.log(
|
|
400
|
+
'debug',
|
|
401
|
+
`Skipping existing description and virtues for ${ptId} (${ptGender})`,
|
|
402
|
+
{
|
|
403
|
+
description: ptExisting.description,
|
|
404
|
+
virtues: ptExisting.virtues,
|
|
405
|
+
}
|
|
406
|
+
);
|
|
407
|
+
continue;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
const description =
|
|
411
|
+
ptGender === 'male'
|
|
412
|
+
? parsedDescVirtues[i].descriptionPTM
|
|
413
|
+
: parsedDescVirtues[i].descriptionPTF;
|
|
414
|
+
await this.log(
|
|
415
|
+
'debug',
|
|
416
|
+
`Updating description and virtues for ${ptId} (${ptGender})`,
|
|
417
|
+
{
|
|
418
|
+
description,
|
|
419
|
+
virtues: parsedDescVirtues[i].virtuesPT,
|
|
420
|
+
}
|
|
421
|
+
);
|
|
422
|
+
await db
|
|
423
|
+
.update(schema.archetypesData)
|
|
424
|
+
.set({
|
|
425
|
+
description,
|
|
426
|
+
virtues: JSON.stringify(parsedDescVirtues[i].virtuesPT),
|
|
427
|
+
updatedAt: new Date().getTime(),
|
|
428
|
+
})
|
|
429
|
+
.where(
|
|
430
|
+
and(
|
|
431
|
+
eq(schema.archetypesData.id, ptId),
|
|
432
|
+
eq(schema.archetypesData.language, 'pt-br'),
|
|
433
|
+
eq(schema.archetypesData.gender, ptGender)
|
|
434
|
+
)
|
|
435
|
+
)
|
|
436
|
+
.execute();
|
|
437
|
+
await this.log(
|
|
438
|
+
'info',
|
|
439
|
+
`Updated description and virtues for ${ptId} (${ptGender})`
|
|
440
|
+
);
|
|
376
441
|
}
|
|
377
|
-
|
|
378
|
-
await db
|
|
379
|
-
.update(schema.archetypesData)
|
|
380
|
-
.set({
|
|
381
|
-
description: parsedDescVirtues[i].descriptionPTF,
|
|
382
|
-
virtues: JSON.stringify(parsedDescVirtues[i].virtuesPT),
|
|
383
|
-
updatedAt: new Date().getTime(),
|
|
384
|
-
})
|
|
385
|
-
.where(
|
|
386
|
-
and(
|
|
387
|
-
eq(schema.archetypesData.id, ptIdFemale),
|
|
388
|
-
eq(schema.archetypesData.language, 'pt-br'),
|
|
389
|
-
eq(schema.archetypesData.gender, 'female')
|
|
390
|
-
)
|
|
391
|
-
)
|
|
392
|
-
.execute();
|
|
393
|
-
await this.log(
|
|
394
|
-
'info',
|
|
395
|
-
`Updated description and virtues for ${ptIdFemale} (female)`
|
|
396
|
-
);
|
|
442
|
+
}
|
|
397
443
|
}
|
|
398
444
|
|
|
399
445
|
await this.log('info', 'Completed generateDescriptionsAndVirtues', {
|
|
@@ -451,8 +497,6 @@ export class ArchetypeService {
|
|
|
451
497
|
|
|
452
498
|
for (let i = 0; i < lines.length; i++) {
|
|
453
499
|
let line = lines[i];
|
|
454
|
-
|
|
455
|
-
// Remove markdown bold (**...**) from field names
|
|
456
500
|
line = line.replace(/\*\*(.*?)\*\*/g, '$1');
|
|
457
501
|
|
|
458
502
|
if (
|
|
@@ -460,7 +504,7 @@ export class ArchetypeService {
|
|
|
460
504
|
line.startsWith('2.') ||
|
|
461
505
|
line.startsWith('3.')
|
|
462
506
|
) {
|
|
463
|
-
continue;
|
|
507
|
+
continue;
|
|
464
508
|
}
|
|
465
509
|
|
|
466
510
|
if (line.startsWith('• Description EN:')) {
|
|
@@ -510,7 +554,6 @@ export class ArchetypeService {
|
|
|
510
554
|
virtuesPT,
|
|
511
555
|
});
|
|
512
556
|
} else if (line.startsWith('• Virtues:')) {
|
|
513
|
-
// Fallback for older response format: use English virtues and attempt to translate
|
|
514
557
|
currentField = 'virtuesEN';
|
|
515
558
|
virtuesEN = line
|
|
516
559
|
.split('• Virtues:')[1]
|
|
@@ -524,14 +567,12 @@ export class ArchetypeService {
|
|
|
524
567
|
{ virtuesEN }
|
|
525
568
|
);
|
|
526
569
|
|
|
527
|
-
// Simple translation mapping for common virtues (as a fallback)
|
|
528
570
|
const virtueTranslations: { [key: string]: string } = {
|
|
529
571
|
Harmony: 'Harmonia',
|
|
530
572
|
Intuition: 'Intuição',
|
|
531
573
|
Grace: 'Graça',
|
|
532
|
-
// Add more translations as needed
|
|
533
574
|
};
|
|
534
|
-
virtuesPT = virtuesEN.map((v) => virtueTranslations[v] || v);
|
|
575
|
+
virtuesPT = virtuesEN.map((v) => virtueTranslations[v] || v);
|
|
535
576
|
this.log(
|
|
536
577
|
'debug',
|
|
537
578
|
`Generated virtuesPT (fallback) for entry ${entryIndex + 1}`,
|
|
@@ -563,7 +604,6 @@ export class ArchetypeService {
|
|
|
563
604
|
}
|
|
564
605
|
}
|
|
565
606
|
|
|
566
|
-
// Validate the parsed data
|
|
567
607
|
if (
|
|
568
608
|
!descriptionEN ||
|
|
569
609
|
!descriptionPTM ||
|
|
@@ -611,12 +651,14 @@ export class ArchetypeService {
|
|
|
611
651
|
combinationString: string,
|
|
612
652
|
gender: Gender,
|
|
613
653
|
language: string,
|
|
614
|
-
descriptions: Array<{ descriptionEN: string }
|
|
654
|
+
descriptions: Array<{ descriptionEN: string }>,
|
|
655
|
+
override: boolean = false
|
|
615
656
|
) {
|
|
616
657
|
await this.log('info', 'Starting generateContent', {
|
|
617
658
|
combinationString,
|
|
618
659
|
gender,
|
|
619
660
|
language,
|
|
661
|
+
override,
|
|
620
662
|
});
|
|
621
663
|
|
|
622
664
|
const db = this.context.drizzle();
|
|
@@ -627,11 +669,18 @@ export class ArchetypeService {
|
|
|
627
669
|
and(
|
|
628
670
|
eq(schema.archetypesData.combination, combinationString),
|
|
629
671
|
eq(schema.archetypesData.gender, gender),
|
|
630
|
-
eq(schema.archetypesData.language,
|
|
672
|
+
eq(schema.archetypesData.language, language)
|
|
631
673
|
)
|
|
632
674
|
)
|
|
633
675
|
.execute();
|
|
634
676
|
|
|
677
|
+
if (!override && archetypes.every((a) => a.content !== '[]')) {
|
|
678
|
+
await this.log('info', 'Skipping content generation', {
|
|
679
|
+
reason: 'Content already exists for all archetypes',
|
|
680
|
+
});
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
|
|
635
684
|
await this.log('info', 'Fetched archetypes for content generation', {
|
|
636
685
|
archetypesCount: archetypes.length,
|
|
637
686
|
names: archetypes.map((a) => a.name),
|
|
@@ -639,6 +688,20 @@ export class ArchetypeService {
|
|
|
639
688
|
|
|
640
689
|
const contentResults = [];
|
|
641
690
|
for (let i = 0; i < 3; i++) {
|
|
691
|
+
const index = (i + 1).toString();
|
|
692
|
+
const id = `${combinationString}:${gender}:${index}${
|
|
693
|
+
language === 'pt-br' ? ':pt' : ''
|
|
694
|
+
}`;
|
|
695
|
+
const existing = archetypes.find((a) => a.id === id);
|
|
696
|
+
|
|
697
|
+
if (!override && existing && existing?.content !== '[]') {
|
|
698
|
+
await this.log('debug', `Skipping existing content for ${id}`, {
|
|
699
|
+
content: existing.content,
|
|
700
|
+
});
|
|
701
|
+
contentResults.push({}); // Placeholder
|
|
702
|
+
continue;
|
|
703
|
+
}
|
|
704
|
+
|
|
642
705
|
await this.log('debug', `Generating content for archetype ${i + 1}`, {
|
|
643
706
|
name: archetypes[i].name,
|
|
644
707
|
});
|
|
@@ -660,7 +723,10 @@ export class ArchetypeService {
|
|
|
660
723
|
await this.log(
|
|
661
724
|
'error',
|
|
662
725
|
`No response for content of archetype ${i + 1}`,
|
|
663
|
-
{
|
|
726
|
+
{
|
|
727
|
+
combinationString,
|
|
728
|
+
archetype: archetypes[i].name,
|
|
729
|
+
}
|
|
664
730
|
);
|
|
665
731
|
throw new Error(
|
|
666
732
|
`Failed to generate content for archetype ${
|
|
@@ -671,7 +737,9 @@ export class ArchetypeService {
|
|
|
671
737
|
await this.log(
|
|
672
738
|
'info',
|
|
673
739
|
`Received content response for archetype ${i + 1}`,
|
|
674
|
-
{
|
|
740
|
+
{
|
|
741
|
+
responseLength: contentResponse.length,
|
|
742
|
+
}
|
|
675
743
|
);
|
|
676
744
|
|
|
677
745
|
await this.log(
|
|
@@ -684,58 +752,52 @@ export class ArchetypeService {
|
|
|
684
752
|
parsedContent,
|
|
685
753
|
});
|
|
686
754
|
|
|
687
|
-
const
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
},
|
|
716
|
-
];
|
|
755
|
+
const contentLangIndex =
|
|
756
|
+
language === 'en-us' ? 0 : gender === 'male' ? 1 : 2;
|
|
757
|
+
const content = [
|
|
758
|
+
{
|
|
759
|
+
section: 'voiceOfTheSoul',
|
|
760
|
+
text: parsedContent[contentLangIndex].voiceOfTheSoul,
|
|
761
|
+
},
|
|
762
|
+
{
|
|
763
|
+
section: 'giftsYouBear',
|
|
764
|
+
text: parsedContent[contentLangIndex].giftsYouBear,
|
|
765
|
+
},
|
|
766
|
+
{
|
|
767
|
+
section: 'shadowsYouFace',
|
|
768
|
+
text: parsedContent[contentLangIndex].shadowsYouFace,
|
|
769
|
+
},
|
|
770
|
+
{
|
|
771
|
+
section: 'rhythmOfYourDays',
|
|
772
|
+
text: parsedContent[contentLangIndex].rhythmOfYourDays,
|
|
773
|
+
},
|
|
774
|
+
{
|
|
775
|
+
section: 'tiesThatBind',
|
|
776
|
+
text: parsedContent[contentLangIndex].tiesThatBind,
|
|
777
|
+
},
|
|
778
|
+
{
|
|
779
|
+
section: 'lightWithin',
|
|
780
|
+
text: parsedContent[contentLangIndex].lightWithin,
|
|
781
|
+
},
|
|
782
|
+
];
|
|
717
783
|
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
.
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
and(
|
|
731
|
-
eq(schema.archetypesData.id, id),
|
|
732
|
-
eq(schema.archetypesData.language, lang)
|
|
733
|
-
)
|
|
784
|
+
await this.log('debug', `Updating content for ${id}`, { content });
|
|
785
|
+
|
|
786
|
+
await db
|
|
787
|
+
.update(schema.archetypesData)
|
|
788
|
+
.set({
|
|
789
|
+
content: JSON.stringify(content),
|
|
790
|
+
updatedAt: new Date().getTime(),
|
|
791
|
+
})
|
|
792
|
+
.where(
|
|
793
|
+
and(
|
|
794
|
+
eq(schema.archetypesData.id, id),
|
|
795
|
+
eq(schema.archetypesData.language, language)
|
|
734
796
|
)
|
|
735
|
-
|
|
797
|
+
)
|
|
798
|
+
.execute();
|
|
736
799
|
|
|
737
|
-
|
|
738
|
-
}
|
|
800
|
+
await this.log('info', `Updated content for ${id}`);
|
|
739
801
|
}
|
|
740
802
|
|
|
741
803
|
await this.log('info', 'Completed generateContent', {
|
|
@@ -798,7 +860,10 @@ export class ArchetypeService {
|
|
|
798
860
|
`Extracted section ${currentSection} in section ${
|
|
799
861
|
sectionIndex + 1
|
|
800
862
|
}`,
|
|
801
|
-
{
|
|
863
|
+
{
|
|
864
|
+
key,
|
|
865
|
+
text: content[key],
|
|
866
|
+
}
|
|
802
867
|
);
|
|
803
868
|
}
|
|
804
869
|
currentSection = line.replace('# ', '');
|
|
@@ -825,7 +890,10 @@ export class ArchetypeService {
|
|
|
825
890
|
`Extracted final section ${currentSection} in section ${
|
|
826
891
|
sectionIndex + 1
|
|
827
892
|
}`,
|
|
828
|
-
{
|
|
893
|
+
{
|
|
894
|
+
key,
|
|
895
|
+
text: content[key],
|
|
896
|
+
}
|
|
829
897
|
);
|
|
830
898
|
}
|
|
831
899
|
|
|
@@ -863,26 +931,22 @@ export class ArchetypeService {
|
|
|
863
931
|
|
|
864
932
|
async generateLeonardoPrompts(
|
|
865
933
|
combinationString: string,
|
|
866
|
-
gender: Gender,
|
|
867
|
-
language: string,
|
|
868
|
-
descriptions: Array<{ descriptionEN: string }
|
|
934
|
+
gender: Gender,
|
|
935
|
+
language: string,
|
|
936
|
+
descriptions: Array<{ descriptionEN: string }>,
|
|
937
|
+
override: boolean = false
|
|
869
938
|
) {
|
|
870
939
|
await this.log('info', 'Starting generateLeonardoPrompts', {
|
|
871
940
|
combinationString,
|
|
872
941
|
gender,
|
|
873
942
|
language,
|
|
943
|
+
override,
|
|
874
944
|
});
|
|
875
945
|
|
|
876
946
|
const db = this.context.drizzle();
|
|
877
|
-
|
|
878
947
|
type Binary = 'male' | 'female';
|
|
879
|
-
|
|
880
|
-
// Fetch archetypes for male and female with language = 'en-us'
|
|
881
948
|
const allGenders: Binary[] = ['male', 'female'];
|
|
882
|
-
const archetypesByGender: Record<Binary, any[]> = {
|
|
883
|
-
male: [],
|
|
884
|
-
female: [],
|
|
885
|
-
};
|
|
949
|
+
const archetypesByGender: Record<Binary, any[]> = { male: [], female: [] };
|
|
886
950
|
|
|
887
951
|
for (const g of allGenders) {
|
|
888
952
|
const archetypes = await db
|
|
@@ -892,14 +956,13 @@ export class ArchetypeService {
|
|
|
892
956
|
and(
|
|
893
957
|
eq(schema.archetypesData.combination, combinationString),
|
|
894
958
|
eq(schema.archetypesData.gender, g),
|
|
895
|
-
eq(schema.archetypesData.language,
|
|
959
|
+
eq(schema.archetypesData.language, language)
|
|
896
960
|
)
|
|
897
961
|
)
|
|
898
962
|
.execute();
|
|
899
963
|
archetypesByGender[g] = archetypes;
|
|
900
964
|
}
|
|
901
965
|
|
|
902
|
-
// Validate that we have archetypes for all genders (3 archetypes per gender)
|
|
903
966
|
for (const g of allGenders) {
|
|
904
967
|
if (archetypesByGender[g].length !== 3) {
|
|
905
968
|
await this.log(
|
|
@@ -916,6 +979,16 @@ export class ArchetypeService {
|
|
|
916
979
|
}
|
|
917
980
|
}
|
|
918
981
|
|
|
982
|
+
if (
|
|
983
|
+
!override &&
|
|
984
|
+
archetypesByGender[gender as Binary].every((a) => a.leonardoPrompt)
|
|
985
|
+
) {
|
|
986
|
+
await this.log('info', 'Skipping Leonardo prompts generation', {
|
|
987
|
+
reason: 'Leonardo prompts already exist for all archetypes',
|
|
988
|
+
});
|
|
989
|
+
return;
|
|
990
|
+
}
|
|
991
|
+
|
|
919
992
|
await this.log('info', 'Fetched archetypes for Leonardo prompts', {
|
|
920
993
|
maleArchetypesCount: archetypesByGender['male'].length,
|
|
921
994
|
femaleArchetypesCount: archetypesByGender['female'].length,
|
|
@@ -925,8 +998,6 @@ export class ArchetypeService {
|
|
|
925
998
|
},
|
|
926
999
|
});
|
|
927
1000
|
|
|
928
|
-
// Since descriptions are provided as an input (from generateDescriptionsAndVirtues),
|
|
929
|
-
// we can use the same descriptions for all genders, as they are gender-neutral (en-us)
|
|
930
1001
|
const promptMessages = this.context
|
|
931
1002
|
.buildLLMMessages()
|
|
932
1003
|
.generateCosmicMirrorArchetypeLeonardoPrompts(
|
|
@@ -957,7 +1028,6 @@ export class ArchetypeService {
|
|
|
957
1028
|
const parsedPrompts = this.parseLeonardoPromptResponse(promptResponse);
|
|
958
1029
|
await this.log('info', 'Parsed Leonardo prompts', { parsedPrompts });
|
|
959
1030
|
|
|
960
|
-
// Update archetypes for all genders
|
|
961
1031
|
for (const g of allGenders) {
|
|
962
1032
|
for (let i = 0; i < 3; i++) {
|
|
963
1033
|
const index = (i + 1).toString();
|
|
@@ -966,105 +1036,39 @@ export class ArchetypeService {
|
|
|
966
1036
|
? parsedPrompts[i].malePrompt
|
|
967
1037
|
: parsedPrompts[i].femalePrompt;
|
|
968
1038
|
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
{
|
|
975
|
-
leonardoPrompt,
|
|
976
|
-
}
|
|
977
|
-
);
|
|
978
|
-
|
|
979
|
-
const enUpdateResult = await db
|
|
980
|
-
.update(schema.archetypesData)
|
|
981
|
-
.set({
|
|
982
|
-
leonardoPrompt,
|
|
983
|
-
updatedAt: new Date().getTime(),
|
|
984
|
-
})
|
|
985
|
-
.where(
|
|
986
|
-
and(
|
|
987
|
-
eq(schema.archetypesData.id, enId),
|
|
988
|
-
eq(schema.archetypesData.language, 'en-us'),
|
|
989
|
-
eq(schema.archetypesData.gender, g)
|
|
990
|
-
)
|
|
991
|
-
)
|
|
992
|
-
.execute();
|
|
993
|
-
|
|
994
|
-
await this.log('info', `Updated Leonardo prompt for ${enId} (en-us)`, {
|
|
995
|
-
rowsAffected: enUpdateResult.rowsAffected,
|
|
996
|
-
});
|
|
997
|
-
|
|
998
|
-
if (enUpdateResult.rowsAffected === 0) {
|
|
999
|
-
await this.log(
|
|
1000
|
-
'error',
|
|
1001
|
-
`Failed to update Leonardo prompt for ${enId} (en-us)`,
|
|
1002
|
-
{
|
|
1003
|
-
enId,
|
|
1004
|
-
language: 'en-us',
|
|
1005
|
-
gender: g,
|
|
1006
|
-
}
|
|
1007
|
-
);
|
|
1008
|
-
throw new Error(
|
|
1009
|
-
`Failed to update Leonardo prompt for ${enId} (en-us)`
|
|
1010
|
-
);
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
// Update Portuguese entries (pt-br) for male and female
|
|
1014
|
-
const ptId = `${combinationString}:${g}:${index}:pt`;
|
|
1015
|
-
const ptGenders = ['male', 'female'];
|
|
1016
|
-
|
|
1017
|
-
for (const ptGender of ptGenders) {
|
|
1018
|
-
const ptLeonardoPrompt =
|
|
1019
|
-
ptGender === 'male'
|
|
1020
|
-
? parsedPrompts[i].malePrompt
|
|
1021
|
-
: parsedPrompts[i].femalePrompt;
|
|
1022
|
-
|
|
1039
|
+
const id = `${combinationString}:${g}:${index}${
|
|
1040
|
+
language === 'pt-br' ? ':pt' : ''
|
|
1041
|
+
}`;
|
|
1042
|
+
const existing = archetypesByGender[g].find((a) => a.id === id);
|
|
1043
|
+
if (!override && existing?.leonardoPrompt) {
|
|
1023
1044
|
await this.log(
|
|
1024
1045
|
'debug',
|
|
1025
|
-
`
|
|
1046
|
+
`Skipping existing Leonardo prompt for ${id}`,
|
|
1026
1047
|
{
|
|
1027
|
-
leonardoPrompt:
|
|
1048
|
+
leonardoPrompt: existing.leonardoPrompt,
|
|
1028
1049
|
}
|
|
1029
1050
|
);
|
|
1030
|
-
|
|
1031
|
-
|
|
1051
|
+
} else {
|
|
1052
|
+
await this.log('debug', `Updating Leonardo prompt for ${id}`, {
|
|
1053
|
+
leonardoPrompt,
|
|
1054
|
+
});
|
|
1055
|
+
const updateResult = await db
|
|
1032
1056
|
.update(schema.archetypesData)
|
|
1033
1057
|
.set({
|
|
1034
|
-
leonardoPrompt
|
|
1058
|
+
leonardoPrompt,
|
|
1035
1059
|
updatedAt: new Date().getTime(),
|
|
1036
1060
|
})
|
|
1037
1061
|
.where(
|
|
1038
1062
|
and(
|
|
1039
|
-
eq(schema.archetypesData.id,
|
|
1040
|
-
eq(schema.archetypesData.language,
|
|
1041
|
-
eq(schema.archetypesData.gender,
|
|
1063
|
+
eq(schema.archetypesData.id, id),
|
|
1064
|
+
eq(schema.archetypesData.language, language),
|
|
1065
|
+
eq(schema.archetypesData.gender, g)
|
|
1042
1066
|
)
|
|
1043
1067
|
)
|
|
1044
1068
|
.execute();
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
`Updated Leonardo prompt for ${ptId} (pt-br, gender: ${ptGender})`,
|
|
1049
|
-
{
|
|
1050
|
-
rowsAffected: ptUpdateResult.rowsAffected,
|
|
1051
|
-
}
|
|
1052
|
-
);
|
|
1053
|
-
|
|
1054
|
-
if (ptUpdateResult.rowsAffected === 0) {
|
|
1055
|
-
await this.log(
|
|
1056
|
-
'error',
|
|
1057
|
-
`Failed to update Leonardo prompt for ${ptId} (pt-br, gender: ${ptGender})`,
|
|
1058
|
-
{
|
|
1059
|
-
ptId,
|
|
1060
|
-
language: 'pt-br',
|
|
1061
|
-
gender: ptGender,
|
|
1062
|
-
}
|
|
1063
|
-
);
|
|
1064
|
-
throw new Error(
|
|
1065
|
-
`Failed to update Leonardo prompt for ${ptId} (pt-br, gender: ${ptGender})`
|
|
1066
|
-
);
|
|
1067
|
-
}
|
|
1069
|
+
await this.log('info', `Updated Leonardo prompt for ${id}`, {
|
|
1070
|
+
rowsAffected: updateResult.rowsAffected,
|
|
1071
|
+
});
|
|
1068
1072
|
}
|
|
1069
1073
|
}
|
|
1070
1074
|
}
|
|
@@ -1092,11 +1096,10 @@ export class ArchetypeService {
|
|
|
1092
1096
|
let currentArchetype = 0;
|
|
1093
1097
|
|
|
1094
1098
|
for (let i = 0; i < lines.length; i += 4) {
|
|
1095
|
-
|
|
1096
|
-
const
|
|
1097
|
-
const
|
|
1098
|
-
const
|
|
1099
|
-
const femalePromptLine = lines[i + 3]; // Female prompt text
|
|
1099
|
+
const maleLabel = lines[i];
|
|
1100
|
+
const malePromptLine = lines[i + 1];
|
|
1101
|
+
const femaleLabel = lines[i + 2];
|
|
1102
|
+
const femalePromptLine = lines[i + 3];
|
|
1100
1103
|
|
|
1101
1104
|
currentArchetype++;
|
|
1102
1105
|
const expectedMaleLabel = `${currentArchetype}.m`;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { and, eq
|
|
1
|
+
import { and, eq } from 'drizzle-orm';
|
|
2
2
|
import { inject, injectable } from 'inversify';
|
|
3
3
|
import { schema } from '../..';
|
|
4
4
|
import { Gender } from '../../types';
|
|
@@ -20,7 +20,7 @@ export class ArchetypeWorkflow {
|
|
|
20
20
|
context: Record<string, any> = {}
|
|
21
21
|
) {
|
|
22
22
|
const logId = `archetype-workflow:${Date.now()}`;
|
|
23
|
-
const logMessage = `[${level.toUpperCase()}] ${message}`;
|
|
23
|
+
const logMessage = `[${new Date().toISOString()}] [${level.toUpperCase()}] ${message}`;
|
|
24
24
|
|
|
25
25
|
console[level](logMessage, context);
|
|
26
26
|
const db = this.context.drizzle();
|
|
@@ -48,167 +48,228 @@ export class ArchetypeWorkflow {
|
|
|
48
48
|
async execute(
|
|
49
49
|
combinationString: string,
|
|
50
50
|
gender: Gender,
|
|
51
|
-
language: string = 'en-us'
|
|
51
|
+
language: string = 'en-us',
|
|
52
|
+
override: boolean = false
|
|
52
53
|
) {
|
|
53
54
|
await this.log('info', 'Starting ArchetypeWorkflow', {
|
|
54
55
|
combinationString,
|
|
55
56
|
gender,
|
|
56
57
|
language,
|
|
58
|
+
override,
|
|
57
59
|
});
|
|
58
|
-
|
|
59
|
-
// Step 1:
|
|
60
|
+
|
|
61
|
+
// Step 1: Fetch existing archetypes
|
|
60
62
|
let archetypes = await this.archetypeService.fetchArchetypesFromDB(
|
|
61
63
|
combinationString,
|
|
62
64
|
gender,
|
|
63
65
|
language
|
|
64
66
|
);
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
await this.log('info', 'Fetched existing archetypes', {
|
|
68
|
+
archetypesCount: archetypes.length,
|
|
69
|
+
archetypeIds: archetypes.map((a) => a.id),
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Step 2: Generate or update archetype names and essence lines
|
|
73
|
+
if (
|
|
74
|
+
override ||
|
|
75
|
+
archetypes.length === 0 ||
|
|
76
|
+
archetypes.some((a) => !a.name || !a.essenceLine)
|
|
77
|
+
) {
|
|
78
|
+
await this.log('info', 'Generating or updating archetype names', {
|
|
67
79
|
combinationString,
|
|
68
80
|
gender,
|
|
69
81
|
language,
|
|
82
|
+
override,
|
|
70
83
|
});
|
|
71
|
-
await this.archetypeService.generateArchetypeNames(
|
|
84
|
+
await this.archetypeService.generateArchetypeNames(
|
|
85
|
+
combinationString,
|
|
86
|
+
override
|
|
87
|
+
);
|
|
72
88
|
archetypes = await this.archetypeService.fetchArchetypesFromDB(
|
|
73
89
|
combinationString,
|
|
74
90
|
gender,
|
|
75
91
|
language
|
|
76
92
|
);
|
|
93
|
+
await this.log('info', 'Refetched archetypes after name generation', {
|
|
94
|
+
archetypesCount: archetypes.length,
|
|
95
|
+
archetypeIds: archetypes.map((a) => a.id),
|
|
96
|
+
});
|
|
97
|
+
} else {
|
|
98
|
+
await this.log('info', 'Skipping archetype names generation', {
|
|
99
|
+
reason: 'Names and essence lines already exist',
|
|
100
|
+
});
|
|
77
101
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
inArray(
|
|
97
|
-
schema.generations.archetypeDataId,
|
|
98
|
-
archetypes.map((a) => a.id)
|
|
99
|
-
)
|
|
100
|
-
)
|
|
101
|
-
)
|
|
102
|
-
.execute();
|
|
103
|
-
|
|
104
|
-
if (inProgressGenerations.length > 0) {
|
|
105
|
-
await this.log(
|
|
106
|
-
'warn',
|
|
107
|
-
`Images are already being processed for ${combinationString}, gender: ${gender}`,
|
|
108
|
-
{
|
|
109
|
-
inProgressGenerationsCount: inProgressGenerations.length,
|
|
110
|
-
generationIds: inProgressGenerations.map((g) => g.id),
|
|
111
|
-
}
|
|
102
|
+
|
|
103
|
+
// Step 3: Generate or update descriptions and virtues
|
|
104
|
+
let descVirtues: any[] = [];
|
|
105
|
+
if (
|
|
106
|
+
override ||
|
|
107
|
+
archetypes.some((a) => !a.description || a.virtues === '[]')
|
|
108
|
+
) {
|
|
109
|
+
await this.log('info', 'Generating or updating descriptions and virtues', {
|
|
110
|
+
combinationString,
|
|
111
|
+
gender,
|
|
112
|
+
language,
|
|
113
|
+
override,
|
|
114
|
+
});
|
|
115
|
+
descVirtues = await this.archetypeService.generateDescriptionsAndVirtues(
|
|
116
|
+
combinationString,
|
|
117
|
+
gender,
|
|
118
|
+
language,
|
|
119
|
+
override
|
|
112
120
|
);
|
|
113
|
-
|
|
121
|
+
archetypes = await this.archetypeService.fetchArchetypesFromDB(
|
|
122
|
+
combinationString,
|
|
123
|
+
gender,
|
|
124
|
+
language
|
|
125
|
+
);
|
|
126
|
+
await this.log('info', 'Refetched archetypes after descriptions and virtues', {
|
|
127
|
+
archetypesCount: archetypes.length,
|
|
128
|
+
archetypeIds: archetypes.map((a) => a.id),
|
|
129
|
+
});
|
|
130
|
+
} else {
|
|
131
|
+
await this.log('info', 'Skipping descriptions and virtues generation', {
|
|
132
|
+
reason: 'Descriptions and virtues already exist',
|
|
133
|
+
});
|
|
114
134
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
// Step 3: Generate missing textual content (description, virtues, content, leonardoPrompt)
|
|
121
|
-
const archetypesNeedingText = archetypes.filter(
|
|
122
|
-
(arc) =>
|
|
123
|
-
!arc.description ||
|
|
124
|
-
arc.virtues === '[]' ||
|
|
125
|
-
arc.content === '[]' ||
|
|
126
|
-
!arc.leonardoPrompt
|
|
127
|
-
);
|
|
128
|
-
|
|
129
|
-
if (archetypesNeedingText.length > 0) {
|
|
130
|
-
await this.log('info', 'Generating missing textual content', {
|
|
135
|
+
|
|
136
|
+
// Step 4: Generate or update content
|
|
137
|
+
if (override || archetypes.some((a) => a.content === '[]')) {
|
|
138
|
+
await this.log('info', 'Generating or updating content', {
|
|
131
139
|
combinationString,
|
|
132
140
|
gender,
|
|
133
141
|
language,
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
const descVirtues =
|
|
139
|
-
await this.archetypeService.generateDescriptionsAndVirtues(
|
|
140
|
-
combinationString,
|
|
141
|
-
gender,
|
|
142
|
-
language
|
|
143
|
-
);
|
|
142
|
+
override,
|
|
143
|
+
});
|
|
144
144
|
await this.archetypeService.generateContent(
|
|
145
145
|
combinationString,
|
|
146
146
|
gender,
|
|
147
147
|
language,
|
|
148
|
-
descVirtues
|
|
148
|
+
descVirtues,
|
|
149
|
+
override
|
|
149
150
|
);
|
|
150
|
-
await this.archetypeService.
|
|
151
|
+
archetypes = await this.archetypeService.fetchArchetypesFromDB(
|
|
151
152
|
combinationString,
|
|
152
153
|
gender,
|
|
153
|
-
language
|
|
154
|
-
descVirtues
|
|
154
|
+
language
|
|
155
155
|
);
|
|
156
|
+
await this.log('info', 'Refetched archetypes after content generation', {
|
|
157
|
+
archetypesCount: archetypes.length,
|
|
158
|
+
archetypeIds: archetypes.map((a) => a.id),
|
|
159
|
+
});
|
|
156
160
|
} else {
|
|
157
|
-
await this.log('info', '
|
|
161
|
+
await this.log('info', 'Skipping content generation', {
|
|
162
|
+
reason: 'Content already exists',
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Step 5: Generate or update Leonardo prompts
|
|
167
|
+
if (override || archetypes.some((a) => !a.leonardoPrompt)) {
|
|
168
|
+
await this.log('info', 'Generating or updating Leonardo prompts', {
|
|
158
169
|
combinationString,
|
|
159
170
|
gender,
|
|
160
171
|
language,
|
|
172
|
+
override,
|
|
173
|
+
});
|
|
174
|
+
await this.archetypeService.generateLeonardoPrompts(
|
|
175
|
+
combinationString,
|
|
176
|
+
gender,
|
|
177
|
+
language,
|
|
178
|
+
descVirtues,
|
|
179
|
+
override
|
|
180
|
+
);
|
|
181
|
+
archetypes = await this.archetypeService.fetchArchetypesFromDB(
|
|
182
|
+
combinationString,
|
|
183
|
+
gender,
|
|
184
|
+
language
|
|
185
|
+
);
|
|
186
|
+
await this.log('info', 'Refetched archetypes after Leonardo prompts', {
|
|
187
|
+
archetypesCount: archetypes.length,
|
|
188
|
+
archetypeIds: archetypes.map((a) => a.id),
|
|
189
|
+
});
|
|
190
|
+
} else {
|
|
191
|
+
await this.log('info', 'Skipping Leonardo prompts generation', {
|
|
192
|
+
reason: 'Leonardo prompts already exist',
|
|
161
193
|
});
|
|
162
194
|
}
|
|
163
|
-
|
|
164
|
-
//
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
gender,
|
|
168
|
-
language
|
|
169
|
-
);
|
|
170
|
-
await this.log('info', 'Refetched archetypes', {
|
|
171
|
-
updatedArchetypesCount: updatedArchetypes.length,
|
|
172
|
-
archetypeIds: updatedArchetypes.map((a) => a.id),
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
// Step 4: Queue image generation if needed
|
|
176
|
-
const archetypesNeedingImages = updatedArchetypes.filter(
|
|
177
|
-
(arc) => JSON.parse(arc.images).length < 3
|
|
195
|
+
|
|
196
|
+
// Step 6: Process image generation if needed
|
|
197
|
+
const archetypesNeedingImages = archetypes.filter(
|
|
198
|
+
(arc) => JSON.parse(arc.images).length < 3 || (override && arc.images !== '[]')
|
|
178
199
|
);
|
|
179
|
-
|
|
200
|
+
|
|
180
201
|
if (archetypesNeedingImages.length > 0) {
|
|
181
|
-
await this.log(
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
202
|
+
await this.log('info', 'Processing image generation for archetypes', {
|
|
203
|
+
archetypesNeedingImagesCount: archetypesNeedingImages.length,
|
|
204
|
+
archetypeIds: archetypesNeedingImages.map((a) => a.id),
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
for (const archetype of archetypesNeedingImages) {
|
|
208
|
+
await this.log('debug', 'Processing image generation', {
|
|
209
|
+
archetypeId: archetype.id,
|
|
210
|
+
leonardoPrompt: archetype.leonardoPrompt,
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
// Reset images and status if override is true
|
|
214
|
+
if (override) {
|
|
215
|
+
await this.context.drizzle()
|
|
216
|
+
.update(schema.archetypesData)
|
|
217
|
+
.set({
|
|
218
|
+
images: '[]',
|
|
219
|
+
status: 'idle',
|
|
220
|
+
updatedAt: new Date().getTime(),
|
|
221
|
+
})
|
|
222
|
+
.where(eq(schema.archetypesData.id, archetype.id))
|
|
223
|
+
.execute();
|
|
224
|
+
await this.log('info', 'Reset images and status for archetype', {
|
|
225
|
+
archetypeId: archetype.id,
|
|
226
|
+
});
|
|
187
227
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
228
|
+
|
|
229
|
+
// Process image generation directly
|
|
230
|
+
await this.leonardoService.processArchetypePopulation({
|
|
231
|
+
archetypeDataId: archetype.id,
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
// Note: processArchetypePopulation sets status to 'pending' in the generations table
|
|
235
|
+
// Update archetype status to 'pending' for consistency
|
|
236
|
+
await this.context.drizzle()
|
|
237
|
+
.update(schema.archetypesData)
|
|
238
|
+
.set({
|
|
239
|
+
status: 'pending',
|
|
240
|
+
updatedAt: new Date().getTime(),
|
|
241
|
+
})
|
|
242
|
+
.where(eq(schema.archetypesData.id, archetype.id))
|
|
243
|
+
.execute();
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
await this.log('info', 'Image generation processing initiated', {
|
|
247
|
+
archetypesProcessed: archetypesNeedingImages.length,
|
|
248
|
+
});
|
|
249
|
+
return {
|
|
250
|
+
message: 'Image generation has been queued. Please try again later.',
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Step 7: Verify all archetypes are complete
|
|
255
|
+
const incompleteArchetypes = archetypes.filter((a) => a.status !== 'generated');
|
|
256
|
+
if (incompleteArchetypes.length > 0) {
|
|
257
|
+
await this.log('warn', 'Some archetypes are not complete', {
|
|
258
|
+
incompleteArchetypeIds: incompleteArchetypes.map((a) => a.id),
|
|
259
|
+
statuses: incompleteArchetypes.map((a) => a.status),
|
|
260
|
+
});
|
|
261
|
+
return {
|
|
262
|
+
message: 'Archetype generation is still in progress. Please try again later.',
|
|
263
|
+
};
|
|
205
264
|
}
|
|
206
|
-
|
|
207
|
-
await this.log('info', '
|
|
208
|
-
|
|
265
|
+
|
|
266
|
+
await this.log('info', 'All archetypes are complete', {
|
|
267
|
+
archetypesCount: archetypes.length,
|
|
268
|
+
archetypeIds: archetypes.map((a) => a.id),
|
|
209
269
|
});
|
|
270
|
+
|
|
210
271
|
return {
|
|
211
|
-
archetypes:
|
|
272
|
+
archetypes: archetypes.map(
|
|
212
273
|
({ id, name, essenceLine, description, virtues, images }) => ({
|
|
213
274
|
id,
|
|
214
275
|
name,
|
|
@@ -220,4 +281,4 @@ export class ArchetypeWorkflow {
|
|
|
220
281
|
),
|
|
221
282
|
};
|
|
222
283
|
}
|
|
223
|
-
}
|
|
284
|
+
}
|