@zodic/shared 0.0.371 → 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/services/ConceptService.ts +65 -53
- 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`;
|