@zodic/shared 0.0.76 → 0.0.78
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.
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { inject, injectable } from 'inversify';
|
|
2
|
+
import 'reflect-metadata';
|
|
3
|
+
import { schema } from '../..';
|
|
4
|
+
import { Gender, VALID_GENDERS_ARRAY } from '../../types';
|
|
5
|
+
import {
|
|
6
|
+
KVArchetype,
|
|
7
|
+
LeonardoGenerateImageResponse,
|
|
8
|
+
sizes,
|
|
9
|
+
} from '../../types/scopes/legacy';
|
|
10
|
+
import { buildCosmicMirrorArchetypeKVKey } from '../../utils/KVKeysBuilders';
|
|
11
|
+
import { AppContext } from '../base/AppContext';
|
|
12
|
+
|
|
13
|
+
@injectable()
|
|
14
|
+
export class LeonardoService {
|
|
15
|
+
constructor(@inject(AppContext) private context: AppContext) {}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Processes and generates missing Leonardo prompts for archetypes.
|
|
19
|
+
*/
|
|
20
|
+
async processArchetypesPrompts(crown: string): Promise<void> {
|
|
21
|
+
console.log(`Processing Leonardo prompts for crown: ${crown}`);
|
|
22
|
+
|
|
23
|
+
const promptsToGenerate: Array<{
|
|
24
|
+
kvKey: string;
|
|
25
|
+
name: string;
|
|
26
|
+
visualDescription: string;
|
|
27
|
+
}> = [];
|
|
28
|
+
|
|
29
|
+
// Fetch archetypes that need prompts
|
|
30
|
+
for (const gender of VALID_GENDERS_ARRAY) {
|
|
31
|
+
for (let index = 1; index <= 3; index++) {
|
|
32
|
+
const kvKey = buildCosmicMirrorArchetypeKVKey(
|
|
33
|
+
'en-us',
|
|
34
|
+
crown,
|
|
35
|
+
gender,
|
|
36
|
+
index
|
|
37
|
+
);
|
|
38
|
+
console.log(`Fetching archetype from KV: ${kvKey}`);
|
|
39
|
+
|
|
40
|
+
const kvData = await this.context
|
|
41
|
+
.kvCosmicMirrorArchetypesStore()
|
|
42
|
+
.get<KVArchetype>(kvKey, 'json');
|
|
43
|
+
if (kvData && !kvData.leonardoPrompt) {
|
|
44
|
+
promptsToGenerate.push({
|
|
45
|
+
kvKey,
|
|
46
|
+
name: kvData.name,
|
|
47
|
+
visualDescription: kvData.visualDescription,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (promptsToGenerate.length === 0) {
|
|
54
|
+
console.log('No archetype prompts need to be generated.');
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
console.log('Archetypes requiring prompt generation:', promptsToGenerate);
|
|
59
|
+
|
|
60
|
+
// Generate prompts
|
|
61
|
+
const archetypes = promptsToGenerate.map(({ name, visualDescription }) => ({
|
|
62
|
+
name,
|
|
63
|
+
visualDescription,
|
|
64
|
+
}));
|
|
65
|
+
const leonardoPrompts =
|
|
66
|
+
await this.generateCosmicMirrorArchetypesLeonardoPrompts(archetypes);
|
|
67
|
+
|
|
68
|
+
if (leonardoPrompts.length !== archetypes.length) {
|
|
69
|
+
throw new Error('Mismatch between archetypes and generated prompts.');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Update KV with generated prompts
|
|
73
|
+
for (const [index, promptSet] of leonardoPrompts.entries()) {
|
|
74
|
+
const { kvKey } = promptsToGenerate[index];
|
|
75
|
+
console.log(`Updating KV with prompts for archetype: ${kvKey}`);
|
|
76
|
+
|
|
77
|
+
const kvData = await this.context
|
|
78
|
+
.kvCosmicMirrorArchetypesStore()
|
|
79
|
+
.get<KVArchetype>(kvKey, 'json');
|
|
80
|
+
if (!kvData) {
|
|
81
|
+
console.warn(`KV data not found for key: ${kvKey}. Skipping update.`);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
kvData.leonardoPrompt = promptSet;
|
|
86
|
+
await this.context
|
|
87
|
+
.kvCosmicMirrorArchetypesStore()
|
|
88
|
+
.put(kvKey, JSON.stringify(kvData));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
console.log(`Completed prompt processing for crown: ${crown}`);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Queues image generation for archetypes if no images exist.
|
|
96
|
+
*/
|
|
97
|
+
async queueImagesForArchetypes(crown: string, gender: Gender): Promise<void> {
|
|
98
|
+
console.log(
|
|
99
|
+
`Queuing image generation for crown: ${crown}, gender: ${gender}`
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
for (let index = 1; index <= 3; index++) {
|
|
103
|
+
const kvKey = buildCosmicMirrorArchetypeKVKey(
|
|
104
|
+
'en-us',
|
|
105
|
+
crown,
|
|
106
|
+
gender,
|
|
107
|
+
index
|
|
108
|
+
);
|
|
109
|
+
console.info(`Fetching KV for archetype: ${kvKey}`);
|
|
110
|
+
|
|
111
|
+
const kvData = await this.context
|
|
112
|
+
.kvCosmicMirrorArchetypesStore()
|
|
113
|
+
.get<KVArchetype>(kvKey, 'json');
|
|
114
|
+
if (!kvData || kvData.images.length >= 3) {
|
|
115
|
+
console.info(
|
|
116
|
+
`Skipping image generation for index ${index}, images already exist.`
|
|
117
|
+
);
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
console.info(`No images found. Queuing generation for index ${index}...`);
|
|
122
|
+
|
|
123
|
+
const generationResponse = await this.queueImageGeneration(
|
|
124
|
+
kvData.leonardoPrompt
|
|
125
|
+
);
|
|
126
|
+
const generationId = generationResponse.sdGenerationJob.generationId;
|
|
127
|
+
|
|
128
|
+
if (!generationId) {
|
|
129
|
+
throw new Error('Leonardo generation failed to return a valid ID.');
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
await this.context.drizzle().insert(schema.generations).values({
|
|
133
|
+
id: generationId,
|
|
134
|
+
archetypeIndex: index,
|
|
135
|
+
conceptCombinationId: null,
|
|
136
|
+
type: 'archetype_image',
|
|
137
|
+
status: 'pending',
|
|
138
|
+
createdAt: new Date(),
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
console.info(
|
|
142
|
+
`Queued generation ${generationId} for archetype index ${index}`
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Generates Leonardo prompts for archetypes.
|
|
149
|
+
*/
|
|
150
|
+
private async generateCosmicMirrorArchetypesLeonardoPrompts(
|
|
151
|
+
archetypes: Array<{ name: string; visualDescription: string }>
|
|
152
|
+
): Promise<string[]> {
|
|
153
|
+
console.log(`Generating Leonardo prompts for archetypes`);
|
|
154
|
+
|
|
155
|
+
const messages = this.context
|
|
156
|
+
.buildLLMMessages()
|
|
157
|
+
.generateCosmicMirrorArchetypesLeonardoPrompts(archetypes);
|
|
158
|
+
const response = await this.context.api().callDeepSeek.single(messages, {});
|
|
159
|
+
|
|
160
|
+
if (!response) {
|
|
161
|
+
throw new Error('Leonardo prompts not generated');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
console.log('Leonardo Prompts from API -> ', response);
|
|
165
|
+
|
|
166
|
+
return response
|
|
167
|
+
.split('\n')
|
|
168
|
+
.map((prompt) => prompt.trim())
|
|
169
|
+
.filter(Boolean);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Queues an image generation request to Leonardo.
|
|
174
|
+
*/
|
|
175
|
+
private async queueImageGeneration(
|
|
176
|
+
prompt: string
|
|
177
|
+
): Promise<LeonardoGenerateImageResponse> {
|
|
178
|
+
console.log(`Queuing Leonardo image generation...`);
|
|
179
|
+
|
|
180
|
+
const { width, height } = sizes['alchemy']['post4:5'];
|
|
181
|
+
|
|
182
|
+
try {
|
|
183
|
+
const response = await this.context
|
|
184
|
+
.api()
|
|
185
|
+
.callLeonardo.generateImage({ width, height, prompt });
|
|
186
|
+
if (!response) {
|
|
187
|
+
throw new Error('Leonardo image generation failed');
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
console.log('Leonardo Image Generation Response:', response);
|
|
191
|
+
return response;
|
|
192
|
+
} catch (error) {
|
|
193
|
+
console.error('Error queuing Leonardo image generation:', error);
|
|
194
|
+
throw error;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { inject, injectable } from 'inversify';
|
|
2
|
+
import { Gender } from '../../types';
|
|
3
|
+
import { KVArchetype } from '../../types/scopes/legacy';
|
|
4
|
+
import { buildCosmicMirrorArchetypeKVKey } from '../../utils/KVKeysBuilders';
|
|
5
|
+
import { AppContext } from '../base/AppContext';
|
|
6
|
+
import { ArchetypeService } from '../services/ArchetypeService';
|
|
7
|
+
import { LeonardoService } from '../services/LeonardoService';
|
|
8
|
+
|
|
9
|
+
@injectable()
|
|
10
|
+
export class ArchetypeWorkflow {
|
|
11
|
+
constructor(
|
|
12
|
+
@inject(AppContext) private context: AppContext,
|
|
13
|
+
@inject(ArchetypeService) private archetypeService: ArchetypeService,
|
|
14
|
+
@inject(LeonardoService) private leonardoService: LeonardoService
|
|
15
|
+
) {}
|
|
16
|
+
|
|
17
|
+
async execute(combinationString: string, gender: Gender) {
|
|
18
|
+
console.log('Starting ArchetypeWorkflow for:', {
|
|
19
|
+
combinationString,
|
|
20
|
+
gender,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const archetypes = await this.fetchArchetypesFromKV(
|
|
24
|
+
combinationString,
|
|
25
|
+
gender
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
if (archetypes.some((arc) => arc.status === 'generating')) {
|
|
29
|
+
console.log(
|
|
30
|
+
`Archetypes are already being processed for ${combinationString}, gender: ${gender}`
|
|
31
|
+
);
|
|
32
|
+
return { message: 'Images are being processed, please try again later.' };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (archetypes.some((arc) => !arc.name || arc.images.length < 3)) {
|
|
36
|
+
console.log(
|
|
37
|
+
`Generating missing basic info for: ${combinationString}, gender: ${gender}`
|
|
38
|
+
);
|
|
39
|
+
await this.archetypeService.generateBasicInfo(combinationString);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const updatedArchetypes = await this.fetchArchetypesFromKV(
|
|
43
|
+
combinationString,
|
|
44
|
+
gender
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
if (updatedArchetypes.some((arc) => !arc.leonardoPrompt)) {
|
|
48
|
+
console.log('Generating missing Leonardo prompts...');
|
|
49
|
+
await this.leonardoService.processArchetypesPrompts(combinationString);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const archetypesNeedingImages = updatedArchetypes.filter(
|
|
53
|
+
(arc) => arc.images.length < 3
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
if (archetypesNeedingImages.length > 0) {
|
|
57
|
+
console.log('Queuing image generation for missing archetypes...');
|
|
58
|
+
await this.updateArchetypeStatus(updatedArchetypes, 'generating', gender);
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
await this.leonardoService.queueImagesForArchetypes(
|
|
62
|
+
combinationString,
|
|
63
|
+
gender
|
|
64
|
+
);
|
|
65
|
+
} catch (error) {
|
|
66
|
+
console.error('Error queuing image generation:', error);
|
|
67
|
+
await this.updateArchetypeStatus(updatedArchetypes, 'idle', gender);
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return { message: 'Images are being processed, please try again later.' };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
await this.updateArchetypeStatus(updatedArchetypes, 'idle', gender);
|
|
75
|
+
|
|
76
|
+
console.log('Archetypes fully processed and ready:', updatedArchetypes);
|
|
77
|
+
return {
|
|
78
|
+
archetypes: updatedArchetypes.map(
|
|
79
|
+
({ name, content, description, virtues, images }) => ({
|
|
80
|
+
name,
|
|
81
|
+
content,
|
|
82
|
+
description,
|
|
83
|
+
virtues,
|
|
84
|
+
images,
|
|
85
|
+
})
|
|
86
|
+
),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Fetch all three archetypes from KV for a given combination and gender.
|
|
92
|
+
*/
|
|
93
|
+
private async fetchArchetypesFromKV(
|
|
94
|
+
combinationString: string,
|
|
95
|
+
gender: Gender
|
|
96
|
+
): Promise<KVArchetype[]> {
|
|
97
|
+
return Promise.all(
|
|
98
|
+
Array.from({ length: 3 }, (_, i) => i + 1).map(async (index) => {
|
|
99
|
+
const kvKey = buildCosmicMirrorArchetypeKVKey(
|
|
100
|
+
'en-us',
|
|
101
|
+
combinationString,
|
|
102
|
+
gender,
|
|
103
|
+
index
|
|
104
|
+
);
|
|
105
|
+
console.log(`Fetching archetype from KV: ${kvKey}`);
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
return (
|
|
109
|
+
(await this.context
|
|
110
|
+
.kvCosmicMirrorArchetypesStore()
|
|
111
|
+
.get<KVArchetype>(kvKey, 'json')) || this.createEmptyArchetype()
|
|
112
|
+
);
|
|
113
|
+
} catch (error) {
|
|
114
|
+
console.error(
|
|
115
|
+
`Error fetching archetype KV for index ${index}:`,
|
|
116
|
+
error
|
|
117
|
+
);
|
|
118
|
+
return this.createEmptyArchetype();
|
|
119
|
+
}
|
|
120
|
+
})
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Update the status of archetypes in KV.
|
|
126
|
+
*/
|
|
127
|
+
private async updateArchetypeStatus(
|
|
128
|
+
archetypes: KVArchetype[],
|
|
129
|
+
status: 'idle' | 'generating',
|
|
130
|
+
gender: Gender
|
|
131
|
+
): Promise<void> {
|
|
132
|
+
await Promise.all(
|
|
133
|
+
archetypes.map(async (archetype, index) => {
|
|
134
|
+
const kvKey = buildCosmicMirrorArchetypeKVKey(
|
|
135
|
+
'en-us',
|
|
136
|
+
archetype.name,
|
|
137
|
+
gender,
|
|
138
|
+
index + 1
|
|
139
|
+
);
|
|
140
|
+
archetype.status = status;
|
|
141
|
+
await this.context
|
|
142
|
+
.kvCosmicMirrorArchetypesStore()
|
|
143
|
+
.put(kvKey, JSON.stringify(archetype));
|
|
144
|
+
})
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Create an empty KVArchetype object when KV data is missing.
|
|
150
|
+
*/
|
|
151
|
+
private createEmptyArchetype(): KVArchetype {
|
|
152
|
+
return {
|
|
153
|
+
name: '',
|
|
154
|
+
description: '',
|
|
155
|
+
content: '',
|
|
156
|
+
leonardoPrompt: '',
|
|
157
|
+
visualDescription: '',
|
|
158
|
+
virtues: [],
|
|
159
|
+
images: [],
|
|
160
|
+
status: 'idle',
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
}
|
|
@@ -18,24 +18,28 @@ export class ConceptWorkflow {
|
|
|
18
18
|
switch (phase) {
|
|
19
19
|
case 'basic-info':
|
|
20
20
|
await this.conceptService.generateBasicInfo(
|
|
21
|
+
'en-us',
|
|
21
22
|
conceptSlug,
|
|
22
23
|
combinationString
|
|
23
24
|
);
|
|
24
25
|
break;
|
|
25
26
|
case 'content':
|
|
26
27
|
await this.conceptService.generateContent(
|
|
28
|
+
'en-us',
|
|
27
29
|
conceptSlug,
|
|
28
30
|
combinationString
|
|
29
31
|
);
|
|
30
32
|
break;
|
|
31
33
|
case 'leonardo-prompt':
|
|
32
34
|
await this.conceptService.generatePrompt(
|
|
35
|
+
'en-us',
|
|
33
36
|
conceptSlug,
|
|
34
37
|
combinationString
|
|
35
38
|
);
|
|
36
39
|
break;
|
|
37
40
|
case 'images':
|
|
38
41
|
await this.conceptService.generateImages(
|
|
42
|
+
'en-us',
|
|
39
43
|
conceptSlug,
|
|
40
44
|
combinationString
|
|
41
45
|
);
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { inject, injectable } from 'inversify';
|
|
2
|
+
import { Gender } from '../../../types';
|
|
3
|
+
import { KVArchetype } from '../../../types/scopes/legacy';
|
|
4
|
+
import { AppContext } from '../../base';
|
|
5
|
+
import { ArchetypeService } from '../../services/ArchetypeService';
|
|
6
|
+
import { LeonardoService } from '../../services/LeonardoService';
|
|
7
|
+
|
|
8
|
+
@injectable()
|
|
9
|
+
class ArchetypeWorkflow {
|
|
10
|
+
constructor(
|
|
11
|
+
@inject(AppContext) private context: AppContext,
|
|
12
|
+
@inject(ArchetypeService) private archetypeService: ArchetypeService,
|
|
13
|
+
@inject(LeonardoService) private leonardoService: LeonardoService
|
|
14
|
+
) {}
|
|
15
|
+
|
|
16
|
+
async execute(combinationString: string, gender: Gender) {
|
|
17
|
+
const kvKeyBase = `cosmic-mirror:archetypes:${combinationString}:${gender}`;
|
|
18
|
+
|
|
19
|
+
console.log('Starting ArchetypeWorkflow for:', {
|
|
20
|
+
combinationString,
|
|
21
|
+
gender,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const archetypes = await Promise.all(
|
|
25
|
+
Array.from({ length: 3 }, (_, i) => i + 1).map(async (index) => {
|
|
26
|
+
const kvKey = `${kvKeyBase}:${index}`;
|
|
27
|
+
try {
|
|
28
|
+
console.log(`Fetching archetype from KV: ${kvKey}`);
|
|
29
|
+
return await this.context
|
|
30
|
+
.kvCosmicMirrorArchetypesStore()
|
|
31
|
+
.get<KVArchetype>(kvKey, 'json');
|
|
32
|
+
} catch (error) {
|
|
33
|
+
console.error(
|
|
34
|
+
`Error fetching archetype KV for index ${index}:`,
|
|
35
|
+
error
|
|
36
|
+
);
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
).then((results) => results.filter((result) => result !== null)); // Filter out nulls
|
|
41
|
+
|
|
42
|
+
const isGenerating = archetypes.some(
|
|
43
|
+
(archetype) => archetype?.status === 'generating'
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
if (isGenerating) {
|
|
47
|
+
console.log(
|
|
48
|
+
`Archetype images are already being generated for: ${combinationString}, gender: ${gender}`
|
|
49
|
+
);
|
|
50
|
+
return { message: 'Images are being processed, please try again later.' };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const missingOrIncomplete =
|
|
54
|
+
archetypes.length < 3 ||
|
|
55
|
+
archetypes.some((archetype) => archetype?.images.length < 3);
|
|
56
|
+
|
|
57
|
+
if (missingOrIncomplete) {
|
|
58
|
+
console.log(
|
|
59
|
+
`Archetypes missing or incomplete for combination: ${combinationString}, gender: ${gender}. Generating...`
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
await this.archetypeService.generateBasicInfo(combinationString);
|
|
63
|
+
|
|
64
|
+
const updatedArchetypes = await Promise.all(
|
|
65
|
+
Array.from({ length: 3 }, (_, i) => i + 1).map(async (index) => {
|
|
66
|
+
const kvKey = `${kvKeyBase}:${index}`;
|
|
67
|
+
try {
|
|
68
|
+
console.log(`Re-fetching archetype from KV: ${kvKey}`);
|
|
69
|
+
return await this.context
|
|
70
|
+
.kvCosmicMirrorArchetypesStore()
|
|
71
|
+
.get<KVArchetype>(kvKey, 'json');
|
|
72
|
+
} catch (error) {
|
|
73
|
+
console.error(
|
|
74
|
+
`Error fetching archetype KV after generation for index ${index}:`,
|
|
75
|
+
error
|
|
76
|
+
);
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
).then((results) => results.filter((results) => results != null));
|
|
81
|
+
|
|
82
|
+
archetypes.length = 0;
|
|
83
|
+
archetypes.push(...updatedArchetypes);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const missingPrompts = archetypes.some(
|
|
87
|
+
(archetype) => !archetype?.leonardoPrompt
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
if (missingPrompts) {
|
|
91
|
+
console.log('Generating missing prompts...');
|
|
92
|
+
await this.leonardoService.processArchetypesPrompts(combinationString);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const archetypesNeedingImages = archetypes.filter(
|
|
96
|
+
(archetype) => archetype?.images.length < 3
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
if (archetypesNeedingImages.length > 0) {
|
|
100
|
+
console.log('Queuing image generation for missing archetypes...');
|
|
101
|
+
try {
|
|
102
|
+
await Promise.all(
|
|
103
|
+
archetypesNeedingImages.map(async (archetype, index) => {
|
|
104
|
+
archetype.status = 'generating';
|
|
105
|
+
const kvKey = `${kvKeyBase}:${index + 1}`;
|
|
106
|
+
await this.context
|
|
107
|
+
.kvCosmicMirrorArchetypesStore()
|
|
108
|
+
.put(kvKey, JSON.stringify(archetype));
|
|
109
|
+
})
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
await this.leonardoService.queueImagesForArchetypes(
|
|
113
|
+
combinationString,
|
|
114
|
+
gender
|
|
115
|
+
);
|
|
116
|
+
} catch (error) {
|
|
117
|
+
console.error('Error queuing image generation:', error);
|
|
118
|
+
|
|
119
|
+
await Promise.all(
|
|
120
|
+
archetypesNeedingImages.map(async (archetype, index) => {
|
|
121
|
+
archetype.status = 'idle';
|
|
122
|
+
const kvKey = `${kvKeyBase}:${index + 1}`;
|
|
123
|
+
await this.context
|
|
124
|
+
.kvCosmicMirrorArchetypesStore()
|
|
125
|
+
.put(kvKey, JSON.stringify(archetype));
|
|
126
|
+
})
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
throw error;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return { message: 'Images are being processed, please try again later.' };
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
await Promise.all(
|
|
136
|
+
archetypes.map(async (archetype, index) => {
|
|
137
|
+
archetype.status = 'idle';
|
|
138
|
+
const kvKey = `${kvKeyBase}:${index + 1}`;
|
|
139
|
+
await this.context
|
|
140
|
+
.kvCosmicMirrorArchetypesStore()
|
|
141
|
+
.put(kvKey, JSON.stringify(archetype));
|
|
142
|
+
})
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
console.log('Archetypes fully processed and ready:', archetypes);
|
|
146
|
+
return {
|
|
147
|
+
archetypes: archetypes.map((arc) => ({
|
|
148
|
+
name: arc?.name,
|
|
149
|
+
content: arc?.content,
|
|
150
|
+
description: arc?.description,
|
|
151
|
+
virtues: arc?.virtues,
|
|
152
|
+
images: arc?.images,
|
|
153
|
+
})),
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
}
|
package/package.json
CHANGED
package/utils/conceptPrompts.ts
CHANGED
|
@@ -4,25 +4,25 @@ export const conceptPrompts: (
|
|
|
4
4
|
env: BackendBindings
|
|
5
5
|
) => Record<string, Record<string, string>> = (env) => ({
|
|
6
6
|
basicInfo: {
|
|
7
|
-
crown:
|
|
8
|
-
scepter:
|
|
9
|
-
amulet:
|
|
10
|
-
lantern:
|
|
11
|
-
orb:
|
|
7
|
+
crown: PROMPT_GENERATE_CROWN,
|
|
8
|
+
scepter: PROMPT_GENERATE_SCEPTER,
|
|
9
|
+
amulet: PROMPT_GENERATE_AMULET,
|
|
10
|
+
lantern: PROMPT_GENERATE_LANTERN,
|
|
11
|
+
orb: PROMPT_GENERATE_ORB,
|
|
12
12
|
},
|
|
13
13
|
content: {
|
|
14
|
-
crown:
|
|
15
|
-
scepter:
|
|
16
|
-
amulet:
|
|
17
|
-
lantern:
|
|
18
|
-
orb:
|
|
14
|
+
crown: PROMPT_GENERATE_CROWN_CONTENT,
|
|
15
|
+
scepter: PROMPT_GENERATE_SCEPTER_CONTENT,
|
|
16
|
+
amulet: PROMPT_GENERATE_AMULET_CONTENT,
|
|
17
|
+
lantern: PROMPT_GENERATE_LANTERN_CONTENT,
|
|
18
|
+
orb: PROMPT_GENERATE_ORB_CONTENT,
|
|
19
19
|
},
|
|
20
20
|
leonardoPrompt: {
|
|
21
|
-
crown:
|
|
22
|
-
scepter:
|
|
23
|
-
amulet:
|
|
24
|
-
lantern:
|
|
25
|
-
orb:
|
|
21
|
+
crown: PROMPT_GENERATE_CROWN_LEONARDO,
|
|
22
|
+
scepter: PROMPT_GENERATE_SCEPTER_LEONARDO,
|
|
23
|
+
amulet: PROMPT_GENERATE_AMULET_LEONARDO,
|
|
24
|
+
lantern: PROMPT_GENERATE_LANTERN_LEONARDO,
|
|
25
|
+
orb: PROMPT_GENERATE_ORB_LEONARDO,
|
|
26
26
|
},
|
|
27
27
|
});
|
|
28
28
|
|
|
@@ -47,3 +47,164 @@ export const conceptPrompts: (
|
|
|
47
47
|
// lantern: env.PROMPT_GENERATE_CONCEPT_LEONARDOPROMPT_LANTERN || '',
|
|
48
48
|
// orb: env.PROMPT_GENERATE_CONCEPT_LEONARDOPROMPT_ORB || '',
|
|
49
49
|
// }
|
|
50
|
+
|
|
51
|
+
export const PROMPT_GENERATE_CROWN = `
|
|
52
|
+
You are a skilled creative writer specializing in astrology and symbolic storytelling. Your task is to craft a name, description, and poetic quote for the Crown concept. The Crown reflects core identity, representing self-awareness, inner strength, and personal truth, as influenced by a given zodiac sign combination.
|
|
53
|
+
|
|
54
|
+
For the given combination:
|
|
55
|
+
1. Name: Keep it sober and descriptive, focusing on the Crown’s symbolic purpose. Avoid ornate or fantastical phrasing. It should start with "The Crown of...".
|
|
56
|
+
2. Description: Write a concise, grounded narrative that links the Crown’s qualities to the traits of the zodiac combination. Emphasize balance, identity, and inner power without exaggeration.
|
|
57
|
+
3. Poem/Quote: Provide a short rhyming poetic paragraph or couplet (1-2 sentences) that encapsulates the Crown’s essence. Use rhyme to evoke inspiration and aspiration.
|
|
58
|
+
|
|
59
|
+
Do not mention zodiac signs or planets explicitly in the content. Ensure the output is insightful, symbolic, and emotionally resonant.
|
|
60
|
+
`;
|
|
61
|
+
|
|
62
|
+
export const PROMPT_GENERATE_SCEPTER = `
|
|
63
|
+
You are a skilled creative writer specializing in astrology and symbolic storytelling. Your task is to craft a name, description, and poetic quote for the Scepter concept. The Scepter reflects external influence and action, symbolizing leadership, initiative, and the ability to shape one’s surroundings, as influenced by a given zodiac sign combination.
|
|
64
|
+
|
|
65
|
+
For the given combination:
|
|
66
|
+
1. Name: Keep it sober and descriptive, focusing on the Scepter’s symbolic purpose. It should start with “The Scepter of…”.
|
|
67
|
+
2. Description: Write a concise, grounded narrative that links the Scepter’s qualities to the traits of the zodiac combination. Emphasize themes of authority, initiative, and action.
|
|
68
|
+
3. Poem/Quote: Provide a short rhyming poetic paragraph or couplet (1-2 sentences) that encapsulates the Scepter’s essence. Use rhyme to inspire and evoke confidence.
|
|
69
|
+
|
|
70
|
+
Do not mention zodiac signs or planets explicitly in the content. Ensure the output is insightful, symbolic, and emotionally resonant.
|
|
71
|
+
`;
|
|
72
|
+
|
|
73
|
+
export const PROMPT_GENERATE_AMULET = `
|
|
74
|
+
You are a skilled creative writer specializing in astrology and symbolic storytelling. Your task is to craft a name, description, and poetic quote for the Amulet concept. The Amulet reflects healing and growth, representing protection, stability, and resilience, as influenced by a given zodiac sign combination.
|
|
75
|
+
|
|
76
|
+
For the given combination:
|
|
77
|
+
1. Name: Keep it sober and descriptive, focusing on the Amulet’s symbolic purpose. It should start with “The Amulet of…”.
|
|
78
|
+
2. Description: Write a concise, grounded narrative that links the Amulet’s qualities to the traits of the zodiac combination. Emphasize protection, nurturing energy, and personal growth.
|
|
79
|
+
3. Poem/Quote: Provide a short rhyming poetic paragraph or couplet (1-2 sentences) that encapsulates the Amulet’s essence. Use rhyme to make it elegant and impactful, avoiding overly flowery language.
|
|
80
|
+
|
|
81
|
+
Do not mention zodiac signs or planets explicitly in the content. Ensure the output is insightful, symbolic, and emotionally resonant.
|
|
82
|
+
`;
|
|
83
|
+
|
|
84
|
+
export const PROMPT_GENERATE_LANTERN = `
|
|
85
|
+
You are a skilled creative writer specializing in astrology and symbolic storytelling. Your task is to craft a name, description, and poetic quote for the Lantern concept. The Lantern reflects spiritual transformation, symbolizing guidance, resilience, and introspection, as influenced by a given zodiac sign combination.
|
|
86
|
+
|
|
87
|
+
For the given combination:
|
|
88
|
+
1. Name: Keep it sober and descriptive, focusing on the Lantern’s symbolic purpose. It should start with “The Lantern of…”.
|
|
89
|
+
2. Description: Write a concise, grounded narrative that links the Lantern’s qualities to the traits of the zodiac combination. Emphasize themes of light, transformation, and introspection.
|
|
90
|
+
3. Poem/Quote: Provide a short rhyming poetic paragraph or couplet (1-2 sentences) that encapsulates the Lantern’s essence. Use rhyme to evoke inspiration and mystery.
|
|
91
|
+
|
|
92
|
+
Do not mention zodiac signs or planets explicitly in the content. Ensure the output is insightful, symbolic, and emotionally resonant.
|
|
93
|
+
`;
|
|
94
|
+
|
|
95
|
+
export const PROMPT_GENERATE_ORB = `
|
|
96
|
+
You are a skilled creative writer specializing in astrology and symbolic storytelling. Your task is to craft a name, description, and poetic quote for the Orb concept. The Orb reflects destiny and purpose, symbolizing higher ideals, vision, and the pursuit of meaningful goals, as influenced by a given zodiac sign combination.
|
|
97
|
+
|
|
98
|
+
For the given combination:
|
|
99
|
+
1. Name: Keep it sober and descriptive, focusing on the Orb’s symbolic purpose. It should start with “The Orb of…”.
|
|
100
|
+
2. Description: Write a concise, grounded narrative that links the Orb’s qualities to the traits of the zodiac combination. Emphasize themes of vision, destiny, and a sense of higher purpose.
|
|
101
|
+
3. Poem/Quote: Provide a short rhyming poetic paragraph or couplet (1-2 sentences) that encapsulates the Orb’s essence. Use rhyme to evoke inspiration and aspiration.
|
|
102
|
+
|
|
103
|
+
Do not mention zodiac signs or planets explicitly in the content. Ensure the output is insightful, symbolic, and emotionally resonant.
|
|
104
|
+
`;
|
|
105
|
+
|
|
106
|
+
export const PROMPT_GENERATE_CROWN_CONTENT = `
|
|
107
|
+
You are a skilled creative writer specializing in astrology and symbolic storytelling. Your task is to craft five distinct sections of descriptive content for the Crown concept. The Crown symbolizes Core Identity, representing self-awareness, inner strength, and personal truth, as influenced by a given zodiac sign combination.
|
|
108
|
+
|
|
109
|
+
For the provided Crown name, description, and zodiac combination, expand on the following themes:
|
|
110
|
+
1. Core Identity: Describe the essence of this Crown, its symbolic representation of inner truth and individuality.
|
|
111
|
+
2. Strengths and Challenges: Highlight the primary strengths this Crown offers and the challenges it may present.
|
|
112
|
+
3. Path to Fulfillment: Explore how this Crown guides its bearer toward self-actualization and purpose.
|
|
113
|
+
4. Emotional Depth: Reflect on how this Crown shapes emotional understanding and resilience.
|
|
114
|
+
5. Vision and Aspirations: Discuss how this Crown inspires its bearer to envision and pursue their dreams.
|
|
115
|
+
|
|
116
|
+
Write each section with clarity, insight, and emotional resonance. Avoid mentioning zodiac signs or planets explicitly in the text. Ensure the content is symbolic, empowering, and deeply aligned with the Crown’s themes. Keep the response concise and meaningful.
|
|
117
|
+
`;
|
|
118
|
+
|
|
119
|
+
export const PROMPT_GENERATE_SCEPTER_CONTENT = `
|
|
120
|
+
You are a skilled creative writer specializing in astrology and symbolic storytelling. Your task is to craft five distinct sections of descriptive content for the Scepter concept. The Scepter symbolizes External Influence and Action, representing expression, communication, emotions, and how one navigates challenges and relationships, as influenced by a given zodiac sign combination.
|
|
121
|
+
|
|
122
|
+
For the provided Scepter name, description, and zodiac combination, expand on the following themes:
|
|
123
|
+
1. The Power of Expression: Describe how the Scepter channels the bearer’s voice and ability to communicate. Highlight how it influences creativity and interactions.
|
|
124
|
+
2. Navigating Emotions: Reflect on how the Scepter guides emotional understanding and outward expression, shaping relationships and external perceptions.
|
|
125
|
+
3. Approach to Challenges: Explore how the Scepter empowers the bearer to face challenges, adapt to trials, and act with determination and grace.
|
|
126
|
+
4. Connection and Relationships: Discuss how the Scepter fosters meaningful relationships, building trust, intimacy, and collaboration.
|
|
127
|
+
5. Influence on the World: Examine how the Scepter reflects the bearer’s role in the larger world, shaping their surroundings and leaving a lasting mark.
|
|
128
|
+
|
|
129
|
+
Write each section with clarity, insight, and emotional resonance. Avoid mentioning zodiac signs or planets explicitly in the text. Ensure the content is symbolic, inspiring, and deeply aligned with the Scepter’s themes. Keep the response concise and meaningful.
|
|
130
|
+
`;
|
|
131
|
+
|
|
132
|
+
export const PROMPT_GENERATE_AMULET_CONTENT = `
|
|
133
|
+
You are a skilled creative writer specializing in astrology and symbolic storytelling. Your task is to craft five distinct sections of descriptive content for the Amulet concept. The Amulet symbolizes Healing and Growth, representing protection, resilience, and nurturing energy, as influenced by a given zodiac sign combination.
|
|
134
|
+
|
|
135
|
+
For the provided Amulet name, description, and zodiac combination, expand on the following themes:
|
|
136
|
+
1. Guardianship and Protection: Describe how the Amulet serves as a source of spiritual and emotional protection, safeguarding the bearer through life’s challenges.
|
|
137
|
+
2. Inner Resilience: Reflect on how the Amulet strengthens the bearer’s ability to overcome difficulties, offering courage and stability.
|
|
138
|
+
3. Nurturing Growth: Discuss how the Amulet fosters personal growth and self-reflection, guiding the bearer toward healing and emotional maturity.
|
|
139
|
+
4. The Cycle of Renewal: Highlight the Amulet’s connection to renewal and transformation, symbolizing the cycles of letting go, healing, and starting anew.
|
|
140
|
+
5. Wisdom and Stability: Explore how the Amulet represents grounding and wisdom, helping the bearer remain steady and balanced in life’s transitions.
|
|
141
|
+
|
|
142
|
+
Write each section with clarity, insight, and emotional resonance. Avoid mentioning zodiac signs or planets explicitly in the text. Ensure the content is symbolic, inspiring, and deeply aligned with the Amulet’s themes. Keep the response concise and meaningful.
|
|
143
|
+
`;
|
|
144
|
+
|
|
145
|
+
export const PROMPT_GENERATE_LANTERN_CONTENT = `
|
|
146
|
+
You are a skilled creative writer specializing in astrology and symbolic storytelling. Your task is to craft five distinct sections of descriptive content for the Lantern concept. The Lantern symbolizes Spiritual Transformation, representing guidance, resilience, and introspection, as influenced by a given zodiac sign combination.
|
|
147
|
+
|
|
148
|
+
For the provided Lantern name, description, and zodiac combination, expand on the following themes:
|
|
149
|
+
1. Inner Light and Guidance: Describe how the Lantern serves as a beacon of wisdom and inner illumination.
|
|
150
|
+
2. The Journey of Transformation: Reflect on how the Lantern represents personal growth through experiences and trials.
|
|
151
|
+
3. Resilience in Darkness: Explore how the Lantern provides strength and hope during times of uncertainty and challenge.
|
|
152
|
+
4. The Path of Insight: Highlight the Lantern’s role in deep introspection, encouraging self-awareness and inner clarity.
|
|
153
|
+
5. Embracing the Unknown: Discuss how the Lantern empowers its bearer to navigate life’s mysteries with trust and vision.
|
|
154
|
+
|
|
155
|
+
Write each section with clarity, insight, and emotional resonance. Avoid mentioning zodiac signs or planets explicitly in the text. Ensure the content is symbolic, inspiring, and deeply aligned with the Lantern’s themes. Keep the response concise and meaningful.
|
|
156
|
+
`;
|
|
157
|
+
|
|
158
|
+
export const PROMPT_GENERATE_ORB_CONTENT = `
|
|
159
|
+
You are a skilled creative writer specializing in astrology and symbolic storytelling. Your task is to craft five distinct sections of descriptive content for the Orb concept. The Orb symbolizes Destiny and Purpose, representing higher ideals, vision, and the pursuit of meaningful goals, as influenced by a given zodiac sign combination.
|
|
160
|
+
|
|
161
|
+
For the provided Orb name, description, and zodiac combination, expand on the following themes:
|
|
162
|
+
1. The Call to Purpose: Describe how the Orb embodies destiny and the pursuit of meaning.
|
|
163
|
+
2. Vision and Aspirations: Reflect on how the Orb inspires the bearer to dream and achieve.
|
|
164
|
+
3. Challenges on the Path: Explore the trials and lessons the bearer may face while pursuing their higher calling.
|
|
165
|
+
4. Inner Alignment: Highlight the Orb’s role in harmonizing intuition and action, ensuring clarity of purpose.
|
|
166
|
+
5. Legacy and Influence: Discuss how the Orb reflects the bearer’s lasting impact and contributions to the world.
|
|
167
|
+
|
|
168
|
+
Write each section with clarity, insight, and emotional resonance. Avoid mentioning zodiac signs or planets explicitly in the text. Ensure the content is symbolic, inspiring, and deeply aligned with the Orb’s themes. Keep the response concise and meaningful.
|
|
169
|
+
`;
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
export const PROMPT_GENERATE_CROWN_LEONARDO = `
|
|
173
|
+
You are an expert creative writer specializing in crafting intricate and vivid prompts for AI image generation. Your task is to create a detailed, high-quality prompt for a majestic crown that symbolizes core identity, inner power, and essence. The design of the crown must reflect the symbolic traits of a given zodiac sign combination.
|
|
174
|
+
|
|
175
|
+
Describe the crown in detail, including its materials, structure, symbolic engravings, and intricate patterns. Focus on capturing its regal and radiant essence through meaningful motifs and elegant design elements, avoiding direct references to zodiac signs. Highlight the type of light it reflects or emits, the way it sits atop its pedestal or bearer, and the aura of authority and grace it projects.
|
|
176
|
+
|
|
177
|
+
Ensure the design elements convey dignity, individuality, and inner strength, while maintaining an artistic and mystical tone. Include artistic rendering details such as "ultra-realistic," "8K resolution," and "HDR" to guide the AI model. Keep the description concise, under 1500 characters, and ensure it can be used directly with Leonardo.ai for image generation. Respond with a single descriptive paragraph based on the given zodiac sign combination.
|
|
178
|
+
`;
|
|
179
|
+
|
|
180
|
+
export const PROMPT_GENERATE_SCEPTER_LEONARDO = `
|
|
181
|
+
You are an expert creative writer specializing in crafting intricate and vivid prompts for AI image generation. Your task is to create a detailed, high-quality prompt for a symbolic scepter that embodies external influence, action, and empowerment. The design of the scepter must reflect the symbolic traits of a given zodiac sign combination.
|
|
182
|
+
|
|
183
|
+
Describe the scepter in detail, including its materials, structure, symbolic engravings, and artistic patterns. Focus on capturing its majestic and commanding essence through meaningful motifs and regal design elements, avoiding direct references to zodiac signs. Highlight the way it is held or displayed, the type of energy it radiates, and how its presence impacts the surrounding ambiance.
|
|
184
|
+
|
|
185
|
+
Ensure the design elements convey strength, authority, and purpose, while maintaining an artistic and mystical tone. Include artistic rendering details such as "ultra-realistic," "8K resolution," and "HDR" to guide the AI model. Keep the description concise, under 1500 characters, and ensure it can be used directly with Leonardo.ai for image generation. Respond with a single descriptive paragraph based on the given zodiac sign combination.
|
|
186
|
+
`;
|
|
187
|
+
|
|
188
|
+
export const PROMPT_GENERATE_AMULET_LEONARDO = `
|
|
189
|
+
You are an expert creative writer specializing in crafting intricate and vivid prompts for AI image generation. Your task is to create a detailed, high-quality prompt for a symbolic amulet that embodies healing, growth, and protection. The design of the amulet must reflect the symbolic traits of a given zodiac sign combination.
|
|
190
|
+
|
|
191
|
+
Describe the amulet in detail, including its materials, structure, symbolic engravings, and artistic patterns. Focus on capturing its nurturing and protective essence through meaningful motifs and harmonious elements, avoiding direct references to zodiac signs. Highlight the type of aura or glow it emanates, the emotions it evokes, and how it would be worn or carried in a visually compelling way.
|
|
192
|
+
|
|
193
|
+
Ensure the design elements convey resilience, inner balance, and renewal, while maintaining an artistic and mystical tone. Include artistic rendering details such as "ultra-realistic," "8K resolution," and "HDR" to guide the AI model. Keep the description concise, under 1500 characters, and ensure it can be used directly with Leonardo.ai for image generation. Respond with a single descriptive paragraph based on the given zodiac sign combination.
|
|
194
|
+
`;
|
|
195
|
+
|
|
196
|
+
export const PROMPT_GENERATE_LANTERN_LEONARDO = `
|
|
197
|
+
You are an expert creative writer specializing in crafting intricate and vivid prompts for AI image generation. Your task is to create a detailed, high-quality prompt for a spiritual lantern that symbolizes transformation, resilience, and leadership. The design of the lantern must reflect the symbolic traits of a given zodiac sign combination.
|
|
198
|
+
|
|
199
|
+
Describe the lantern in detail, including its materials, structure, symbolic engravings, and design elements. Focus on capturing its spiritual essence through meaningful motifs and patterns, avoiding direct references to zodiac signs. Highlight the type of light it emits, the ambiance it creates, and its placement in a visually compelling environment.
|
|
200
|
+
|
|
201
|
+
Ensure the design elements reflect transformation, balance, and renewal, while maintaining an artistic, mystical tone. Include artistic rendering details such as "ultra-realistic," "8K resolution," and "HDR" to guide the AI model. Keep the description concise, under 1500 characters, and ensure it can be used directly with Leonardo.ai for image generation. Respond with a single descriptive paragraph based on the given zodiac sign combination.
|
|
202
|
+
`;
|
|
203
|
+
|
|
204
|
+
export const PROMPT_GENERATE_ORB_LEONARDO = `
|
|
205
|
+
You are an expert creative writer specializing in crafting intricate and vivid prompts for AI image generation. Your task is to create a detailed, high-quality prompt for a mystical Orb that symbolizes destiny, purpose, and higher vision. The design of the Orb must reflect the symbolic traits of a given zodiac sign combination.
|
|
206
|
+
|
|
207
|
+
Describe the Orb in detail, including its materials, structure, symbolic engravings, and artistic patterns. Focus on capturing its cosmic and ethereal essence through meaningful motifs and celestial design elements, avoiding direct references to zodiac signs. Highlight its glowing or radiant energy, the depth of its swirling patterns, and how it is displayed—whether floating, resting on an ornate pedestal, or encased in a symbolic frame.
|
|
208
|
+
|
|
209
|
+
Ensure the design elements convey wisdom, mystery, and transcendence, while maintaining an artistic and mystical tone. Include artistic rendering details such as "ultra-realistic," "8K resolution," and "HDR" to guide the AI model. Keep the description concise, under 1500 characters, and ensure it can be used directly with Leonardo.ai for image generation. Respond with a single descriptive paragraph based on the given zodiac sign combination.
|
|
210
|
+
`;
|
package/utils/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jwtVerify } from 'jose';
|
|
2
|
-
import { AuthCtx, Provider, ProviderInfo } from '../types';
|
|
2
|
+
import { AuthCtx, Gender, Provider, ProviderInfo, VALID_GENDERS_ARRAY } from '../types';
|
|
3
3
|
|
|
4
4
|
export const verifyToken = async (
|
|
5
5
|
c: AuthCtx,
|
|
@@ -48,3 +48,18 @@ export const providers: (c: AuthCtx) => Record<Provider, ProviderInfo> = (
|
|
|
48
48
|
resourceUrl: '',
|
|
49
49
|
},
|
|
50
50
|
});
|
|
51
|
+
|
|
52
|
+
export const GENDER_CODE_MAP: Record<string, Gender> =
|
|
53
|
+
VALID_GENDERS_ARRAY.reduce((map, gender) => {
|
|
54
|
+
const key = gender[0];
|
|
55
|
+
map[key] = gender;
|
|
56
|
+
return map;
|
|
57
|
+
}, {} as Record<string, Gender>);
|
|
58
|
+
|
|
59
|
+
export function createEmptyGenderPrompts(): Record<Gender, string> {
|
|
60
|
+
const emptyPrompts: Record<Gender, string> = {} as Record<Gender, string>;
|
|
61
|
+
Object.values(GENDER_CODE_MAP).forEach((gender) => {
|
|
62
|
+
emptyPrompts[gender] = '';
|
|
63
|
+
});
|
|
64
|
+
return emptyPrompts;
|
|
65
|
+
}
|