@zodic/shared 0.0.373 → 0.0.375
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 +457 -345
- package/app/services/LeonardoService.ts +21 -16
- package/app/workflow/ArchetypeWorkflow.ts +142 -200
- package/package.json +1 -1
- package/types/scopes/generic.ts +1 -1
- package/utils/buildMessages.ts +1 -1
|
@@ -29,7 +29,6 @@ export class ArchetypeService {
|
|
|
29
29
|
context: Record<string, any> = {}
|
|
30
30
|
) {
|
|
31
31
|
const logMessage = `[${new Date().toISOString()}] [${level.toUpperCase()}] ${message}`;
|
|
32
|
-
|
|
33
32
|
console[level](logMessage, context);
|
|
34
33
|
}
|
|
35
34
|
|
|
@@ -49,6 +48,7 @@ export class ArchetypeService {
|
|
|
49
48
|
.select()
|
|
50
49
|
.from(schema.archetypesData)
|
|
51
50
|
.where(eq(schema.archetypesData.combination, combinationString))
|
|
51
|
+
.orderBy(schema.archetypesData.archetypeIndex)
|
|
52
52
|
.execute();
|
|
53
53
|
|
|
54
54
|
if (
|
|
@@ -134,7 +134,7 @@ export class ArchetypeService {
|
|
|
134
134
|
continue;
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
for (const gender of ['male', 'female']) {
|
|
137
|
+
for (const gender of ['male', 'female'] as Gender[]) {
|
|
138
138
|
for (const lang of ['en-us', 'pt-br']) {
|
|
139
139
|
const id = `${combinationString}:${gender}:${index}${
|
|
140
140
|
lang === 'pt-br' ? ':pt' : ''
|
|
@@ -153,6 +153,7 @@ export class ArchetypeService {
|
|
|
153
153
|
await this.log('debug', `Skipping existing archetype ${id}`, {
|
|
154
154
|
name: existing.name,
|
|
155
155
|
essenceLine: existing.essenceLine,
|
|
156
|
+
archetypeIndex: index,
|
|
156
157
|
});
|
|
157
158
|
continue;
|
|
158
159
|
}
|
|
@@ -160,6 +161,9 @@ export class ArchetypeService {
|
|
|
160
161
|
await this.log('debug', `Saving archetype name for ${id}`, {
|
|
161
162
|
name,
|
|
162
163
|
essenceLine,
|
|
164
|
+
archetypeIndex: index,
|
|
165
|
+
gender,
|
|
166
|
+
language: lang,
|
|
163
167
|
});
|
|
164
168
|
|
|
165
169
|
await db
|
|
@@ -210,6 +214,13 @@ export class ArchetypeService {
|
|
|
210
214
|
blocksCount: blocks.length,
|
|
211
215
|
});
|
|
212
216
|
|
|
217
|
+
if (blocks.length !== 3) {
|
|
218
|
+
this.log('error', 'Expected exactly 3 archetype blocks', {
|
|
219
|
+
blocksCount: blocks.length,
|
|
220
|
+
});
|
|
221
|
+
throw new Error(`Expected 3 archetype blocks, got ${blocks.length}`);
|
|
222
|
+
}
|
|
223
|
+
|
|
213
224
|
const english: Array<{ name: string; essenceLine: string }> = [];
|
|
214
225
|
const portuguese: Array<{
|
|
215
226
|
masc: string;
|
|
@@ -217,7 +228,7 @@ export class ArchetypeService {
|
|
|
217
228
|
essenceLine: string;
|
|
218
229
|
}> = [];
|
|
219
230
|
|
|
220
|
-
|
|
231
|
+
blocks.forEach((block, index) => {
|
|
221
232
|
const nameMatch = block.match(/- Name: (.+)/);
|
|
222
233
|
const essenceLineMatch = block.match(/- Essence Line: (.+)/);
|
|
223
234
|
const ptMascMatch = block.match(/- Portuguese \(Masc\): (.+)/);
|
|
@@ -240,10 +251,21 @@ export class ArchetypeService {
|
|
|
240
251
|
fem: ptFemMatch[1].trim(),
|
|
241
252
|
essenceLine: ptEssenceLineMatch[1].trim(),
|
|
242
253
|
});
|
|
254
|
+
this.log('debug', `Parsed block for archetypeIndex ${index + 1}`, {
|
|
255
|
+
english: english[index],
|
|
256
|
+
portuguese: portuguese[index],
|
|
257
|
+
});
|
|
243
258
|
} else {
|
|
244
|
-
this.log(
|
|
259
|
+
this.log(
|
|
260
|
+
'error',
|
|
261
|
+
`Malformed archetype name block for index ${index + 1}`,
|
|
262
|
+
{ block }
|
|
263
|
+
);
|
|
264
|
+
throw new Error(
|
|
265
|
+
`Malformed archetype name block for index ${index + 1}`
|
|
266
|
+
);
|
|
245
267
|
}
|
|
246
|
-
}
|
|
268
|
+
});
|
|
247
269
|
|
|
248
270
|
this.log('info', 'Completed parseArchetypeNameBlocks', {
|
|
249
271
|
english,
|
|
@@ -254,7 +276,7 @@ export class ArchetypeService {
|
|
|
254
276
|
|
|
255
277
|
async generateDescriptionsAndVirtues(
|
|
256
278
|
combinationString: string,
|
|
257
|
-
gender: Gender,
|
|
279
|
+
gender: Gender, // Used for compatibility, but processes both genders
|
|
258
280
|
language: string,
|
|
259
281
|
override: boolean = false
|
|
260
282
|
): Promise<ParsedDescriptionAndVirtues[]> {
|
|
@@ -266,48 +288,70 @@ export class ArchetypeService {
|
|
|
266
288
|
});
|
|
267
289
|
|
|
268
290
|
const db = this.context.drizzle();
|
|
269
|
-
const
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
291
|
+
const allGenders: Gender[] = ['male', 'female'];
|
|
292
|
+
const archetypesByGender: Record<Gender, any[]> = { male: [], female: [] };
|
|
293
|
+
|
|
294
|
+
for (const g of allGenders) {
|
|
295
|
+
const archetypes = await db
|
|
296
|
+
.select()
|
|
297
|
+
.from(schema.archetypesData)
|
|
298
|
+
.where(
|
|
299
|
+
and(
|
|
300
|
+
eq(schema.archetypesData.combination, combinationString),
|
|
301
|
+
eq(schema.archetypesData.gender, g),
|
|
302
|
+
eq(schema.archetypesData.language, language)
|
|
303
|
+
)
|
|
277
304
|
)
|
|
278
|
-
|
|
279
|
-
|
|
305
|
+
.orderBy(schema.archetypesData.archetypeIndex)
|
|
306
|
+
.execute();
|
|
307
|
+
archetypesByGender[g] = archetypes;
|
|
308
|
+
}
|
|
280
309
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
310
|
+
const needsGeneration = allGenders.some(
|
|
311
|
+
(g) =>
|
|
312
|
+
archetypesByGender[g].length !== 3 ||
|
|
313
|
+
archetypesByGender[g].some((a) => !a.description || a.virtues === '[]')
|
|
314
|
+
);
|
|
315
|
+
|
|
316
|
+
if (!override && !needsGeneration) {
|
|
285
317
|
await this.log('info', 'Skipping descriptions and virtues generation', {
|
|
286
318
|
reason: 'Descriptions and virtues already exist for all archetypes',
|
|
287
319
|
});
|
|
288
|
-
return
|
|
320
|
+
return archetypesByGender['male'].map((a, i) => ({
|
|
289
321
|
descriptionEN: a.description || '',
|
|
290
|
-
descriptionPTM:
|
|
291
|
-
descriptionPTF:
|
|
322
|
+
descriptionPTM: archetypesByGender['male'][i].description || '',
|
|
323
|
+
descriptionPTF: archetypesByGender['female'][i].description || '',
|
|
292
324
|
virtuesEN: JSON.parse(a.virtues || '[]'),
|
|
293
325
|
virtuesPT: JSON.parse(a.virtues || '[]'),
|
|
294
326
|
}));
|
|
295
327
|
}
|
|
296
328
|
|
|
297
329
|
await this.log('info', 'Fetched archetypes for description generation', {
|
|
298
|
-
|
|
299
|
-
|
|
330
|
+
maleArchetypes: archetypesByGender['male'].map((a) => ({
|
|
331
|
+
id: a.id,
|
|
332
|
+
name: a.name,
|
|
333
|
+
index: a.archetypeIndex,
|
|
334
|
+
})),
|
|
335
|
+
femaleArchetypes: archetypesByGender['female'].map((a) => ({
|
|
336
|
+
id: a.id,
|
|
337
|
+
name: a.name,
|
|
338
|
+
index: a.archetypeIndex,
|
|
339
|
+
})),
|
|
300
340
|
});
|
|
301
341
|
|
|
302
342
|
const descVirtueMessages = this.context
|
|
303
343
|
.buildLLMMessages()
|
|
304
344
|
.generateCosmicMirrorDescriptionAndVirtues({
|
|
305
345
|
combination: combinationString,
|
|
306
|
-
names: [
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
346
|
+
names: archetypesByGender['male'].map((a) => a.name) as [
|
|
347
|
+
string,
|
|
348
|
+
string,
|
|
349
|
+
string
|
|
350
|
+
],
|
|
351
|
+
essenceLines: archetypesByGender['male'].map((a) => a.essenceLine) as [
|
|
352
|
+
string,
|
|
353
|
+
string,
|
|
354
|
+
string
|
|
311
355
|
],
|
|
312
356
|
});
|
|
313
357
|
|
|
@@ -317,7 +361,7 @@ export class ArchetypeService {
|
|
|
317
361
|
const descVirtueResponse = await this.context
|
|
318
362
|
.api()
|
|
319
363
|
.callTogether.single(descVirtueMessages, {
|
|
320
|
-
options: { temperature: 0.
|
|
364
|
+
options: { temperature: 0.3 },
|
|
321
365
|
});
|
|
322
366
|
if (!descVirtueResponse) {
|
|
323
367
|
await this.log('error', 'No response for descriptions and virtues', {
|
|
@@ -339,106 +383,78 @@ export class ArchetypeService {
|
|
|
339
383
|
|
|
340
384
|
for (let i = 0; i < 3; i++) {
|
|
341
385
|
const index = (i + 1).toString();
|
|
342
|
-
const
|
|
343
|
-
|
|
344
|
-
|
|
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
|
-
) {
|
|
386
|
+
for (const g of allGenders) {
|
|
387
|
+
const archetype = archetypesByGender[g][i];
|
|
388
|
+
if (!archetype || archetype.archetypeIndex !== index) {
|
|
353
389
|
await this.log(
|
|
354
|
-
'
|
|
355
|
-
`
|
|
390
|
+
'error',
|
|
391
|
+
`Archetype index mismatch for gender ${g} at position ${i + 1}`,
|
|
356
392
|
{
|
|
357
|
-
|
|
358
|
-
|
|
393
|
+
expectedIndex: index,
|
|
394
|
+
actualIndex: archetype?.archetypeIndex,
|
|
395
|
+
archetypeId: archetype?.id,
|
|
359
396
|
}
|
|
360
397
|
);
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
'debug',
|
|
364
|
-
`Updating description and virtues for ${enId}`,
|
|
365
|
-
{
|
|
366
|
-
description: parsedDescVirtues[i].descriptionEN,
|
|
367
|
-
virtues: parsedDescVirtues[i].virtuesEN,
|
|
368
|
-
}
|
|
398
|
+
throw new Error(
|
|
399
|
+
`Archetype index mismatch for gender ${g}: expected ${index}, got ${archetype?.archetypeIndex}`
|
|
369
400
|
);
|
|
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}`);
|
|
385
401
|
}
|
|
386
|
-
}
|
|
387
402
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
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;
|
|
403
|
+
const id = `${combinationString}:${g}:${index}${
|
|
404
|
+
language === 'pt-br' ? ':pt' : ''
|
|
405
|
+
}`;
|
|
406
|
+
if (!override && archetype.description && archetype.virtues !== '[]') {
|
|
414
407
|
await this.log(
|
|
415
408
|
'debug',
|
|
416
|
-
`
|
|
409
|
+
`Skipping existing description and virtues for ${id}`,
|
|
417
410
|
{
|
|
418
|
-
description,
|
|
419
|
-
virtues:
|
|
411
|
+
description: archetype.description,
|
|
412
|
+
virtues: archetype.virtues,
|
|
413
|
+
archetypeIndex: index,
|
|
414
|
+
gender: g,
|
|
415
|
+
language,
|
|
420
416
|
}
|
|
421
417
|
);
|
|
422
|
-
|
|
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
|
-
);
|
|
418
|
+
continue;
|
|
441
419
|
}
|
|
420
|
+
|
|
421
|
+
const description =
|
|
422
|
+
language === 'en-us'
|
|
423
|
+
? parsedDescVirtues[i].descriptionEN
|
|
424
|
+
: g === 'male'
|
|
425
|
+
? parsedDescVirtues[i].descriptionPTM
|
|
426
|
+
: parsedDescVirtues[i].descriptionPTF;
|
|
427
|
+
const virtues =
|
|
428
|
+
language === 'en-us'
|
|
429
|
+
? parsedDescVirtues[i].virtuesEN
|
|
430
|
+
: parsedDescVirtues[i].virtuesPT;
|
|
431
|
+
|
|
432
|
+
await this.log('debug', `Updating description and virtues for ${id}`, {
|
|
433
|
+
description,
|
|
434
|
+
virtues,
|
|
435
|
+
archetypeIndex: index,
|
|
436
|
+
gender: g,
|
|
437
|
+
language,
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
await db
|
|
441
|
+
.update(schema.archetypesData)
|
|
442
|
+
.set({
|
|
443
|
+
description,
|
|
444
|
+
virtues: JSON.stringify(virtues),
|
|
445
|
+
updatedAt: new Date().getTime(),
|
|
446
|
+
})
|
|
447
|
+
.where(
|
|
448
|
+
and(
|
|
449
|
+
eq(schema.archetypesData.id, id),
|
|
450
|
+
eq(schema.archetypesData.language, language),
|
|
451
|
+
eq(schema.archetypesData.gender, g),
|
|
452
|
+
eq(schema.archetypesData.archetypeIndex, index)
|
|
453
|
+
)
|
|
454
|
+
)
|
|
455
|
+
.execute();
|
|
456
|
+
|
|
457
|
+
await this.log('info', `Updated description and virtues for ${id}`);
|
|
442
458
|
}
|
|
443
459
|
}
|
|
444
460
|
|
|
@@ -488,6 +504,22 @@ export class ArchetypeService {
|
|
|
488
504
|
lines,
|
|
489
505
|
});
|
|
490
506
|
|
|
507
|
+
if (lines[0] !== `${entryIndex + 1}.`) {
|
|
508
|
+
this.log(
|
|
509
|
+
'error',
|
|
510
|
+
`Invalid archetype index in entry ${entryIndex + 1}`,
|
|
511
|
+
{
|
|
512
|
+
expected: `${entryIndex + 1}.`,
|
|
513
|
+
found: lines[0],
|
|
514
|
+
}
|
|
515
|
+
);
|
|
516
|
+
throw new Error(
|
|
517
|
+
`Invalid archetype index in entry ${entryIndex + 1}: expected ${
|
|
518
|
+
entryIndex + 1
|
|
519
|
+
}, got ${lines[0]}`
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
|
|
491
523
|
let descriptionEN = '';
|
|
492
524
|
let descriptionPTM = '';
|
|
493
525
|
let descriptionPTF = '';
|
|
@@ -495,18 +527,10 @@ export class ArchetypeService {
|
|
|
495
527
|
let virtuesPT: string[] = [];
|
|
496
528
|
let currentField = '';
|
|
497
529
|
|
|
498
|
-
for (let i =
|
|
530
|
+
for (let i = 1; i < lines.length; i++) {
|
|
499
531
|
let line = lines[i];
|
|
500
532
|
line = line.replace(/\*\*(.*?)\*\*/g, '$1');
|
|
501
533
|
|
|
502
|
-
if (
|
|
503
|
-
line.startsWith('1.') ||
|
|
504
|
-
line.startsWith('2.') ||
|
|
505
|
-
line.startsWith('3.')
|
|
506
|
-
) {
|
|
507
|
-
continue;
|
|
508
|
-
}
|
|
509
|
-
|
|
510
534
|
if (line.startsWith('• Description EN:')) {
|
|
511
535
|
currentField = 'descriptionEN';
|
|
512
536
|
descriptionEN = line.split('• Description EN:')[1]?.trim() || '';
|
|
@@ -612,7 +636,7 @@ export class ArchetypeService {
|
|
|
612
636
|
virtuesPT.length !== 3
|
|
613
637
|
) {
|
|
614
638
|
this.log(
|
|
615
|
-
'
|
|
639
|
+
'error',
|
|
616
640
|
`Malformed description and virtues response for entry ${
|
|
617
641
|
entryIndex + 1
|
|
618
642
|
}`,
|
|
@@ -632,13 +656,19 @@ export class ArchetypeService {
|
|
|
632
656
|
);
|
|
633
657
|
}
|
|
634
658
|
|
|
635
|
-
|
|
659
|
+
const parsed = {
|
|
636
660
|
descriptionEN,
|
|
637
661
|
descriptionPTM,
|
|
638
662
|
descriptionPTF,
|
|
639
663
|
virtuesEN,
|
|
640
664
|
virtuesPT,
|
|
641
665
|
};
|
|
666
|
+
this.log(
|
|
667
|
+
'debug',
|
|
668
|
+
`Parsed description and virtues for archetypeIndex ${entryIndex + 1}`,
|
|
669
|
+
{ parsed }
|
|
670
|
+
);
|
|
671
|
+
return parsed;
|
|
642
672
|
});
|
|
643
673
|
|
|
644
674
|
this.log('info', 'Completed parseDescriptionAndVirtuesResponse', {
|
|
@@ -649,7 +679,7 @@ export class ArchetypeService {
|
|
|
649
679
|
|
|
650
680
|
async generateContent(
|
|
651
681
|
combinationString: string,
|
|
652
|
-
gender: Gender,
|
|
682
|
+
gender: Gender, // Used for compatibility, but processes both genders
|
|
653
683
|
language: string,
|
|
654
684
|
descriptions: Array<{ descriptionEN: string }>,
|
|
655
685
|
override: boolean = false
|
|
@@ -662,19 +692,32 @@ export class ArchetypeService {
|
|
|
662
692
|
});
|
|
663
693
|
|
|
664
694
|
const db = this.context.drizzle();
|
|
665
|
-
const
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
695
|
+
const allGenders: Gender[] = ['male', 'female'];
|
|
696
|
+
const archetypesByGender: Record<Gender, any[]> = { male: [], female: [] };
|
|
697
|
+
|
|
698
|
+
for (const g of allGenders) {
|
|
699
|
+
const archetypes = await db
|
|
700
|
+
.select()
|
|
701
|
+
.from(schema.archetypesData)
|
|
702
|
+
.where(
|
|
703
|
+
and(
|
|
704
|
+
eq(schema.archetypesData.combination, combinationString),
|
|
705
|
+
eq(schema.archetypesData.gender, g),
|
|
706
|
+
eq(schema.archetypesData.language, language)
|
|
707
|
+
)
|
|
673
708
|
)
|
|
674
|
-
|
|
675
|
-
|
|
709
|
+
.orderBy(schema.archetypesData.archetypeIndex)
|
|
710
|
+
.execute();
|
|
711
|
+
archetypesByGender[g] = archetypes;
|
|
712
|
+
}
|
|
676
713
|
|
|
677
|
-
|
|
714
|
+
const needsGeneration = allGenders.some(
|
|
715
|
+
(g) =>
|
|
716
|
+
archetypesByGender[g].length !== 3 ||
|
|
717
|
+
archetypesByGender[g].some((a) => a.content === '[]')
|
|
718
|
+
);
|
|
719
|
+
|
|
720
|
+
if (!override && !needsGeneration) {
|
|
678
721
|
await this.log('info', 'Skipping content generation', {
|
|
679
722
|
reason: 'Content already exists for all archetypes',
|
|
680
723
|
});
|
|
@@ -682,122 +725,159 @@ export class ArchetypeService {
|
|
|
682
725
|
}
|
|
683
726
|
|
|
684
727
|
await this.log('info', 'Fetched archetypes for content generation', {
|
|
685
|
-
|
|
686
|
-
|
|
728
|
+
maleArchetypes: archetypesByGender['male'].map((a) => ({
|
|
729
|
+
id: a.id,
|
|
730
|
+
name: a.name,
|
|
731
|
+
index: a.archetypeIndex,
|
|
732
|
+
})),
|
|
733
|
+
femaleArchetypes: archetypesByGender['female'].map((a) => ({
|
|
734
|
+
id: a.id,
|
|
735
|
+
name: a.name,
|
|
736
|
+
index: a.archetypeIndex,
|
|
737
|
+
})),
|
|
687
738
|
});
|
|
688
739
|
|
|
689
740
|
const contentResults = [];
|
|
690
741
|
for (let i = 0; i < 3; i++) {
|
|
691
742
|
const index = (i + 1).toString();
|
|
692
|
-
const
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
743
|
+
for (const g of allGenders) {
|
|
744
|
+
const archetype = archetypesByGender[g][i];
|
|
745
|
+
if (!archetype || archetype.archetypeIndex !== index) {
|
|
746
|
+
await this.log(
|
|
747
|
+
'error',
|
|
748
|
+
`Archetype index mismatch for gender ${g} at position ${i + 1}`,
|
|
749
|
+
{
|
|
750
|
+
expectedIndex: index,
|
|
751
|
+
actualIndex: archetype?.archetypeIndex,
|
|
752
|
+
archetypeId: archetype?.id,
|
|
753
|
+
}
|
|
754
|
+
);
|
|
755
|
+
throw new Error(
|
|
756
|
+
`Archetype index mismatch for gender ${g}: expected ${index}, got ${archetype?.archetypeIndex}`
|
|
757
|
+
);
|
|
758
|
+
}
|
|
704
759
|
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
760
|
+
const id = `${combinationString}:${g}:${index}${
|
|
761
|
+
language === 'pt-br' ? ':pt' : ''
|
|
762
|
+
}`;
|
|
763
|
+
if (!override && archetype.content !== '[]') {
|
|
764
|
+
await this.log('debug', `Skipping existing content for ${id}`, {
|
|
765
|
+
content: archetype.content,
|
|
766
|
+
archetypeIndex: index,
|
|
767
|
+
gender: g,
|
|
768
|
+
language,
|
|
769
|
+
});
|
|
770
|
+
if (g === 'male') contentResults.push({}); // Placeholder for male only
|
|
771
|
+
continue;
|
|
772
|
+
}
|
|
715
773
|
|
|
716
|
-
await this.log('debug', `Calling API for content of archetype ${i + 1}`, {
|
|
717
|
-
messages: contentMessages,
|
|
718
|
-
});
|
|
719
|
-
const contentResponse = await this.context
|
|
720
|
-
.api()
|
|
721
|
-
.callTogether.single(contentMessages, {});
|
|
722
|
-
if (!contentResponse) {
|
|
723
774
|
await this.log(
|
|
724
|
-
'
|
|
725
|
-
`
|
|
775
|
+
'debug',
|
|
776
|
+
`Generating content for archetype ${index} (${g})`,
|
|
777
|
+
{ name: archetype.name }
|
|
778
|
+
);
|
|
779
|
+
const contentMessages = this.context
|
|
780
|
+
.buildLLMMessages()
|
|
781
|
+
.generateCosmicMirrorArchetypeContent({
|
|
782
|
+
combination: combinationString,
|
|
783
|
+
name: archetype.name,
|
|
784
|
+
description: descriptions[i].descriptionEN,
|
|
785
|
+
});
|
|
786
|
+
|
|
787
|
+
await this.log(
|
|
788
|
+
'debug',
|
|
789
|
+
`Calling API for content of archetype ${index} (${g})`,
|
|
790
|
+
{ messages: contentMessages }
|
|
791
|
+
);
|
|
792
|
+
const contentResponse = await this.context
|
|
793
|
+
.api()
|
|
794
|
+
.callTogether.single(contentMessages, {});
|
|
795
|
+
if (!contentResponse) {
|
|
796
|
+
await this.log(
|
|
797
|
+
'error',
|
|
798
|
+
`No response for content of archetype ${index} (${g})`,
|
|
799
|
+
{
|
|
800
|
+
combinationString,
|
|
801
|
+
archetype: archetype.name,
|
|
802
|
+
}
|
|
803
|
+
);
|
|
804
|
+
throw new Error(
|
|
805
|
+
`Failed to generate content for archetype ${index} (${g}) of: ${combinationString}`
|
|
806
|
+
);
|
|
807
|
+
}
|
|
808
|
+
await this.log(
|
|
809
|
+
'info',
|
|
810
|
+
`Received content response for archetype ${index} (${g})`,
|
|
726
811
|
{
|
|
727
|
-
|
|
728
|
-
|
|
812
|
+
responseLength: contentResponse.length,
|
|
813
|
+
rawResponse: contentResponse, // Log raw response for debugging
|
|
729
814
|
}
|
|
730
815
|
);
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
816
|
+
|
|
817
|
+
await this.log(
|
|
818
|
+
'debug',
|
|
819
|
+
`Parsing content response for archetype ${index} (${g})`
|
|
735
820
|
);
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
'info',
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
responseLength: contentResponse.length,
|
|
742
|
-
}
|
|
743
|
-
);
|
|
821
|
+
const parsedContent = this.parseContentResponse(contentResponse);
|
|
822
|
+
if (g === 'male') contentResults.push(parsedContent);
|
|
823
|
+
await this.log('info', `Parsed content for archetype ${index} (${g})`, {
|
|
824
|
+
parsedContent,
|
|
825
|
+
});
|
|
744
826
|
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
827
|
+
const contentLangIndex =
|
|
828
|
+
language === 'en-us' ? 0 : g === 'male' ? 1 : 2;
|
|
829
|
+
const content = [
|
|
830
|
+
{
|
|
831
|
+
section: 'voiceOfTheSoul',
|
|
832
|
+
text: parsedContent[contentLangIndex].voiceOfTheSoul,
|
|
833
|
+
},
|
|
834
|
+
{
|
|
835
|
+
section: 'giftsYouBear',
|
|
836
|
+
text: parsedContent[contentLangIndex].giftsYouBear,
|
|
837
|
+
},
|
|
838
|
+
{
|
|
839
|
+
section: 'shadowsYouFace',
|
|
840
|
+
text: parsedContent[contentLangIndex].shadowsYouFace,
|
|
841
|
+
},
|
|
842
|
+
{
|
|
843
|
+
section: 'rhythmOfYourDays',
|
|
844
|
+
text: parsedContent[contentLangIndex].rhythmOfYourDays,
|
|
845
|
+
},
|
|
846
|
+
{
|
|
847
|
+
section: 'tiesThatBind',
|
|
848
|
+
text: parsedContent[contentLangIndex].tiesThatBind,
|
|
849
|
+
},
|
|
850
|
+
{
|
|
851
|
+
section: 'lightWithin',
|
|
852
|
+
text: parsedContent[contentLangIndex].lightWithin,
|
|
853
|
+
},
|
|
854
|
+
];
|
|
855
|
+
|
|
856
|
+
await this.log('debug', `Updating content for ${id}`, {
|
|
857
|
+
content,
|
|
858
|
+
archetypeIndex: index,
|
|
859
|
+
gender: g,
|
|
860
|
+
language,
|
|
861
|
+
});
|
|
754
862
|
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
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
|
-
];
|
|
783
|
-
|
|
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)
|
|
863
|
+
await db
|
|
864
|
+
.update(schema.archetypesData)
|
|
865
|
+
.set({
|
|
866
|
+
content: JSON.stringify(content),
|
|
867
|
+
updatedAt: new Date().getTime(),
|
|
868
|
+
})
|
|
869
|
+
.where(
|
|
870
|
+
and(
|
|
871
|
+
eq(schema.archetypesData.id, id),
|
|
872
|
+
eq(schema.archetypesData.language, language),
|
|
873
|
+
eq(schema.archetypesData.gender, g),
|
|
874
|
+
eq(schema.archetypesData.archetypeIndex, index)
|
|
875
|
+
)
|
|
796
876
|
)
|
|
797
|
-
|
|
798
|
-
.execute();
|
|
877
|
+
.execute();
|
|
799
878
|
|
|
800
|
-
|
|
879
|
+
await this.log('info', `Updated content for ${id}`);
|
|
880
|
+
}
|
|
801
881
|
}
|
|
802
882
|
|
|
803
883
|
await this.log('info', 'Completed generateContent', {
|
|
@@ -821,6 +901,14 @@ export class ArchetypeService {
|
|
|
821
901
|
sectionsCount: sections.length,
|
|
822
902
|
});
|
|
823
903
|
|
|
904
|
+
if (sections.length !== 3) {
|
|
905
|
+
this.log('error', 'Expected exactly 3 content sections', {
|
|
906
|
+
sectionsCount: sections.length,
|
|
907
|
+
response,
|
|
908
|
+
});
|
|
909
|
+
throw new Error(`Expected 3 content sections, got ${sections.length}`);
|
|
910
|
+
}
|
|
911
|
+
|
|
824
912
|
const result = sections.map((section, sectionIndex) => {
|
|
825
913
|
this.log('debug', `Processing section ${sectionIndex + 1}`, { section });
|
|
826
914
|
|
|
@@ -830,24 +918,28 @@ export class ArchetypeService {
|
|
|
830
918
|
lines,
|
|
831
919
|
});
|
|
832
920
|
|
|
921
|
+
const expectedHeader =
|
|
922
|
+
sectionIndex === 0 ? 'EN:' : sectionIndex === 1 ? 'PT-M:' : 'PT-F:';
|
|
923
|
+
const actualHeader = lines[0].trim(); // Trim the header to remove trailing spaces
|
|
924
|
+
if (actualHeader !== expectedHeader) {
|
|
925
|
+
this.log(
|
|
926
|
+
'error',
|
|
927
|
+
`Invalid language header in section ${sectionIndex + 1}`,
|
|
928
|
+
{
|
|
929
|
+
expected: expectedHeader,
|
|
930
|
+
found: actualHeader,
|
|
931
|
+
}
|
|
932
|
+
);
|
|
933
|
+
throw new Error(
|
|
934
|
+
`Invalid language header in section ${sectionIndex + 1}`
|
|
935
|
+
);
|
|
936
|
+
}
|
|
937
|
+
|
|
833
938
|
const content: Record<string, string> = {};
|
|
834
939
|
let currentSection = '';
|
|
835
940
|
let currentText: string[] = [];
|
|
836
941
|
|
|
837
|
-
for (const line of lines) {
|
|
838
|
-
if (
|
|
839
|
-
line.startsWith('EN:') ||
|
|
840
|
-
line.startsWith('PT-M:') ||
|
|
841
|
-
line.startsWith('PT-F:')
|
|
842
|
-
) {
|
|
843
|
-
this.log(
|
|
844
|
-
'debug',
|
|
845
|
-
`Skipping language header in section ${sectionIndex + 1}`,
|
|
846
|
-
{ line }
|
|
847
|
-
);
|
|
848
|
-
continue;
|
|
849
|
-
}
|
|
850
|
-
|
|
942
|
+
for (const line of lines.slice(1)) {
|
|
851
943
|
if (line.startsWith('#')) {
|
|
852
944
|
if (currentSection && currentText.length > 0) {
|
|
853
945
|
const key = currentSection
|
|
@@ -913,15 +1005,21 @@ export class ArchetypeService {
|
|
|
913
1005
|
|
|
914
1006
|
if (Object.values(parsedContent).some((value) => !value)) {
|
|
915
1007
|
this.log(
|
|
916
|
-
'
|
|
1008
|
+
'error',
|
|
917
1009
|
`Malformed content response for section ${sectionIndex + 1}`,
|
|
918
1010
|
{
|
|
919
1011
|
parsedContent,
|
|
920
1012
|
response: section,
|
|
921
1013
|
}
|
|
922
1014
|
);
|
|
1015
|
+
throw new Error(
|
|
1016
|
+
`Malformed content response for section ${sectionIndex + 1}`
|
|
1017
|
+
);
|
|
923
1018
|
}
|
|
924
1019
|
|
|
1020
|
+
this.log('debug', `Parsed content for section ${sectionIndex + 1}`, {
|
|
1021
|
+
parsedContent,
|
|
1022
|
+
});
|
|
925
1023
|
return parsedContent;
|
|
926
1024
|
});
|
|
927
1025
|
|
|
@@ -931,7 +1029,7 @@ export class ArchetypeService {
|
|
|
931
1029
|
|
|
932
1030
|
async generateLeonardoPrompts(
|
|
933
1031
|
combinationString: string,
|
|
934
|
-
gender: Gender,
|
|
1032
|
+
gender: Gender, // Used for compatibility, but processes both genders
|
|
935
1033
|
language: string,
|
|
936
1034
|
descriptions: Array<{ descriptionEN: string }>,
|
|
937
1035
|
override: boolean = false
|
|
@@ -944,9 +1042,8 @@ export class ArchetypeService {
|
|
|
944
1042
|
});
|
|
945
1043
|
|
|
946
1044
|
const db = this.context.drizzle();
|
|
947
|
-
|
|
948
|
-
const
|
|
949
|
-
const archetypesByGender: Record<Binary, any[]> = { male: [], female: [] };
|
|
1045
|
+
const allGenders: Gender[] = ['male', 'female'];
|
|
1046
|
+
const archetypesByGender: Record<Gender, any[]> = { male: [], female: [] };
|
|
950
1047
|
|
|
951
1048
|
for (const g of allGenders) {
|
|
952
1049
|
const archetypes = await db
|
|
@@ -959,30 +1056,18 @@ export class ArchetypeService {
|
|
|
959
1056
|
eq(schema.archetypesData.language, language)
|
|
960
1057
|
)
|
|
961
1058
|
)
|
|
1059
|
+
.orderBy(schema.archetypesData.archetypeIndex)
|
|
962
1060
|
.execute();
|
|
963
1061
|
archetypesByGender[g] = archetypes;
|
|
964
1062
|
}
|
|
965
1063
|
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
{
|
|
972
|
-
combinationString,
|
|
973
|
-
gender: g,
|
|
974
|
-
}
|
|
975
|
-
);
|
|
976
|
-
throw new Error(
|
|
977
|
-
`Expected 3 archetypes for gender ${g}, but found ${archetypesByGender[g].length}`
|
|
978
|
-
);
|
|
979
|
-
}
|
|
980
|
-
}
|
|
1064
|
+
const needsGeneration = allGenders.some(
|
|
1065
|
+
(g) =>
|
|
1066
|
+
archetypesByGender[g].length !== 3 ||
|
|
1067
|
+
archetypesByGender[g].some((a) => !a.leonardoPrompt)
|
|
1068
|
+
);
|
|
981
1069
|
|
|
982
|
-
if (
|
|
983
|
-
!override &&
|
|
984
|
-
archetypesByGender[gender as Binary].every((a) => a.leonardoPrompt)
|
|
985
|
-
) {
|
|
1070
|
+
if (!override && !needsGeneration) {
|
|
986
1071
|
await this.log('info', 'Skipping Leonardo prompts generation', {
|
|
987
1072
|
reason: 'Leonardo prompts already exist for all archetypes',
|
|
988
1073
|
});
|
|
@@ -990,12 +1075,16 @@ export class ArchetypeService {
|
|
|
990
1075
|
}
|
|
991
1076
|
|
|
992
1077
|
await this.log('info', 'Fetched archetypes for Leonardo prompts', {
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
1078
|
+
maleArchetypes: archetypesByGender['male'].map((a) => ({
|
|
1079
|
+
id: a.id,
|
|
1080
|
+
name: a.name,
|
|
1081
|
+
index: a.archetypeIndex,
|
|
1082
|
+
})),
|
|
1083
|
+
femaleArchetypes: archetypesByGender['female'].map((a) => ({
|
|
1084
|
+
id: a.id,
|
|
1085
|
+
name: a.name,
|
|
1086
|
+
index: a.archetypeIndex,
|
|
1087
|
+
})),
|
|
999
1088
|
});
|
|
1000
1089
|
|
|
1001
1090
|
const promptMessages = this.context
|
|
@@ -1030,46 +1119,71 @@ export class ArchetypeService {
|
|
|
1030
1119
|
|
|
1031
1120
|
for (const g of allGenders) {
|
|
1032
1121
|
for (let i = 0; i < 3; i++) {
|
|
1122
|
+
const archetype = archetypesByGender[g][i];
|
|
1033
1123
|
const index = (i + 1).toString();
|
|
1124
|
+
if (!archetype || archetype.archetypeIndex !== index) {
|
|
1125
|
+
await this.log(
|
|
1126
|
+
'error',
|
|
1127
|
+
`Archetype index mismatch for gender ${g} at position ${i + 1}`,
|
|
1128
|
+
{
|
|
1129
|
+
expectedIndex: index,
|
|
1130
|
+
actualIndex: archetype?.archetypeIndex,
|
|
1131
|
+
archetypeId: archetype?.id,
|
|
1132
|
+
}
|
|
1133
|
+
);
|
|
1134
|
+
throw new Error(
|
|
1135
|
+
`Archetype index mismatch for gender ${g}: expected ${index}, got ${archetype?.archetypeIndex}`
|
|
1136
|
+
);
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1034
1139
|
const leonardoPrompt =
|
|
1035
1140
|
g === 'male'
|
|
1036
1141
|
? parsedPrompts[i].malePrompt
|
|
1037
1142
|
: parsedPrompts[i].femalePrompt;
|
|
1038
|
-
|
|
1039
1143
|
const id = `${combinationString}:${g}:${index}${
|
|
1040
1144
|
language === 'pt-br' ? ':pt' : ''
|
|
1041
1145
|
}`;
|
|
1042
|
-
|
|
1043
|
-
if (!override &&
|
|
1146
|
+
|
|
1147
|
+
if (!override && archetype.leonardoPrompt) {
|
|
1044
1148
|
await this.log(
|
|
1045
1149
|
'debug',
|
|
1046
1150
|
`Skipping existing Leonardo prompt for ${id}`,
|
|
1047
1151
|
{
|
|
1048
|
-
leonardoPrompt:
|
|
1152
|
+
leonardoPrompt: archetype.leonardoPrompt,
|
|
1153
|
+
archetypeIndex: index,
|
|
1154
|
+
gender: g,
|
|
1155
|
+
language,
|
|
1049
1156
|
}
|
|
1050
1157
|
);
|
|
1051
|
-
|
|
1052
|
-
|
|
1158
|
+
continue;
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
await this.log('debug', `Updating Leonardo prompt for ${id}`, {
|
|
1162
|
+
leonardoPrompt,
|
|
1163
|
+
archetypeIndex: index,
|
|
1164
|
+
gender: g,
|
|
1165
|
+
language,
|
|
1166
|
+
});
|
|
1167
|
+
|
|
1168
|
+
const updateResult = await db
|
|
1169
|
+
.update(schema.archetypesData)
|
|
1170
|
+
.set({
|
|
1053
1171
|
leonardoPrompt,
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
and(
|
|
1063
|
-
eq(schema.archetypesData.id, id),
|
|
1064
|
-
eq(schema.archetypesData.language, language),
|
|
1065
|
-
eq(schema.archetypesData.gender, g)
|
|
1066
|
-
)
|
|
1172
|
+
updatedAt: new Date().getTime(),
|
|
1173
|
+
})
|
|
1174
|
+
.where(
|
|
1175
|
+
and(
|
|
1176
|
+
eq(schema.archetypesData.id, id),
|
|
1177
|
+
eq(schema.archetypesData.language, language),
|
|
1178
|
+
eq(schema.archetypesData.gender, g),
|
|
1179
|
+
eq(schema.archetypesData.archetypeIndex, index)
|
|
1067
1180
|
)
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1181
|
+
)
|
|
1182
|
+
.execute();
|
|
1183
|
+
|
|
1184
|
+
await this.log('info', `Updated Leonardo prompt for ${id}`, {
|
|
1185
|
+
rowsAffected: updateResult.rowsAffected,
|
|
1186
|
+
});
|
|
1073
1187
|
}
|
|
1074
1188
|
}
|
|
1075
1189
|
|
|
@@ -1092,38 +1206,45 @@ export class ArchetypeService {
|
|
|
1092
1206
|
lines,
|
|
1093
1207
|
});
|
|
1094
1208
|
|
|
1095
|
-
|
|
1096
|
-
|
|
1209
|
+
if (lines.length !== 12) {
|
|
1210
|
+
this.log('error', 'Expected exactly 12 lines for 3 archetype prompts', {
|
|
1211
|
+
linesCount: lines.length,
|
|
1212
|
+
response,
|
|
1213
|
+
});
|
|
1214
|
+
throw new Error(
|
|
1215
|
+
`Expected 12 lines for 3 archetype prompts, got ${lines.length}`
|
|
1216
|
+
);
|
|
1217
|
+
}
|
|
1097
1218
|
|
|
1219
|
+
const prompts: LeonardoPrompt[] = [];
|
|
1098
1220
|
for (let i = 0; i < lines.length; i += 4) {
|
|
1221
|
+
const archetypeIndex = i / 4 + 1;
|
|
1099
1222
|
const maleLabel = lines[i];
|
|
1100
1223
|
const malePromptLine = lines[i + 1];
|
|
1101
1224
|
const femaleLabel = lines[i + 2];
|
|
1102
1225
|
const femalePromptLine = lines[i + 3];
|
|
1103
1226
|
|
|
1104
|
-
|
|
1105
|
-
const
|
|
1106
|
-
const expectedFemaleLabel = `${currentArchetype}.f`;
|
|
1227
|
+
const expectedMaleLabel = `${archetypeIndex}.m`;
|
|
1228
|
+
const expectedFemaleLabel = `${archetypeIndex}.f`;
|
|
1107
1229
|
|
|
1108
1230
|
if (
|
|
1109
1231
|
!maleLabel?.startsWith(expectedMaleLabel) ||
|
|
1110
1232
|
!femaleLabel?.startsWith(expectedFemaleLabel)
|
|
1111
1233
|
) {
|
|
1112
1234
|
this.log(
|
|
1113
|
-
'
|
|
1114
|
-
`Malformed Leonardo prompt format for archetype ${
|
|
1235
|
+
'error',
|
|
1236
|
+
`Malformed Leonardo prompt format for archetype ${archetypeIndex}`,
|
|
1115
1237
|
{
|
|
1116
1238
|
maleLabel,
|
|
1117
1239
|
malePromptLine,
|
|
1118
1240
|
femaleLabel,
|
|
1119
1241
|
femalePromptLine,
|
|
1120
|
-
|
|
1242
|
+
expectedMaleLabel,
|
|
1243
|
+
expectedFemaleLabel,
|
|
1121
1244
|
}
|
|
1122
1245
|
);
|
|
1123
1246
|
throw new Error(
|
|
1124
|
-
`
|
|
1125
|
-
i + 2
|
|
1126
|
-
}`
|
|
1247
|
+
`Malformed prompt format for archetype ${archetypeIndex}`
|
|
1127
1248
|
);
|
|
1128
1249
|
}
|
|
1129
1250
|
|
|
@@ -1132,42 +1253,30 @@ export class ArchetypeService {
|
|
|
1132
1253
|
|
|
1133
1254
|
if (!malePrompt || !femalePrompt) {
|
|
1134
1255
|
this.log(
|
|
1135
|
-
'
|
|
1136
|
-
`Empty Leonardo prompt for archetype ${
|
|
1256
|
+
'error',
|
|
1257
|
+
`Empty Leonardo prompt for archetype ${archetypeIndex}`,
|
|
1137
1258
|
{
|
|
1138
1259
|
malePrompt,
|
|
1139
1260
|
femalePrompt,
|
|
1140
|
-
malePromptLine,
|
|
1141
|
-
femalePromptLine,
|
|
1142
1261
|
}
|
|
1143
1262
|
);
|
|
1144
|
-
throw new Error(`Empty prompt for archetype ${
|
|
1263
|
+
throw new Error(`Empty prompt for archetype ${archetypeIndex}`);
|
|
1145
1264
|
}
|
|
1146
1265
|
|
|
1147
1266
|
prompts.push({ malePrompt, femalePrompt });
|
|
1148
|
-
this.log('debug', `Parsed prompts for
|
|
1267
|
+
this.log('debug', `Parsed prompts for archetypeIndex ${archetypeIndex}`, {
|
|
1149
1268
|
malePrompt,
|
|
1150
1269
|
femalePrompt,
|
|
1151
1270
|
});
|
|
1152
1271
|
}
|
|
1153
1272
|
|
|
1154
|
-
if (prompts.length !== 3) {
|
|
1155
|
-
this.log('error', 'Expected exactly 3 archetype prompts', {
|
|
1156
|
-
promptsCount: prompts.length,
|
|
1157
|
-
response,
|
|
1158
|
-
});
|
|
1159
|
-
throw new Error(
|
|
1160
|
-
`Expected exactly 3 archetype prompts, but got ${prompts.length}`
|
|
1161
|
-
);
|
|
1162
|
-
}
|
|
1163
|
-
|
|
1164
1273
|
this.log('info', 'Completed parseLeonardoPromptResponse', { prompts });
|
|
1165
1274
|
return prompts;
|
|
1166
1275
|
}
|
|
1167
1276
|
|
|
1168
1277
|
async fetchArchetypesFromDB(
|
|
1169
1278
|
combinationString: string,
|
|
1170
|
-
gender: Gender,
|
|
1279
|
+
gender: Gender | null, // null to fetch both genders
|
|
1171
1280
|
language: string
|
|
1172
1281
|
) {
|
|
1173
1282
|
await this.log('debug', 'Executing fetchArchetypesFromDB', {
|
|
@@ -1176,20 +1285,23 @@ export class ArchetypeService {
|
|
|
1176
1285
|
language,
|
|
1177
1286
|
});
|
|
1178
1287
|
const db = this.context.drizzle();
|
|
1288
|
+
const conditions = [
|
|
1289
|
+
eq(schema.archetypesData.combination, combinationString),
|
|
1290
|
+
eq(schema.archetypesData.language, language),
|
|
1291
|
+
];
|
|
1292
|
+
if (gender) {
|
|
1293
|
+
conditions.push(eq(schema.archetypesData.gender, gender));
|
|
1294
|
+
}
|
|
1179
1295
|
const result = await db
|
|
1180
1296
|
.select()
|
|
1181
1297
|
.from(schema.archetypesData)
|
|
1182
|
-
.where(
|
|
1183
|
-
|
|
1184
|
-
eq(schema.archetypesData.combination, combinationString),
|
|
1185
|
-
eq(schema.archetypesData.gender, gender),
|
|
1186
|
-
eq(schema.archetypesData.language, language)
|
|
1187
|
-
)
|
|
1188
|
-
)
|
|
1298
|
+
.where(and(...conditions))
|
|
1299
|
+
.orderBy(schema.archetypesData.archetypeIndex)
|
|
1189
1300
|
.execute();
|
|
1190
1301
|
await this.log('debug', 'fetchArchetypesFromDB result', {
|
|
1191
1302
|
resultCount: result.length,
|
|
1192
|
-
result,
|
|
1303
|
+
indexes: result.map((r) => r.archetypeIndex),
|
|
1304
|
+
genders: result.map((r) => r.gender),
|
|
1193
1305
|
});
|
|
1194
1306
|
return result;
|
|
1195
1307
|
}
|