@zodic/shared 0.0.293 → 0.0.295
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 +240 -1
- package/app/workflow/ArchetypeWorkflow.ts +27 -0
- package/db/migrations/0012_sudden_doctor_spectrum.sql +27 -0
- package/db/migrations/meta/0012_snapshot.json +2602 -0
- package/db/migrations/meta/_journal.json +7 -0
- package/db/schema.ts +1 -1
- package/package.json +1 -1
- package/types/scopes/generic.ts +14 -8
- package/utils/archetypeNamesMessages.ts +188 -46
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { eq } from 'drizzle-orm';
|
|
1
2
|
import { inject, injectable } from 'inversify';
|
|
2
|
-
import {
|
|
3
|
+
import { ChatMessages, schema } from '../..';
|
|
4
|
+
import { KVArchetype, ZodiacSignSlug } from '../../types/scopes/legacy';
|
|
5
|
+
import { generateArchetypePrompt } from '../../utils/archetypeNamesMessages';
|
|
3
6
|
import { buildCosmicMirrorArchetypeKVKey } from '../../utils/KVKeysBuilders';
|
|
4
7
|
import { AppContext } from '../base';
|
|
5
8
|
|
|
@@ -281,4 +284,240 @@ export class ArchetypeService {
|
|
|
281
284
|
})
|
|
282
285
|
);
|
|
283
286
|
}
|
|
287
|
+
|
|
288
|
+
async generateArchetypeNames(
|
|
289
|
+
combination: string,
|
|
290
|
+
gender: 'male' | 'female' | 'non-binary',
|
|
291
|
+
overrideExisting: boolean = false
|
|
292
|
+
) {
|
|
293
|
+
const [sun, ascendant, moon] = combination.split('-') as ZodiacSignSlug[];
|
|
294
|
+
|
|
295
|
+
const prompt = generateArchetypePrompt([{ sun, ascendant, moon }]);
|
|
296
|
+
const messages: ChatMessages = [
|
|
297
|
+
{
|
|
298
|
+
role: 'user',
|
|
299
|
+
content: prompt,
|
|
300
|
+
},
|
|
301
|
+
];
|
|
302
|
+
const response = await this.context.api().callTogether.single(messages, {});
|
|
303
|
+
|
|
304
|
+
if (!response) {
|
|
305
|
+
throw new Error(
|
|
306
|
+
`No response when generating archetype names for ${combination}`
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
const blocks = response
|
|
311
|
+
.split('-EN')[1]
|
|
312
|
+
.split('-PT')[0]
|
|
313
|
+
.trim()
|
|
314
|
+
.split(/\n\d\.\s*\n?/)
|
|
315
|
+
.filter(Boolean);
|
|
316
|
+
const ptBlocks = response
|
|
317
|
+
.split('-PT')[1]
|
|
318
|
+
.trim()
|
|
319
|
+
.split(/\n\d\.\s*\n?/)
|
|
320
|
+
.filter(Boolean);
|
|
321
|
+
|
|
322
|
+
const englishNames = blocks.map((block) => {
|
|
323
|
+
const nameMatch = block.match(/• Name:\s*(.+)/);
|
|
324
|
+
const essenceMatch = block.match(/• Essence:\s*(.+)/);
|
|
325
|
+
return {
|
|
326
|
+
name: nameMatch?.[1]?.trim() || '',
|
|
327
|
+
essenceLine: essenceMatch?.[1]?.trim() || '',
|
|
328
|
+
};
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
const portugueseVariants = ptBlocks.map((block) => {
|
|
332
|
+
const masc = block.match(/• Masculino:\s*(.+)/)?.[1]?.trim() || '';
|
|
333
|
+
const fem = block.match(/• Feminino:\s*(.+)/)?.[1]?.trim() || '';
|
|
334
|
+
const essence = block.match(/• Essência:\s*(.+)/)?.[1]?.trim() || '';
|
|
335
|
+
return { masc, fem, essenceLine: essence };
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
const db = this.context.drizzle();
|
|
339
|
+
|
|
340
|
+
await Promise.all(
|
|
341
|
+
englishNames.map(async (entry, i) => {
|
|
342
|
+
const index = (i + 1).toString();
|
|
343
|
+
const existingEntry = await db
|
|
344
|
+
.select({ id: schema.archetypesData.id })
|
|
345
|
+
.from(schema.archetypesData)
|
|
346
|
+
.where(
|
|
347
|
+
eq(schema.archetypesData.id, `${combination}:${gender}:${index}`)
|
|
348
|
+
)
|
|
349
|
+
.execute();
|
|
350
|
+
|
|
351
|
+
if (overrideExisting || existingEntry.length === 0) {
|
|
352
|
+
await db
|
|
353
|
+
.insert(schema.archetypesData)
|
|
354
|
+
.values({
|
|
355
|
+
id: `${combination}:${gender}:${index}`,
|
|
356
|
+
combination,
|
|
357
|
+
gender,
|
|
358
|
+
archetypeIndex: index,
|
|
359
|
+
language: 'en-us',
|
|
360
|
+
name: entry.name,
|
|
361
|
+
essenceLine: entry.essenceLine,
|
|
362
|
+
status: 'idle',
|
|
363
|
+
})
|
|
364
|
+
.onConflictDoUpdate({
|
|
365
|
+
target: [schema.archetypesData.id],
|
|
366
|
+
set: {
|
|
367
|
+
name: entry.name,
|
|
368
|
+
essenceLine: entry.essenceLine,
|
|
369
|
+
updatedAt: new Date().getTime(),
|
|
370
|
+
},
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
const existingEntryPt = await db
|
|
375
|
+
.select({ id: schema.archetypesData.id })
|
|
376
|
+
.from(schema.archetypesData)
|
|
377
|
+
.where(
|
|
378
|
+
eq(schema.archetypesData.id, `${combination}:${gender}:${index}:pt`)
|
|
379
|
+
)
|
|
380
|
+
.execute();
|
|
381
|
+
|
|
382
|
+
if (overrideExisting || existingEntryPt.length === 0) {
|
|
383
|
+
await db
|
|
384
|
+
.insert(schema.archetypesData)
|
|
385
|
+
.values({
|
|
386
|
+
id: `${combination}:${gender}:${index}:pt`,
|
|
387
|
+
combination,
|
|
388
|
+
gender,
|
|
389
|
+
archetypeIndex: index,
|
|
390
|
+
language: 'pt-br',
|
|
391
|
+
name: portugueseVariants[i].masc,
|
|
392
|
+
essenceLine: portugueseVariants[i].essenceLine,
|
|
393
|
+
status: 'idle',
|
|
394
|
+
})
|
|
395
|
+
.onConflictDoUpdate({
|
|
396
|
+
target: [schema.archetypesData.id],
|
|
397
|
+
set: {
|
|
398
|
+
name: portugueseVariants[i].masc,
|
|
399
|
+
essenceLine: portugueseVariants[i].essenceLine,
|
|
400
|
+
updatedAt: new Date().getTime(),
|
|
401
|
+
},
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
})
|
|
405
|
+
);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
async generateArchetypeNamesBatch(
|
|
409
|
+
entries: Array<{
|
|
410
|
+
combination: string;
|
|
411
|
+
gender: 'male' | 'female' | 'non-binary';
|
|
412
|
+
}>,
|
|
413
|
+
overrideExisting: boolean = false
|
|
414
|
+
) {
|
|
415
|
+
const prompts = entries.map(({ combination }) => {
|
|
416
|
+
const [sun, ascendant, moon] = combination.split('-') as ZodiacSignSlug[];
|
|
417
|
+
return { sun, ascendant, moon };
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
const prompt = generateArchetypePrompt(prompts);
|
|
421
|
+
const messages: ChatMessages = [{ role: 'user', content: prompt }];
|
|
422
|
+
const response = await this.context.api().callTogether.single(messages, {});
|
|
423
|
+
|
|
424
|
+
if (!response)
|
|
425
|
+
throw new Error('No response when generating batch archetype names');
|
|
426
|
+
|
|
427
|
+
const db = this.context.drizzle();
|
|
428
|
+
|
|
429
|
+
const blocks = response
|
|
430
|
+
.split(/Composition \d+/)
|
|
431
|
+
.slice(1)
|
|
432
|
+
.map((b) => b.trim());
|
|
433
|
+
|
|
434
|
+
for (let i = 0; i < entries.length; i++) {
|
|
435
|
+
const { combination, gender } = entries[i];
|
|
436
|
+
const block = blocks[i];
|
|
437
|
+
const en = block.split('-EN')[1].split('-PT')[0].trim();
|
|
438
|
+
const pt = block.split('-PT')[1].trim();
|
|
439
|
+
|
|
440
|
+
const english = en
|
|
441
|
+
.split(/\n\d\.\s*\n?/)
|
|
442
|
+
.filter(Boolean)
|
|
443
|
+
.map((line) => ({
|
|
444
|
+
name: line.match(/• Name:\s*(.+)/)?.[1]?.trim() || '',
|
|
445
|
+
essenceLine: line.match(/• Essence:\s*(.+)/)?.[1]?.trim() || '',
|
|
446
|
+
}));
|
|
447
|
+
|
|
448
|
+
const portuguese = pt
|
|
449
|
+
.split(/\n\d\.\s*\n?/)
|
|
450
|
+
.filter(Boolean)
|
|
451
|
+
.map((line) => ({
|
|
452
|
+
masc: line.match(/• Masculino:\s*(.+)/)?.[1]?.trim() || '',
|
|
453
|
+
essenceLine: line.match(/• Essência:\s*(.+)/)?.[1]?.trim() || '',
|
|
454
|
+
}));
|
|
455
|
+
|
|
456
|
+
for (let j = 0; j < 3; j++) {
|
|
457
|
+
const index = (j + 1).toString();
|
|
458
|
+
|
|
459
|
+
const existingEntry = await db
|
|
460
|
+
.select({ id: schema.archetypesData.id })
|
|
461
|
+
.from(schema.archetypesData)
|
|
462
|
+
.where(
|
|
463
|
+
eq(schema.archetypesData.id, `${combination}:${gender}:${index}`)
|
|
464
|
+
)
|
|
465
|
+
.execute();
|
|
466
|
+
|
|
467
|
+
if (overrideExisting || existingEntry.length === 0) {
|
|
468
|
+
await db
|
|
469
|
+
.insert(schema.archetypesData)
|
|
470
|
+
.values({
|
|
471
|
+
id: `${combination}:${gender}:${index}`,
|
|
472
|
+
combination,
|
|
473
|
+
gender,
|
|
474
|
+
archetypeIndex: index,
|
|
475
|
+
language: 'en-us',
|
|
476
|
+
name: english[j].name,
|
|
477
|
+
essenceLine: english[j].essenceLine,
|
|
478
|
+
status: 'idle',
|
|
479
|
+
})
|
|
480
|
+
.onConflictDoUpdate({
|
|
481
|
+
target: [schema.archetypesData.id],
|
|
482
|
+
set: {
|
|
483
|
+
name: english[j].name,
|
|
484
|
+
essenceLine: english[j].essenceLine,
|
|
485
|
+
updatedAt: new Date().getTime(),
|
|
486
|
+
},
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
const existingEntryPt = await db
|
|
491
|
+
.select({ id: schema.archetypesData.id })
|
|
492
|
+
.from(schema.archetypesData)
|
|
493
|
+
.where(
|
|
494
|
+
eq(schema.archetypesData.id, `${combination}:${gender}:${index}:pt`)
|
|
495
|
+
)
|
|
496
|
+
.execute();
|
|
497
|
+
|
|
498
|
+
if (overrideExisting || existingEntryPt.length === 0) {
|
|
499
|
+
await db
|
|
500
|
+
.insert(schema.archetypesData)
|
|
501
|
+
.values({
|
|
502
|
+
id: `${combination}:${gender}:${index}:pt`,
|
|
503
|
+
combination,
|
|
504
|
+
gender,
|
|
505
|
+
archetypeIndex: index,
|
|
506
|
+
language: 'pt-br',
|
|
507
|
+
name: portuguese[j].masc,
|
|
508
|
+
essenceLine: portuguese[j].essenceLine,
|
|
509
|
+
status: 'idle',
|
|
510
|
+
})
|
|
511
|
+
.onConflictDoUpdate({
|
|
512
|
+
target: [schema.archetypesData.id],
|
|
513
|
+
set: {
|
|
514
|
+
name: portuguese[j].masc,
|
|
515
|
+
essenceLine: portuguese[j].essenceLine,
|
|
516
|
+
updatedAt: new Date().getTime(),
|
|
517
|
+
},
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
}
|
|
284
523
|
}
|
|
@@ -87,6 +87,33 @@ export class ArchetypeWorkflow {
|
|
|
87
87
|
};
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
async generateNames({
|
|
91
|
+
combinations,
|
|
92
|
+
gender,
|
|
93
|
+
overrideExisting,
|
|
94
|
+
}: {
|
|
95
|
+
combinations: string[];
|
|
96
|
+
gender: Gender;
|
|
97
|
+
overrideExisting?: boolean;
|
|
98
|
+
}): Promise<void> {
|
|
99
|
+
if (combinations.length === 0) return;
|
|
100
|
+
|
|
101
|
+
if (combinations.length === 1) {
|
|
102
|
+
await this.archetypeService.generateArchetypeNames(
|
|
103
|
+
combinations[0],
|
|
104
|
+
gender,
|
|
105
|
+
overrideExisting
|
|
106
|
+
);
|
|
107
|
+
} else {
|
|
108
|
+
const entries = combinations.map((combination) => ({
|
|
109
|
+
combination,
|
|
110
|
+
gender,
|
|
111
|
+
}));
|
|
112
|
+
|
|
113
|
+
await this.archetypeService.generateArchetypeNamesBatch(entries, overrideExisting);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
90
117
|
/**
|
|
91
118
|
* Fetch all three archetypes from KV for a given combination and gender.
|
|
92
119
|
*/
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
PRAGMA foreign_keys=OFF;--> statement-breakpoint
|
|
2
|
+
CREATE TABLE `__new_archetypes_data` (
|
|
3
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
4
|
+
`language` text NOT NULL,
|
|
5
|
+
`gender` text,
|
|
6
|
+
`combination` text NOT NULL,
|
|
7
|
+
`archetype_index` text NOT NULL,
|
|
8
|
+
`name` text NOT NULL,
|
|
9
|
+
`essence_line` text NOT NULL,
|
|
10
|
+
`description` text,
|
|
11
|
+
`content` text DEFAULT '[]' NOT NULL,
|
|
12
|
+
`virtues` text DEFAULT '[]' NOT NULL,
|
|
13
|
+
`leonardo_prompt` text,
|
|
14
|
+
`status` text DEFAULT 'idle',
|
|
15
|
+
`created_at` integer DEFAULT CURRENT_TIMESTAMP,
|
|
16
|
+
`images` text DEFAULT '[]' NOT NULL,
|
|
17
|
+
`updated_at` integer DEFAULT CURRENT_TIMESTAMP
|
|
18
|
+
);
|
|
19
|
+
--> statement-breakpoint
|
|
20
|
+
INSERT INTO `__new_archetypes_data`("id", "language", "gender", "combination", "archetype_index", "name", "essence_line", "description", "content", "virtues", "leonardo_prompt", "status", "created_at", "images", "updated_at") SELECT "id", "language", "gender", "combination", "archetype_index", "name", "essence_line", "description", "content", "virtues", "leonardo_prompt", "status", "created_at", "images", "updated_at" FROM `archetypes_data`;--> statement-breakpoint
|
|
21
|
+
DROP TABLE `archetypes_data`;--> statement-breakpoint
|
|
22
|
+
ALTER TABLE `__new_archetypes_data` RENAME TO `archetypes_data`;--> statement-breakpoint
|
|
23
|
+
PRAGMA foreign_keys=ON;--> statement-breakpoint
|
|
24
|
+
CREATE INDEX `archetypes_data_language_idx` ON `archetypes_data` (`language`);--> statement-breakpoint
|
|
25
|
+
CREATE INDEX `archetypes_data_combination_idx` ON `archetypes_data` (`combination`);--> statement-breakpoint
|
|
26
|
+
CREATE INDEX `archetypes_data_archetype_index_idx` ON `archetypes_data` (`archetype_index`);--> statement-breakpoint
|
|
27
|
+
CREATE INDEX `archetypes_data_gender_idx` ON `archetypes_data` (`gender`);
|