@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
|
@@ -2,7 +2,6 @@ import { eq } from 'drizzle-orm';
|
|
|
2
2
|
import { inject, injectable } from 'inversify';
|
|
3
3
|
import 'reflect-metadata';
|
|
4
4
|
import { schema } from '../..';
|
|
5
|
-
import { Gender } from '../../types';
|
|
6
5
|
import { AppContext } from '../base/AppContext';
|
|
7
6
|
|
|
8
7
|
interface QueueMessage {
|
|
@@ -48,12 +47,11 @@ export class LeonardoService {
|
|
|
48
47
|
/**
|
|
49
48
|
* Processes a message from ARCHETYPE_POPULATION_QUEUE to ensure the archetype has three images.
|
|
50
49
|
*/
|
|
51
|
-
async processArchetypePopulation(
|
|
52
|
-
const { archetypeDataId } = message;
|
|
50
|
+
async processArchetypePopulation(archetypeDataId: string): Promise<void> {
|
|
53
51
|
await this.log('info', 'Processing archetype population', {
|
|
54
52
|
archetypeDataId,
|
|
55
53
|
});
|
|
56
|
-
|
|
54
|
+
|
|
57
55
|
const db = this.context.drizzle();
|
|
58
56
|
const archetype = await db
|
|
59
57
|
.select({
|
|
@@ -69,14 +67,21 @@ export class LeonardoService {
|
|
|
69
67
|
.where(eq(schema.archetypesData.id, archetypeDataId))
|
|
70
68
|
.limit(1)
|
|
71
69
|
.execute();
|
|
72
|
-
|
|
70
|
+
|
|
73
71
|
if (!archetype[0]) {
|
|
74
72
|
await this.log('error', 'Archetype not found', { archetypeDataId });
|
|
75
73
|
throw new Error(`Archetype not found: ${archetypeDataId}`);
|
|
76
74
|
}
|
|
77
|
-
|
|
78
|
-
const {
|
|
79
|
-
|
|
75
|
+
|
|
76
|
+
const {
|
|
77
|
+
combination,
|
|
78
|
+
gender,
|
|
79
|
+
language,
|
|
80
|
+
archetypeIndex,
|
|
81
|
+
leonardoPrompt,
|
|
82
|
+
images,
|
|
83
|
+
} = archetype[0];
|
|
84
|
+
|
|
80
85
|
await this.log('info', 'Fetched archetype details', {
|
|
81
86
|
archetypeDataId,
|
|
82
87
|
combination,
|
|
@@ -84,7 +89,7 @@ export class LeonardoService {
|
|
|
84
89
|
language,
|
|
85
90
|
archetypeIndex,
|
|
86
91
|
});
|
|
87
|
-
|
|
92
|
+
|
|
88
93
|
const parsedImages = JSON.parse(images || '[]');
|
|
89
94
|
if (parsedImages.length >= 3) {
|
|
90
95
|
await this.log('info', 'Archetype already has sufficient images', {
|
|
@@ -93,7 +98,7 @@ export class LeonardoService {
|
|
|
93
98
|
});
|
|
94
99
|
return;
|
|
95
100
|
}
|
|
96
|
-
|
|
101
|
+
|
|
97
102
|
if (!leonardoPrompt) {
|
|
98
103
|
await this.log('error', 'Missing Leonardo prompt for archetype', {
|
|
99
104
|
archetypeDataId,
|
|
@@ -102,21 +107,21 @@ export class LeonardoService {
|
|
|
102
107
|
`Missing Leonardo prompt for archetype: ${archetypeDataId}`
|
|
103
108
|
);
|
|
104
109
|
}
|
|
105
|
-
|
|
110
|
+
|
|
106
111
|
await this.log('debug', 'Generating images for archetype', {
|
|
107
112
|
archetypeDataId,
|
|
108
113
|
prompt: leonardoPrompt,
|
|
109
114
|
});
|
|
110
|
-
|
|
115
|
+
|
|
111
116
|
const generationResponse = await this.context
|
|
112
117
|
.api()
|
|
113
118
|
.callLeonardo.generateImage({
|
|
114
119
|
prompt: leonardoPrompt,
|
|
115
120
|
width: 512,
|
|
116
121
|
height: 640,
|
|
117
|
-
quantity: 3 - parsedImages.length,
|
|
122
|
+
// quantity: 3 - parsedImages.length,
|
|
118
123
|
});
|
|
119
|
-
|
|
124
|
+
|
|
120
125
|
const generationId = generationResponse.sdGenerationJob.generationId;
|
|
121
126
|
if (!generationId) {
|
|
122
127
|
await this.log(
|
|
@@ -126,7 +131,7 @@ export class LeonardoService {
|
|
|
126
131
|
);
|
|
127
132
|
throw new Error('Leonardo generation failed to return a valid ID');
|
|
128
133
|
}
|
|
129
|
-
|
|
134
|
+
|
|
130
135
|
await db.insert(schema.generations).values({
|
|
131
136
|
id: generationId,
|
|
132
137
|
archetypeIndex: parseInt(archetypeIndex),
|
|
@@ -136,7 +141,7 @@ export class LeonardoService {
|
|
|
136
141
|
gender,
|
|
137
142
|
createdAt: new Date(),
|
|
138
143
|
});
|
|
139
|
-
|
|
144
|
+
|
|
140
145
|
await this.log('info', 'Queued image generation', {
|
|
141
146
|
generationId,
|
|
142
147
|
archetypeDataId,
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import { and, eq } from 'drizzle-orm';
|
|
2
1
|
import { inject, injectable } from 'inversify';
|
|
3
|
-
import { schema } from '../..';
|
|
4
|
-
import { Gender } from '../../types';
|
|
5
2
|
import { AppContext } from '../base';
|
|
6
|
-
import {
|
|
7
|
-
import { LeonardoService } from '
|
|
3
|
+
import { Gender, Languages } from '../../types';
|
|
4
|
+
import { ArchetypeService, LeonardoService, schema } from '../..';
|
|
5
|
+
import { and, eq } from 'drizzle-orm';
|
|
8
6
|
|
|
9
7
|
@injectable()
|
|
10
8
|
export class ArchetypeWorkflow {
|
|
@@ -19,266 +17,210 @@ export class ArchetypeWorkflow {
|
|
|
19
17
|
message: string,
|
|
20
18
|
context: Record<string, any> = {}
|
|
21
19
|
) {
|
|
22
|
-
const logId = `archetype-workflow:${Date.now()}`;
|
|
23
20
|
const logMessage = `[${new Date().toISOString()}] [${level.toUpperCase()}] ${message}`;
|
|
24
|
-
|
|
25
21
|
console[level](logMessage, context);
|
|
26
|
-
const db = this.context.drizzle();
|
|
27
|
-
try {
|
|
28
|
-
await db
|
|
29
|
-
.insert(schema.logs)
|
|
30
|
-
.values({
|
|
31
|
-
id: logId,
|
|
32
|
-
level,
|
|
33
|
-
message,
|
|
34
|
-
context: JSON.stringify(context),
|
|
35
|
-
createdAt: new Date().getTime(),
|
|
36
|
-
})
|
|
37
|
-
.execute();
|
|
38
|
-
} catch (error) {
|
|
39
|
-
console.error('[ERROR] Failed to persist log to database:', {
|
|
40
|
-
error,
|
|
41
|
-
logId,
|
|
42
|
-
message,
|
|
43
|
-
context,
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
22
|
}
|
|
47
23
|
|
|
48
24
|
async execute(
|
|
49
25
|
combinationString: string,
|
|
50
26
|
gender: Gender,
|
|
51
|
-
language:
|
|
52
|
-
override: boolean = false
|
|
27
|
+
language: Languages,
|
|
28
|
+
override: boolean = false,
|
|
29
|
+
userId?: string
|
|
53
30
|
) {
|
|
54
|
-
await this.log('info', 'Starting ArchetypeWorkflow', {
|
|
31
|
+
await this.log('info', 'Starting ArchetypeWorkflow.execute', {
|
|
55
32
|
combinationString,
|
|
56
33
|
gender,
|
|
57
34
|
language,
|
|
58
35
|
override,
|
|
36
|
+
userId,
|
|
59
37
|
});
|
|
60
38
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
combinationString,
|
|
64
|
-
|
|
65
|
-
language
|
|
66
|
-
);
|
|
67
|
-
await this.log('info', 'Fetched existing archetypes', {
|
|
68
|
-
archetypesCount: archetypes.length,
|
|
69
|
-
archetypeIds: archetypes.map((a) => a.id),
|
|
70
|
-
});
|
|
39
|
+
try {
|
|
40
|
+
// Step 1: Generate archetype names for both genders
|
|
41
|
+
await this.log('debug', 'Generating archetype names', { combinationString, override, userId });
|
|
42
|
+
await this.archetypeService.generateArchetypeNames(combinationString, override);
|
|
71
43
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
override ||
|
|
75
|
-
archetypes.length === 0 ||
|
|
76
|
-
archetypes.some((a) => !a.name || !a.essenceLine)
|
|
77
|
-
) {
|
|
78
|
-
await this.log('info', 'Generating or updating archetype names', {
|
|
44
|
+
// Step 2: Generate descriptions and virtues for both genders
|
|
45
|
+
await this.log('debug', 'Generating descriptions and virtues', {
|
|
79
46
|
combinationString,
|
|
80
47
|
gender,
|
|
81
48
|
language,
|
|
82
49
|
override,
|
|
50
|
+
userId,
|
|
83
51
|
});
|
|
84
|
-
await this.archetypeService.
|
|
52
|
+
const descriptions = await this.archetypeService.generateDescriptionsAndVirtues(
|
|
85
53
|
combinationString,
|
|
54
|
+
gender, // Service processes both genders internally
|
|
55
|
+
language,
|
|
86
56
|
override
|
|
87
57
|
);
|
|
88
|
-
archetypes = await this.archetypeService.fetchArchetypesFromDB(
|
|
89
|
-
combinationString,
|
|
90
|
-
gender,
|
|
91
|
-
language
|
|
92
|
-
);
|
|
93
|
-
await this.log('info', 'Refetched archetypes after name generation', {
|
|
94
|
-
archetypesCount: archetypes.length,
|
|
95
|
-
archetypeIds: archetypes.map((a) => a.id),
|
|
96
|
-
});
|
|
97
|
-
} else {
|
|
98
|
-
await this.log('info', 'Skipping archetype names generation', {
|
|
99
|
-
reason: 'Names and essence lines already exist',
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
58
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
if (
|
|
106
|
-
override ||
|
|
107
|
-
archetypes.some((a) => !a.description || a.virtues === '[]')
|
|
108
|
-
) {
|
|
109
|
-
await this.log('info', 'Generating or updating descriptions and virtues', {
|
|
59
|
+
// Step 3: Generate content for both genders
|
|
60
|
+
await this.log('debug', 'Generating content', {
|
|
110
61
|
combinationString,
|
|
111
62
|
gender,
|
|
112
63
|
language,
|
|
113
64
|
override,
|
|
65
|
+
userId,
|
|
114
66
|
});
|
|
115
|
-
|
|
67
|
+
await this.archetypeService.generateContent(
|
|
116
68
|
combinationString,
|
|
117
|
-
gender,
|
|
69
|
+
gender, // Service processes both genders internally
|
|
118
70
|
language,
|
|
71
|
+
descriptions,
|
|
119
72
|
override
|
|
120
73
|
);
|
|
121
|
-
archetypes = await this.archetypeService.fetchArchetypesFromDB(
|
|
122
|
-
combinationString,
|
|
123
|
-
gender,
|
|
124
|
-
language
|
|
125
|
-
);
|
|
126
|
-
await this.log('info', 'Refetched archetypes after descriptions and virtues', {
|
|
127
|
-
archetypesCount: archetypes.length,
|
|
128
|
-
archetypeIds: archetypes.map((a) => a.id),
|
|
129
|
-
});
|
|
130
|
-
} else {
|
|
131
|
-
await this.log('info', 'Skipping descriptions and virtues generation', {
|
|
132
|
-
reason: 'Descriptions and virtues already exist',
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
74
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
await this.log('info', 'Generating or updating content', {
|
|
75
|
+
// Step 4: Generate Leonardo prompts for both genders
|
|
76
|
+
await this.log('debug', 'Generating Leonardo prompts', {
|
|
139
77
|
combinationString,
|
|
140
78
|
gender,
|
|
141
79
|
language,
|
|
142
80
|
override,
|
|
81
|
+
userId,
|
|
143
82
|
});
|
|
144
|
-
await this.archetypeService.
|
|
83
|
+
await this.archetypeService.generateLeonardoPrompts(
|
|
145
84
|
combinationString,
|
|
146
|
-
gender,
|
|
85
|
+
gender, // Service processes both genders internally
|
|
147
86
|
language,
|
|
148
|
-
|
|
87
|
+
descriptions,
|
|
149
88
|
override
|
|
150
89
|
);
|
|
151
|
-
archetypes = await this.archetypeService.fetchArchetypesFromDB(
|
|
152
|
-
combinationString,
|
|
153
|
-
gender,
|
|
154
|
-
language
|
|
155
|
-
);
|
|
156
|
-
await this.log('info', 'Refetched archetypes after content generation', {
|
|
157
|
-
archetypesCount: archetypes.length,
|
|
158
|
-
archetypeIds: archetypes.map((a) => a.id),
|
|
159
|
-
});
|
|
160
|
-
} else {
|
|
161
|
-
await this.log('info', 'Skipping content generation', {
|
|
162
|
-
reason: 'Content already exists',
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
90
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
await this.log('info', 'Generating or updating Leonardo prompts', {
|
|
91
|
+
// Step 5: Fetch archetypes for the requested gender only for image generation
|
|
92
|
+
await this.log('debug', 'Fetching archetypes for image generation', {
|
|
169
93
|
combinationString,
|
|
170
94
|
gender,
|
|
171
95
|
language,
|
|
172
|
-
|
|
96
|
+
userId,
|
|
173
97
|
});
|
|
174
|
-
await this.archetypeService.
|
|
98
|
+
const archetypes = await this.archetypeService.fetchArchetypesFromDB(
|
|
175
99
|
combinationString,
|
|
176
|
-
gender,
|
|
177
|
-
language,
|
|
178
|
-
descVirtues,
|
|
179
|
-
override
|
|
180
|
-
);
|
|
181
|
-
archetypes = await this.archetypeService.fetchArchetypesFromDB(
|
|
182
|
-
combinationString,
|
|
183
|
-
gender,
|
|
100
|
+
gender, // Fetch only the requested gender
|
|
184
101
|
language
|
|
185
102
|
);
|
|
186
|
-
await this.log('info', 'Refetched archetypes after Leonardo prompts', {
|
|
187
|
-
archetypesCount: archetypes.length,
|
|
188
|
-
archetypeIds: archetypes.map((a) => a.id),
|
|
189
|
-
});
|
|
190
|
-
} else {
|
|
191
|
-
await this.log('info', 'Skipping Leonardo prompts generation', {
|
|
192
|
-
reason: 'Leonardo prompts already exist',
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
103
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
104
|
+
if (archetypes.length !== 3) {
|
|
105
|
+
await this.log('error', `Expected 3 archetypes for ${gender}, found ${archetypes.length}`, {
|
|
106
|
+
combinationString,
|
|
107
|
+
gender,
|
|
108
|
+
language,
|
|
109
|
+
userId,
|
|
110
|
+
});
|
|
111
|
+
throw new Error(
|
|
112
|
+
`Expected 3 archetypes for combination ${combinationString}, gender ${gender}, language ${language}, but found ${archetypes.length}`
|
|
113
|
+
);
|
|
114
|
+
}
|
|
200
115
|
|
|
201
|
-
|
|
202
|
-
await this.log('info',
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
116
|
+
// Step 6: Process image generation only for the requested gender
|
|
117
|
+
await this.log('info', `Processing image generation for gender ${gender}`, {
|
|
118
|
+
archetypeIds: archetypes.map((a) => a.id),
|
|
119
|
+
archetypeIndexes: archetypes.map((a) => a.archetypeIndex),
|
|
120
|
+
userId,
|
|
121
|
+
});
|
|
122
|
+
for (const archetype of archetypes) {
|
|
123
|
+
if (!archetype.leonardoPrompt) {
|
|
124
|
+
await this.log('warn', `No Leonardo prompt for archetype ${archetype.id}`, {
|
|
125
|
+
archetypeIndex: archetype.archetypeIndex,
|
|
126
|
+
gender,
|
|
127
|
+
language,
|
|
128
|
+
userId,
|
|
129
|
+
});
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
206
132
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
133
|
+
if (override || !archetype.images || archetype.images === '[]') {
|
|
134
|
+
await this.log('debug', `Queueing image generation for archetype ${archetype.id}`, {
|
|
135
|
+
archetypeIndex: archetype.archetypeIndex,
|
|
136
|
+
gender,
|
|
137
|
+
language,
|
|
138
|
+
userId,
|
|
139
|
+
});
|
|
140
|
+
await this.leonardoService.processArchetypePopulation(archetype.id);
|
|
141
|
+
} else {
|
|
142
|
+
await this.log('debug', `Skipping image generation for archetype ${archetype.id}`, {
|
|
143
|
+
reason: 'Images already exist and override is false',
|
|
144
|
+
archetypeIndex: archetype.archetypeIndex,
|
|
145
|
+
gender,
|
|
146
|
+
language,
|
|
147
|
+
userId,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
212
151
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
152
|
+
// Step 7: Update status to 'completed' for archetypes with at least 3 images
|
|
153
|
+
await this.log('debug', 'Updating status for archetypes with images', {
|
|
154
|
+
combinationString,
|
|
155
|
+
gender,
|
|
156
|
+
language,
|
|
157
|
+
userId,
|
|
158
|
+
});
|
|
159
|
+
const db = this.context.drizzle();
|
|
160
|
+
for (const archetype of archetypes) {
|
|
161
|
+
let imageCount = 0;
|
|
162
|
+
try {
|
|
163
|
+
const images = archetype.images ? JSON.parse(archetype.images) : [];
|
|
164
|
+
imageCount = Array.isArray(images) ? images.length : 0;
|
|
165
|
+
} catch (error) {
|
|
166
|
+
await this.log('warn', `Failed to parse images for archetype ${archetype.id}`, {
|
|
167
|
+
archetypeIndex: archetype.archetypeIndex,
|
|
168
|
+
gender,
|
|
169
|
+
language,
|
|
170
|
+
userId,
|
|
171
|
+
error: error instanceof Error ? error.message : String(error),
|
|
172
|
+
});
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (imageCount >= 3) {
|
|
177
|
+
await db
|
|
216
178
|
.update(schema.archetypesData)
|
|
217
179
|
.set({
|
|
218
|
-
|
|
219
|
-
status: 'idle',
|
|
180
|
+
status: 'completed',
|
|
220
181
|
updatedAt: new Date().getTime(),
|
|
221
182
|
})
|
|
222
|
-
.where(
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
183
|
+
.where(
|
|
184
|
+
and(
|
|
185
|
+
eq(schema.archetypesData.id, archetype.id),
|
|
186
|
+
eq(schema.archetypesData.gender, gender),
|
|
187
|
+
eq(schema.archetypesData.language, language),
|
|
188
|
+
eq(schema.archetypesData.archetypeIndex, archetype.archetypeIndex)
|
|
189
|
+
)
|
|
190
|
+
);
|
|
191
|
+
await this.log('info', `Updated status to 'completed' for archetype ${archetype.id}`, {
|
|
192
|
+
archetypeIndex: archetype.archetypeIndex,
|
|
193
|
+
gender,
|
|
194
|
+
language,
|
|
195
|
+
imageCount,
|
|
196
|
+
userId,
|
|
197
|
+
});
|
|
198
|
+
} else {
|
|
199
|
+
await this.log('debug', `Skipping status update for archetype ${archetype.id}`, {
|
|
200
|
+
reason: `Fewer than 3 images (found ${imageCount})`,
|
|
201
|
+
archetypeIndex: archetype.archetypeIndex,
|
|
202
|
+
gender,
|
|
203
|
+
language,
|
|
204
|
+
userId,
|
|
226
205
|
});
|
|
227
206
|
}
|
|
228
|
-
|
|
229
|
-
// Process image generation directly
|
|
230
|
-
await this.leonardoService.processArchetypePopulation({
|
|
231
|
-
archetypeDataId: archetype.id,
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
// Note: processArchetypePopulation sets status to 'pending' in the generations table
|
|
235
|
-
// Update archetype status to 'pending' for consistency
|
|
236
|
-
await this.context.drizzle()
|
|
237
|
-
.update(schema.archetypesData)
|
|
238
|
-
.set({
|
|
239
|
-
status: 'pending',
|
|
240
|
-
updatedAt: new Date().getTime(),
|
|
241
|
-
})
|
|
242
|
-
.where(eq(schema.archetypesData.id, archetype.id))
|
|
243
|
-
.execute();
|
|
244
207
|
}
|
|
245
208
|
|
|
246
|
-
await this.log('info', '
|
|
247
|
-
|
|
209
|
+
await this.log('info', 'Completed ArchetypeWorkflow.execute', {
|
|
210
|
+
combinationString,
|
|
211
|
+
gender,
|
|
212
|
+
language,
|
|
213
|
+
userId,
|
|
248
214
|
});
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
if (incompleteArchetypes.length > 0) {
|
|
257
|
-
await this.log('warn', 'Some archetypes are not complete', {
|
|
258
|
-
incompleteArchetypeIds: incompleteArchetypes.map((a) => a.id),
|
|
259
|
-
statuses: incompleteArchetypes.map((a) => a.status),
|
|
215
|
+
} catch (error) {
|
|
216
|
+
await this.log('error', 'Error in ArchetypeWorkflow.execute', {
|
|
217
|
+
combinationString,
|
|
218
|
+
gender,
|
|
219
|
+
language,
|
|
220
|
+
userId,
|
|
221
|
+
error: error instanceof Error ? error.message : String(error),
|
|
260
222
|
});
|
|
261
|
-
|
|
262
|
-
message: 'Archetype generation is still in progress. Please try again later.',
|
|
263
|
-
};
|
|
223
|
+
throw error;
|
|
264
224
|
}
|
|
265
|
-
|
|
266
|
-
await this.log('info', 'All archetypes are complete', {
|
|
267
|
-
archetypesCount: archetypes.length,
|
|
268
|
-
archetypeIds: archetypes.map((a) => a.id),
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
return {
|
|
272
|
-
archetypes: archetypes.map(
|
|
273
|
-
({ id, name, essenceLine, description, virtues, images }) => ({
|
|
274
|
-
id,
|
|
275
|
-
name,
|
|
276
|
-
essenceLine,
|
|
277
|
-
description,
|
|
278
|
-
virtues: JSON.parse(virtues),
|
|
279
|
-
images: JSON.parse(images),
|
|
280
|
-
})
|
|
281
|
-
),
|
|
282
|
-
};
|
|
283
225
|
}
|
|
284
226
|
}
|
package/package.json
CHANGED
package/types/scopes/generic.ts
CHANGED
|
@@ -31,7 +31,7 @@ export type PlacementType =
|
|
|
31
31
|
| 'karmic_point'
|
|
32
32
|
| 'arabic_part';
|
|
33
33
|
|
|
34
|
-
export const VALID_GENDERS_ARRAY = ['male', 'female'
|
|
34
|
+
export const VALID_GENDERS_ARRAY = ['male', 'female'] as const;
|
|
35
35
|
|
|
36
36
|
export type Gender = (typeof VALID_GENDERS_ARRAY)[number];
|
|
37
37
|
|
package/utils/buildMessages.ts
CHANGED
|
@@ -25,7 +25,7 @@ export const buildLLMMessages = (env: BackendBindings) => ({
|
|
|
25
25
|
content: `
|
|
26
26
|
You are a gifted fantasy writer and astrologer. Your task is to write mystical **narrative descriptions** and **core virtues** for three archetypes, based on their names, essence lines, and astrological combination.
|
|
27
27
|
|
|
28
|
-
Each archetype is influenced by the zodiac combination (Sun, Ascendant, Moon), and each one emphasizes one of those signs respectively.
|
|
28
|
+
Each archetype is influenced by the zodiac combination (Sun, Ascendant, Moon), and each one emphasizes one of those signs respectively. The signs and the archetype name should not be mentioned in the description. Use only their abstract representation and symbolism.
|
|
29
29
|
|
|
30
30
|
Please provide:
|
|
31
31
|
|