@zodic/shared 0.0.319 → 0.0.320
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 +348 -124
- package/package.json +1 -1
|
@@ -248,13 +248,13 @@ export class ArchetypeService {
|
|
|
248
248
|
combinationString: string,
|
|
249
249
|
gender: Gender,
|
|
250
250
|
language: string
|
|
251
|
-
) {
|
|
251
|
+
): Promise<ParsedDescriptionAndVirtues[]> {
|
|
252
252
|
await this.log('info', 'Starting generateDescriptionsAndVirtues', {
|
|
253
253
|
combinationString,
|
|
254
254
|
gender,
|
|
255
255
|
language,
|
|
256
256
|
});
|
|
257
|
-
|
|
257
|
+
|
|
258
258
|
const db = this.context.drizzle();
|
|
259
259
|
const archetypes = await db
|
|
260
260
|
.select()
|
|
@@ -267,12 +267,12 @@ export class ArchetypeService {
|
|
|
267
267
|
)
|
|
268
268
|
)
|
|
269
269
|
.execute();
|
|
270
|
-
|
|
270
|
+
|
|
271
271
|
await this.log('info', 'Fetched archetypes for description generation', {
|
|
272
272
|
archetypesCount: archetypes.length,
|
|
273
273
|
names: archetypes.map((a) => a.name),
|
|
274
274
|
});
|
|
275
|
-
|
|
275
|
+
|
|
276
276
|
const descVirtueMessages = this.context
|
|
277
277
|
.buildLLMMessages()
|
|
278
278
|
.generateCosmicMirrorDescriptionAndVirtues({
|
|
@@ -284,13 +284,17 @@ export class ArchetypeService {
|
|
|
284
284
|
archetypes[2].essenceLine,
|
|
285
285
|
],
|
|
286
286
|
});
|
|
287
|
-
|
|
287
|
+
|
|
288
288
|
await this.log('debug', 'Calling API for descriptions and virtues', {
|
|
289
289
|
messages: descVirtueMessages,
|
|
290
290
|
});
|
|
291
291
|
const descVirtueResponse = await this.context
|
|
292
292
|
.api()
|
|
293
|
-
.callTogether.single(descVirtueMessages, {
|
|
293
|
+
.callTogether.single(descVirtueMessages, {
|
|
294
|
+
options: {
|
|
295
|
+
temperature: 0.5,
|
|
296
|
+
},
|
|
297
|
+
});
|
|
294
298
|
if (!descVirtueResponse) {
|
|
295
299
|
await this.log('error', 'No response for descriptions and virtues', {
|
|
296
300
|
combinationString,
|
|
@@ -302,15 +306,16 @@ export class ArchetypeService {
|
|
|
302
306
|
await this.log('info', 'Received descriptions and virtues response', {
|
|
303
307
|
responseLength: descVirtueResponse.length,
|
|
304
308
|
});
|
|
305
|
-
|
|
306
|
-
const parsedDescVirtues =
|
|
309
|
+
|
|
310
|
+
const parsedDescVirtues =
|
|
311
|
+
this.parseDescriptionAndVirtuesResponse(descVirtueResponse);
|
|
307
312
|
await this.log('info', 'Parsed descriptions and virtues', {
|
|
308
313
|
parsedDescVirtues,
|
|
309
314
|
});
|
|
310
|
-
|
|
315
|
+
|
|
311
316
|
for (let i = 0; i < 3; i++) {
|
|
312
317
|
const index = (i + 1).toString();
|
|
313
|
-
|
|
318
|
+
|
|
314
319
|
// Update English entry (en-us)
|
|
315
320
|
const enId = `${combinationString}:${gender}:${index}`;
|
|
316
321
|
await this.log('debug', `Updating description and virtues for ${enId}`, {
|
|
@@ -332,13 +337,17 @@ export class ArchetypeService {
|
|
|
332
337
|
)
|
|
333
338
|
.execute();
|
|
334
339
|
await this.log('info', `Updated description and virtues for ${enId}`);
|
|
335
|
-
|
|
340
|
+
|
|
336
341
|
// Update Portuguese entries (pt-br) for both male and female
|
|
337
342
|
const ptIdMale = `${combinationString}:${gender}:${index}:pt`;
|
|
338
|
-
await this.log(
|
|
339
|
-
|
|
340
|
-
virtues
|
|
341
|
-
|
|
343
|
+
await this.log(
|
|
344
|
+
'debug',
|
|
345
|
+
`Updating description and virtues for ${ptIdMale} (male)`,
|
|
346
|
+
{
|
|
347
|
+
description: parsedDescVirtues[i].descriptionPTM,
|
|
348
|
+
virtues: parsedDescVirtues[i].virtuesPT,
|
|
349
|
+
}
|
|
350
|
+
);
|
|
342
351
|
await db
|
|
343
352
|
.update(schema.archetypesData)
|
|
344
353
|
.set({
|
|
@@ -354,13 +363,20 @@ export class ArchetypeService {
|
|
|
354
363
|
)
|
|
355
364
|
)
|
|
356
365
|
.execute();
|
|
357
|
-
await this.log(
|
|
358
|
-
|
|
366
|
+
await this.log(
|
|
367
|
+
'info',
|
|
368
|
+
`Updated description and virtues for ${ptIdMale} (male)`
|
|
369
|
+
);
|
|
370
|
+
|
|
359
371
|
const ptIdFemale = `${combinationString}:${gender}:${index}:pt`;
|
|
360
|
-
await this.log(
|
|
361
|
-
|
|
362
|
-
virtues
|
|
363
|
-
|
|
372
|
+
await this.log(
|
|
373
|
+
'debug',
|
|
374
|
+
`Updating description and virtues for ${ptIdFemale} (female)`,
|
|
375
|
+
{
|
|
376
|
+
description: parsedDescVirtues[i].descriptionPTF,
|
|
377
|
+
virtues: parsedDescVirtues[i].virtuesPT,
|
|
378
|
+
}
|
|
379
|
+
);
|
|
364
380
|
await db
|
|
365
381
|
.update(schema.archetypesData)
|
|
366
382
|
.set({
|
|
@@ -376,9 +392,12 @@ export class ArchetypeService {
|
|
|
376
392
|
)
|
|
377
393
|
)
|
|
378
394
|
.execute();
|
|
379
|
-
await this.log(
|
|
395
|
+
await this.log(
|
|
396
|
+
'info',
|
|
397
|
+
`Updated description and virtues for ${ptIdFemale} (female)`
|
|
398
|
+
);
|
|
380
399
|
}
|
|
381
|
-
|
|
400
|
+
|
|
382
401
|
await this.log('info', 'Completed generateDescriptionsAndVirtues', {
|
|
383
402
|
combinationString,
|
|
384
403
|
gender,
|
|
@@ -387,67 +406,89 @@ export class ArchetypeService {
|
|
|
387
406
|
return parsedDescVirtues;
|
|
388
407
|
}
|
|
389
408
|
|
|
390
|
-
|
|
391
|
-
|
|
409
|
+
private parseDescriptionAndVirtuesResponse(
|
|
410
|
+
response: string
|
|
411
|
+
): ParsedDescriptionAndVirtues[] {
|
|
392
412
|
this.log('debug', 'Starting parseDescriptionAndVirtuesResponse', {
|
|
393
413
|
responseLength: response.length,
|
|
394
414
|
});
|
|
395
|
-
|
|
415
|
+
|
|
396
416
|
const entries = response
|
|
397
417
|
.split(/---/)
|
|
398
418
|
.map((block) => block.trim())
|
|
399
419
|
.filter((block) => block.length > 0);
|
|
400
|
-
|
|
420
|
+
|
|
401
421
|
this.log('debug', 'Split response into entries', {
|
|
402
422
|
entriesCount: entries.length,
|
|
403
423
|
});
|
|
404
|
-
|
|
424
|
+
|
|
405
425
|
if (entries.length !== 3) {
|
|
406
426
|
this.log('error', 'Expected exactly 3 archetype entries', {
|
|
407
427
|
entriesCount: entries.length,
|
|
408
428
|
response,
|
|
409
429
|
});
|
|
410
|
-
throw new Error(
|
|
430
|
+
throw new Error(
|
|
431
|
+
`Expected exactly 3 archetype entries, but got ${entries.length}`
|
|
432
|
+
);
|
|
411
433
|
}
|
|
412
|
-
|
|
434
|
+
|
|
413
435
|
const result = entries.map((entry, entryIndex) => {
|
|
414
436
|
this.log('debug', `Processing entry ${entryIndex + 1}`, { entry });
|
|
415
|
-
|
|
416
|
-
const lines = entry
|
|
437
|
+
|
|
438
|
+
const lines = entry
|
|
439
|
+
.split('\n')
|
|
440
|
+
.map((line) => line.trim())
|
|
441
|
+
.filter((line) => line);
|
|
417
442
|
this.log('debug', `Split entry ${entryIndex + 1} into lines`, {
|
|
418
443
|
linesCount: lines.length,
|
|
419
444
|
lines,
|
|
420
445
|
});
|
|
421
|
-
|
|
446
|
+
|
|
422
447
|
let descriptionEN = '';
|
|
423
448
|
let descriptionPTM = '';
|
|
424
449
|
let descriptionPTF = '';
|
|
425
450
|
let virtuesEN: string[] = [];
|
|
426
451
|
let virtuesPT: string[] = [];
|
|
427
452
|
let currentField = '';
|
|
428
|
-
|
|
453
|
+
|
|
429
454
|
for (let i = 0; i < lines.length; i++) {
|
|
430
455
|
let line = lines[i];
|
|
431
|
-
|
|
456
|
+
|
|
432
457
|
// Remove markdown bold (**...**) from field names
|
|
433
458
|
line = line.replace(/\*\*(.*?)\*\*/g, '$1');
|
|
434
|
-
|
|
435
|
-
if (
|
|
459
|
+
|
|
460
|
+
if (
|
|
461
|
+
line.startsWith('1.') ||
|
|
462
|
+
line.startsWith('2.') ||
|
|
463
|
+
line.startsWith('3.')
|
|
464
|
+
) {
|
|
436
465
|
continue; // Skip entry number lines
|
|
437
466
|
}
|
|
438
|
-
|
|
467
|
+
|
|
439
468
|
if (line.startsWith('• Description EN:')) {
|
|
440
469
|
currentField = 'descriptionEN';
|
|
441
470
|
descriptionEN = line.split('• Description EN:')[1]?.trim() || '';
|
|
442
|
-
this.log(
|
|
471
|
+
this.log(
|
|
472
|
+
'debug',
|
|
473
|
+
`Extracted descriptionEN for entry ${entryIndex + 1}`,
|
|
474
|
+
{ descriptionEN }
|
|
475
|
+
);
|
|
443
476
|
} else if (line.startsWith('• Description PT-M:')) {
|
|
444
477
|
currentField = 'descriptionPTM';
|
|
445
478
|
descriptionPTM = line.split('• Description PT-M:')[1]?.trim() || '';
|
|
446
|
-
this.log(
|
|
479
|
+
this.log(
|
|
480
|
+
'debug',
|
|
481
|
+
`Extracted descriptionPTM for entry ${entryIndex + 1}`,
|
|
482
|
+
{ descriptionPTM }
|
|
483
|
+
);
|
|
447
484
|
} else if (line.startsWith('• Description PT-F:')) {
|
|
448
485
|
currentField = 'descriptionPTF';
|
|
449
486
|
descriptionPTF = line.split('• Description PT-F:')[1]?.trim() || '';
|
|
450
|
-
this.log(
|
|
487
|
+
this.log(
|
|
488
|
+
'debug',
|
|
489
|
+
`Extracted descriptionPTF for entry ${entryIndex + 1}`,
|
|
490
|
+
{ descriptionPTF }
|
|
491
|
+
);
|
|
451
492
|
} else if (line.startsWith('• Virtues EN:')) {
|
|
452
493
|
currentField = 'virtuesEN';
|
|
453
494
|
virtuesEN = line
|
|
@@ -456,7 +497,9 @@ export class ArchetypeService {
|
|
|
456
497
|
.map((v) => v.trim())
|
|
457
498
|
.filter((v) => v)
|
|
458
499
|
.slice(0, 3);
|
|
459
|
-
this.log('debug', `Extracted virtuesEN for entry ${entryIndex + 1}`, {
|
|
500
|
+
this.log('debug', `Extracted virtuesEN for entry ${entryIndex + 1}`, {
|
|
501
|
+
virtuesEN,
|
|
502
|
+
});
|
|
460
503
|
} else if (line.startsWith('• Virtues PT:')) {
|
|
461
504
|
currentField = 'virtuesPT';
|
|
462
505
|
virtuesPT = line
|
|
@@ -465,7 +508,9 @@ export class ArchetypeService {
|
|
|
465
508
|
.map((v) => v.trim())
|
|
466
509
|
.filter((v) => v)
|
|
467
510
|
.slice(0, 3);
|
|
468
|
-
this.log('debug', `Extracted virtuesPT for entry ${entryIndex + 1}`, {
|
|
511
|
+
this.log('debug', `Extracted virtuesPT for entry ${entryIndex + 1}`, {
|
|
512
|
+
virtuesPT,
|
|
513
|
+
});
|
|
469
514
|
} else if (line.startsWith('• Virtues:')) {
|
|
470
515
|
// Fallback for older response format: use English virtues and attempt to translate
|
|
471
516
|
currentField = 'virtuesEN';
|
|
@@ -475,8 +520,12 @@ export class ArchetypeService {
|
|
|
475
520
|
.map((v) => v.trim())
|
|
476
521
|
.filter((v) => v)
|
|
477
522
|
.slice(0, 3);
|
|
478
|
-
this.log(
|
|
479
|
-
|
|
523
|
+
this.log(
|
|
524
|
+
'debug',
|
|
525
|
+
`Extracted virtuesEN (fallback) for entry ${entryIndex + 1}`,
|
|
526
|
+
{ virtuesEN }
|
|
527
|
+
);
|
|
528
|
+
|
|
480
529
|
// Simple translation mapping for common virtues (as a fallback)
|
|
481
530
|
const virtueTranslations: { [key: string]: string } = {
|
|
482
531
|
Harmony: 'Harmonia',
|
|
@@ -485,38 +534,78 @@ export class ArchetypeService {
|
|
|
485
534
|
// Add more translations as needed
|
|
486
535
|
};
|
|
487
536
|
virtuesPT = virtuesEN.map((v) => virtueTranslations[v] || v); // Fallback to English if no translation
|
|
488
|
-
this.log(
|
|
537
|
+
this.log(
|
|
538
|
+
'debug',
|
|
539
|
+
`Generated virtuesPT (fallback) for entry ${entryIndex + 1}`,
|
|
540
|
+
{ virtuesPT }
|
|
541
|
+
);
|
|
489
542
|
} else if (currentField && !currentField.startsWith('virtues')) {
|
|
490
543
|
if (currentField === 'descriptionEN') {
|
|
491
544
|
descriptionEN += ' ' + line;
|
|
492
|
-
this.log(
|
|
545
|
+
this.log(
|
|
546
|
+
'debug',
|
|
547
|
+
`Appended to descriptionEN for entry ${entryIndex + 1}`,
|
|
548
|
+
{ descriptionEN }
|
|
549
|
+
);
|
|
493
550
|
} else if (currentField === 'descriptionPTM') {
|
|
494
551
|
descriptionPTM += ' ' + line;
|
|
495
|
-
this.log(
|
|
552
|
+
this.log(
|
|
553
|
+
'debug',
|
|
554
|
+
`Appended to descriptionPTM for entry ${entryIndex + 1}`,
|
|
555
|
+
{ descriptionPTM }
|
|
556
|
+
);
|
|
496
557
|
} else if (currentField === 'descriptionPTF') {
|
|
497
558
|
descriptionPTF += ' ' + line;
|
|
498
|
-
this.log(
|
|
559
|
+
this.log(
|
|
560
|
+
'debug',
|
|
561
|
+
`Appended to descriptionPTF for entry ${entryIndex + 1}`,
|
|
562
|
+
{ descriptionPTF }
|
|
563
|
+
);
|
|
499
564
|
}
|
|
500
565
|
}
|
|
501
566
|
}
|
|
502
|
-
|
|
567
|
+
|
|
503
568
|
// Validate the parsed data
|
|
504
|
-
if (
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
569
|
+
if (
|
|
570
|
+
!descriptionEN ||
|
|
571
|
+
!descriptionPTM ||
|
|
572
|
+
!descriptionPTF ||
|
|
573
|
+
virtuesEN.length !== 3 ||
|
|
574
|
+
virtuesPT.length !== 3
|
|
575
|
+
) {
|
|
576
|
+
this.log(
|
|
577
|
+
'warn',
|
|
578
|
+
`Malformed description and virtues response for entry ${
|
|
579
|
+
entryIndex + 1
|
|
580
|
+
}`,
|
|
581
|
+
{
|
|
582
|
+
descriptionEN,
|
|
583
|
+
descriptionPTM,
|
|
584
|
+
descriptionPTF,
|
|
585
|
+
virtuesEN,
|
|
586
|
+
virtuesPT,
|
|
587
|
+
response: entry,
|
|
588
|
+
}
|
|
589
|
+
);
|
|
590
|
+
throw new Error(
|
|
591
|
+
`Malformed response for entry ${
|
|
592
|
+
entryIndex + 1
|
|
593
|
+
}: Missing required fields`
|
|
594
|
+
);
|
|
514
595
|
}
|
|
515
|
-
|
|
516
|
-
return {
|
|
596
|
+
|
|
597
|
+
return {
|
|
598
|
+
descriptionEN,
|
|
599
|
+
descriptionPTM,
|
|
600
|
+
descriptionPTF,
|
|
601
|
+
virtuesEN,
|
|
602
|
+
virtuesPT,
|
|
603
|
+
};
|
|
604
|
+
});
|
|
605
|
+
|
|
606
|
+
this.log('info', 'Completed parseDescriptionAndVirtuesResponse', {
|
|
607
|
+
result,
|
|
517
608
|
});
|
|
518
|
-
|
|
519
|
-
this.log('info', 'Completed parseDescriptionAndVirtuesResponse', { result });
|
|
520
609
|
return result;
|
|
521
610
|
}
|
|
522
611
|
|
|
@@ -776,8 +865,8 @@ export class ArchetypeService {
|
|
|
776
865
|
|
|
777
866
|
async generateLeonardoPrompts(
|
|
778
867
|
combinationString: string,
|
|
779
|
-
gender: Gender,
|
|
780
|
-
language: string,
|
|
868
|
+
gender: Gender, // User's gender, used for filtering results in ArchetypeWorkflow.execute
|
|
869
|
+
language: string, // User's language, used for filtering results in ArchetypeWorkflow.execute
|
|
781
870
|
descriptions: Array<{ descriptionEN: string }>
|
|
782
871
|
) {
|
|
783
872
|
await this.log('info', 'Starting generateLeonardoPrompts', {
|
|
@@ -787,27 +876,63 @@ export class ArchetypeService {
|
|
|
787
876
|
});
|
|
788
877
|
|
|
789
878
|
const db = this.context.drizzle();
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
879
|
+
|
|
880
|
+
type Binary = 'male' | 'female'
|
|
881
|
+
|
|
882
|
+
// Fetch archetypes for male and female with language = 'en-us'
|
|
883
|
+
const allGenders: Binary[] = ['male', 'female'];
|
|
884
|
+
const archetypesByGender: Record<Binary, any[]> = {
|
|
885
|
+
male: [],
|
|
886
|
+
female: [],
|
|
887
|
+
};
|
|
888
|
+
|
|
889
|
+
for (const g of allGenders) {
|
|
890
|
+
const archetypes = await db
|
|
891
|
+
.select()
|
|
892
|
+
.from(schema.archetypesData)
|
|
893
|
+
.where(
|
|
894
|
+
and(
|
|
895
|
+
eq(schema.archetypesData.combination, combinationString),
|
|
896
|
+
eq(schema.archetypesData.gender, g),
|
|
897
|
+
eq(schema.archetypesData.language, 'en-us')
|
|
898
|
+
)
|
|
798
899
|
)
|
|
799
|
-
|
|
800
|
-
|
|
900
|
+
.execute();
|
|
901
|
+
archetypesByGender[g] = archetypes;
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
// Validate that we have archetypes for all genders (3 archetypes per gender)
|
|
905
|
+
for (const g of allGenders) {
|
|
906
|
+
if (archetypesByGender[g].length !== 3) {
|
|
907
|
+
await this.log(
|
|
908
|
+
'error',
|
|
909
|
+
`Expected 3 archetypes for gender ${g}, but found ${archetypesByGender[g].length}`,
|
|
910
|
+
{
|
|
911
|
+
combinationString,
|
|
912
|
+
gender: g,
|
|
913
|
+
}
|
|
914
|
+
);
|
|
915
|
+
throw new Error(
|
|
916
|
+
`Expected 3 archetypes for gender ${g}, but found ${archetypesByGender[g].length}`
|
|
917
|
+
);
|
|
918
|
+
}
|
|
919
|
+
}
|
|
801
920
|
|
|
802
921
|
await this.log('info', 'Fetched archetypes for Leonardo prompts', {
|
|
803
|
-
|
|
804
|
-
|
|
922
|
+
maleArchetypesCount: archetypesByGender['male'].length,
|
|
923
|
+
femaleArchetypesCount: archetypesByGender['female'].length,
|
|
924
|
+
names: {
|
|
925
|
+
male: archetypesByGender['male'].map((a) => a.name),
|
|
926
|
+
female: archetypesByGender['female'].map((a) => a.name),
|
|
927
|
+
},
|
|
805
928
|
});
|
|
806
929
|
|
|
930
|
+
// Since descriptions are provided as an input (from generateDescriptionsAndVirtues),
|
|
931
|
+
// we can use the same descriptions for all genders, as they are gender-neutral (en-us)
|
|
807
932
|
const promptMessages = this.context
|
|
808
933
|
.buildLLMMessages()
|
|
809
934
|
.generateCosmicMirrorArchetypeLeonardoPrompts(
|
|
810
|
-
|
|
935
|
+
archetypesByGender['male'].map((arc, idx) => ({
|
|
811
936
|
name: arc.name,
|
|
812
937
|
description: descriptions[idx].descriptionEN,
|
|
813
938
|
}))
|
|
@@ -834,22 +959,26 @@ export class ArchetypeService {
|
|
|
834
959
|
const parsedPrompts = this.parseLeonardoPromptResponse(promptResponse);
|
|
835
960
|
await this.log('info', 'Parsed Leonardo prompts', { parsedPrompts });
|
|
836
961
|
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
}`;
|
|
848
|
-
await this.log(
|
|
849
|
-
|
|
850
|
-
|
|
962
|
+
// Update archetypes for all genders
|
|
963
|
+
for (const g of allGenders) {
|
|
964
|
+
for (let i = 0; i < 3; i++) {
|
|
965
|
+
const index = (i + 1).toString();
|
|
966
|
+
const leonardoPrompt =
|
|
967
|
+
g === 'male'
|
|
968
|
+
? parsedPrompts[i].malePrompt
|
|
969
|
+
: parsedPrompts[i].femalePrompt;
|
|
970
|
+
|
|
971
|
+
// Update English entry (en-us)
|
|
972
|
+
const enId = `${combinationString}:${g}:${index}`;
|
|
973
|
+
await this.log(
|
|
974
|
+
'debug',
|
|
975
|
+
`Updating Leonardo prompt for ${enId} (en-us)`,
|
|
976
|
+
{
|
|
977
|
+
leonardoPrompt,
|
|
978
|
+
}
|
|
979
|
+
);
|
|
851
980
|
|
|
852
|
-
await db
|
|
981
|
+
const enUpdateResult = await db
|
|
853
982
|
.update(schema.archetypesData)
|
|
854
983
|
.set({
|
|
855
984
|
leonardoPrompt,
|
|
@@ -857,13 +986,88 @@ export class ArchetypeService {
|
|
|
857
986
|
})
|
|
858
987
|
.where(
|
|
859
988
|
and(
|
|
860
|
-
eq(schema.archetypesData.id,
|
|
861
|
-
eq(schema.archetypesData.language,
|
|
989
|
+
eq(schema.archetypesData.id, enId),
|
|
990
|
+
eq(schema.archetypesData.language, 'en-us'),
|
|
991
|
+
eq(schema.archetypesData.gender, g)
|
|
862
992
|
)
|
|
863
993
|
)
|
|
864
994
|
.execute();
|
|
865
995
|
|
|
866
|
-
await this.log('info', `Updated Leonardo prompt for ${
|
|
996
|
+
await this.log('info', `Updated Leonardo prompt for ${enId} (en-us)`, {
|
|
997
|
+
rowsAffected: enUpdateResult.rowsAffected,
|
|
998
|
+
});
|
|
999
|
+
|
|
1000
|
+
if (enUpdateResult.rowsAffected === 0) {
|
|
1001
|
+
await this.log(
|
|
1002
|
+
'error',
|
|
1003
|
+
`Failed to update Leonardo prompt for ${enId} (en-us)`,
|
|
1004
|
+
{
|
|
1005
|
+
enId,
|
|
1006
|
+
language: 'en-us',
|
|
1007
|
+
gender: g,
|
|
1008
|
+
}
|
|
1009
|
+
);
|
|
1010
|
+
throw new Error(
|
|
1011
|
+
`Failed to update Leonardo prompt for ${enId} (en-us)`
|
|
1012
|
+
);
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
// Update Portuguese entries (pt-br) for male and female
|
|
1016
|
+
const ptId = `${combinationString}:${g}:${index}:pt`;
|
|
1017
|
+
const ptGenders = ['male', 'female'];
|
|
1018
|
+
|
|
1019
|
+
for (const ptGender of ptGenders) {
|
|
1020
|
+
const ptLeonardoPrompt =
|
|
1021
|
+
ptGender === 'male'
|
|
1022
|
+
? parsedPrompts[i].malePrompt
|
|
1023
|
+
: parsedPrompts[i].femalePrompt;
|
|
1024
|
+
|
|
1025
|
+
await this.log(
|
|
1026
|
+
'debug',
|
|
1027
|
+
`Updating Leonardo prompt for ${ptId} (pt-br, gender: ${ptGender})`,
|
|
1028
|
+
{
|
|
1029
|
+
leonardoPrompt: ptLeonardoPrompt,
|
|
1030
|
+
}
|
|
1031
|
+
);
|
|
1032
|
+
|
|
1033
|
+
const ptUpdateResult = await db
|
|
1034
|
+
.update(schema.archetypesData)
|
|
1035
|
+
.set({
|
|
1036
|
+
leonardoPrompt: ptLeonardoPrompt,
|
|
1037
|
+
updatedAt: new Date().getTime(),
|
|
1038
|
+
})
|
|
1039
|
+
.where(
|
|
1040
|
+
and(
|
|
1041
|
+
eq(schema.archetypesData.id, ptId),
|
|
1042
|
+
eq(schema.archetypesData.language, 'pt-br'),
|
|
1043
|
+
eq(schema.archetypesData.gender, ptGender)
|
|
1044
|
+
)
|
|
1045
|
+
)
|
|
1046
|
+
.execute();
|
|
1047
|
+
|
|
1048
|
+
await this.log(
|
|
1049
|
+
'info',
|
|
1050
|
+
`Updated Leonardo prompt for ${ptId} (pt-br, gender: ${ptGender})`,
|
|
1051
|
+
{
|
|
1052
|
+
rowsAffected: ptUpdateResult.rowsAffected,
|
|
1053
|
+
}
|
|
1054
|
+
);
|
|
1055
|
+
|
|
1056
|
+
if (ptUpdateResult.rowsAffected === 0) {
|
|
1057
|
+
await this.log(
|
|
1058
|
+
'error',
|
|
1059
|
+
`Failed to update Leonardo prompt for ${ptId} (pt-br, gender: ${ptGender})`,
|
|
1060
|
+
{
|
|
1061
|
+
ptId,
|
|
1062
|
+
language: 'pt-br',
|
|
1063
|
+
gender: ptGender,
|
|
1064
|
+
}
|
|
1065
|
+
);
|
|
1066
|
+
throw new Error(
|
|
1067
|
+
`Failed to update Leonardo prompt for ${ptId} (pt-br, gender: ${ptGender})`
|
|
1068
|
+
);
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
867
1071
|
}
|
|
868
1072
|
}
|
|
869
1073
|
|
|
@@ -879,63 +1083,83 @@ export class ArchetypeService {
|
|
|
879
1083
|
this.log('debug', 'Starting parseLeonardoPromptResponse', {
|
|
880
1084
|
responseLength: response.length,
|
|
881
1085
|
});
|
|
882
|
-
|
|
1086
|
+
|
|
883
1087
|
const lines = response.split('\n').filter((line) => line.trim());
|
|
884
1088
|
this.log('debug', 'Split response into lines', {
|
|
885
1089
|
linesCount: lines.length,
|
|
886
1090
|
lines,
|
|
887
1091
|
});
|
|
888
|
-
|
|
1092
|
+
|
|
889
1093
|
const prompts: LeonardoPrompt[] = [];
|
|
890
1094
|
let currentArchetype = 0;
|
|
891
|
-
|
|
1095
|
+
|
|
892
1096
|
for (let i = 0; i < lines.length; i += 4) {
|
|
893
1097
|
// Expect pairs of label and prompt: "1.m", male prompt, "1.f", female prompt
|
|
894
1098
|
const maleLabel = lines[i]; // "1.m"
|
|
895
1099
|
const malePromptLine = lines[i + 1]; // Male prompt text
|
|
896
1100
|
const femaleLabel = lines[i + 2]; // "1.f"
|
|
897
1101
|
const femalePromptLine = lines[i + 3]; // Female prompt text
|
|
898
|
-
|
|
1102
|
+
|
|
899
1103
|
currentArchetype++;
|
|
900
1104
|
const expectedMaleLabel = `${currentArchetype}.m`;
|
|
901
1105
|
const expectedFemaleLabel = `${currentArchetype}.f`;
|
|
902
|
-
|
|
903
|
-
if (
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
1106
|
+
|
|
1107
|
+
if (
|
|
1108
|
+
!maleLabel?.startsWith(expectedMaleLabel) ||
|
|
1109
|
+
!femaleLabel?.startsWith(expectedFemaleLabel)
|
|
1110
|
+
) {
|
|
1111
|
+
this.log(
|
|
1112
|
+
'warn',
|
|
1113
|
+
`Malformed Leonardo prompt format for archetype ${currentArchetype}`,
|
|
1114
|
+
{
|
|
1115
|
+
maleLabel,
|
|
1116
|
+
malePromptLine,
|
|
1117
|
+
femaleLabel,
|
|
1118
|
+
femalePromptLine,
|
|
1119
|
+
lines,
|
|
1120
|
+
}
|
|
1121
|
+
);
|
|
1122
|
+
throw new Error(
|
|
1123
|
+
`Expected ${expectedMaleLabel} and ${expectedFemaleLabel} at lines ${i} and ${
|
|
1124
|
+
i + 2
|
|
1125
|
+
}`
|
|
1126
|
+
);
|
|
912
1127
|
}
|
|
913
|
-
|
|
1128
|
+
|
|
914
1129
|
const malePrompt = malePromptLine?.trim() || '';
|
|
915
1130
|
const femalePrompt = femalePromptLine?.trim() || '';
|
|
916
|
-
|
|
1131
|
+
|
|
917
1132
|
if (!malePrompt || !femalePrompt) {
|
|
918
|
-
this.log(
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
1133
|
+
this.log(
|
|
1134
|
+
'warn',
|
|
1135
|
+
`Empty Leonardo prompt for archetype ${currentArchetype}`,
|
|
1136
|
+
{
|
|
1137
|
+
malePrompt,
|
|
1138
|
+
femalePrompt,
|
|
1139
|
+
malePromptLine,
|
|
1140
|
+
femalePromptLine,
|
|
1141
|
+
}
|
|
1142
|
+
);
|
|
924
1143
|
throw new Error(`Empty prompt for archetype ${currentArchetype}`);
|
|
925
1144
|
}
|
|
926
|
-
|
|
1145
|
+
|
|
927
1146
|
prompts.push({ malePrompt, femalePrompt });
|
|
928
|
-
this.log('debug', `Parsed prompts for archetype ${currentArchetype}`, {
|
|
1147
|
+
this.log('debug', `Parsed prompts for archetype ${currentArchetype}`, {
|
|
1148
|
+
malePrompt,
|
|
1149
|
+
femalePrompt,
|
|
1150
|
+
});
|
|
929
1151
|
}
|
|
930
|
-
|
|
1152
|
+
|
|
931
1153
|
if (prompts.length !== 3) {
|
|
932
1154
|
this.log('error', 'Expected exactly 3 archetype prompts', {
|
|
933
1155
|
promptsCount: prompts.length,
|
|
934
1156
|
response,
|
|
935
1157
|
});
|
|
936
|
-
throw new Error(
|
|
1158
|
+
throw new Error(
|
|
1159
|
+
`Expected exactly 3 archetype prompts, but got ${prompts.length}`
|
|
1160
|
+
);
|
|
937
1161
|
}
|
|
938
|
-
|
|
1162
|
+
|
|
939
1163
|
this.log('info', 'Completed parseLeonardoPromptResponse', { prompts });
|
|
940
1164
|
return prompts;
|
|
941
1165
|
}
|