@zodic/shared 0.0.74 → 0.0.76

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,289 @@
1
+ import { inject, injectable } from 'inversify';
2
+ import { KVArchetype } from '../../types/scopes/legacy';
3
+ import { buildCosmicMirrorArchetypeKVKey } from '../../utils/KVKeysBuilders';
4
+ import { AppContext } from '../base';
5
+
6
+ @injectable()
7
+ export class ArchetypeService {
8
+ constructor(@inject(AppContext) private context: AppContext) {}
9
+
10
+ async generateBasicInfo(combinationString: string): Promise<void> {
11
+ console.log(
12
+ `Generating basic info for archetypes of combination: ${combinationString}`
13
+ );
14
+
15
+ const [sun, ascendant, moon] = combinationString.split('-');
16
+
17
+ const messages = this.context
18
+ .buildLLMMessages()
19
+ .generateCosmicMirrorArchetypeBasicInfo({ sun, ascendant, moon });
20
+
21
+ const response = await this.context.api().callDeepSeek.single(messages, {});
22
+
23
+ if (!response) {
24
+ throw new Error(
25
+ `Failed to generate basic info for archetypes: ${combinationString}`
26
+ );
27
+ }
28
+
29
+ const archetypes = this.parseArchetypeResponse(response);
30
+
31
+ await Promise.all(
32
+ archetypes.map(async (archetype, index) => {
33
+ const archetypeIndex = index + 1;
34
+
35
+ const maleKey = buildCosmicMirrorArchetypeKVKey(
36
+ 'en-us',
37
+ combinationString,
38
+ 'male',
39
+ archetypeIndex
40
+ );
41
+ const femaleKey = buildCosmicMirrorArchetypeKVKey(
42
+ 'en-us',
43
+ combinationString,
44
+ 'female',
45
+ archetypeIndex
46
+ );
47
+ const nonBinaryKey = buildCosmicMirrorArchetypeKVKey(
48
+ 'en-us',
49
+ combinationString,
50
+ 'non-binary',
51
+ archetypeIndex
52
+ );
53
+
54
+ const kvDataMale: KVArchetype = {
55
+ name: archetype.name,
56
+ description: archetype.descriptionMale,
57
+ visualDescription: archetype.visualRepresentation,
58
+ content: '',
59
+ leonardoPrompt: '',
60
+ virtues: archetype.virtues,
61
+ images: [],
62
+ status: 'idle',
63
+ };
64
+
65
+ const kvDataFemale: KVArchetype = {
66
+ name: archetype.name,
67
+ description: archetype.descriptionFemale,
68
+ visualDescription: archetype.visualRepresentation,
69
+ content: '',
70
+ leonardoPrompt: '',
71
+ virtues: archetype.virtues,
72
+ images: [],
73
+ status: 'idle',
74
+ };
75
+
76
+ await Promise.all([
77
+ this.context
78
+ .kvCosmicMirrorArchetypesStore()
79
+ .put(maleKey, JSON.stringify(kvDataMale)),
80
+ this.context
81
+ .kvCosmicMirrorArchetypesStore()
82
+ .put(femaleKey, JSON.stringify(kvDataFemale)),
83
+ this.context
84
+ .kvCosmicMirrorArchetypesStore()
85
+ .put(nonBinaryKey, JSON.stringify(kvDataFemale)),
86
+ ]);
87
+ })
88
+ );
89
+
90
+ console.log(
91
+ `Basic info stored for archetypes of combination: ${combinationString}`
92
+ );
93
+ }
94
+
95
+ private parseArchetypeResponse(response: string): Array<{
96
+ name: string;
97
+ descriptionMale: string;
98
+ descriptionFemale: string;
99
+ visualRepresentation: string;
100
+ virtues: string[];
101
+ }> {
102
+ console.log('Parsing archetype response from ChatGPT');
103
+
104
+ const archetypes: Array<{
105
+ name: string;
106
+ descriptionMale: string;
107
+ descriptionFemale: string;
108
+ visualRepresentation: string;
109
+ virtues: string[];
110
+ }> = [];
111
+
112
+ const entries = response.split(/\n\d+\.\n/).filter(Boolean);
113
+
114
+ for (const entry of entries) {
115
+ const nameMatch = entry.match(/- Name: (.+)/);
116
+ const descriptionMaleMatch = entry.match(
117
+ /- Narrative Description \(Male\): (.+)/
118
+ );
119
+ const descriptionFemaleMatch = entry.match(
120
+ /- Narrative Description \(Female\): (.+)/
121
+ );
122
+ const visualRepresentationMatch = entry.match(
123
+ /- Visual Representation: (.+)/
124
+ );
125
+ const virtuesMatch = entry.match(/- Virtues: (.+)/);
126
+
127
+ if (
128
+ nameMatch &&
129
+ descriptionMaleMatch &&
130
+ descriptionFemaleMatch &&
131
+ visualRepresentationMatch &&
132
+ virtuesMatch
133
+ ) {
134
+ archetypes.push({
135
+ name: nameMatch[1].trim(),
136
+ descriptionMale: descriptionMaleMatch[1].trim(),
137
+ descriptionFemale: descriptionFemaleMatch[1].trim(),
138
+ visualRepresentation: visualRepresentationMatch[1].trim(),
139
+ virtues: virtuesMatch[1].split(',').map((virtue) => virtue.trim()),
140
+ });
141
+ }
142
+ }
143
+
144
+ return archetypes;
145
+ }
146
+
147
+ async generatePrompts(combinationString: string): Promise<void> {
148
+ console.log(
149
+ `Generating Leonardo.ai prompts for archetypes of: ${combinationString}`
150
+ );
151
+
152
+ const kvStore = this.context.kvCosmicMirrorArchetypesStore();
153
+
154
+ const kvKeys = [1, 2, 3].map((index) =>
155
+ buildCosmicMirrorArchetypeKVKey(
156
+ 'en-us',
157
+ combinationString,
158
+ 'male',
159
+ index
160
+ )
161
+ );
162
+
163
+ const archetypeEntries = await Promise.all(
164
+ kvKeys.map((key) => kvStore.get<KVArchetype>(key))
165
+ );
166
+
167
+ if (archetypeEntries.some((entry) => !entry)) {
168
+ throw new Error(
169
+ `Missing archetype data for combination: ${combinationString}`
170
+ );
171
+ }
172
+
173
+ const messages = this.context
174
+ .buildLLMMessages()
175
+ .generateCosmicMirrorArchetypesLeonardoPrompts(
176
+ archetypeEntries.map((entry) => ({
177
+ name: entry!.name,
178
+ visualDescription: entry!.visualDescription, // Using visual description for prompt
179
+ }))
180
+ );
181
+
182
+ const response = await this.context.api().callDeepSeek.single(messages, {});
183
+ if (!response) {
184
+ throw new Error(
185
+ `Failed to generate Leonardo prompts for: ${combinationString}`
186
+ );
187
+ }
188
+
189
+ const parsedPrompts = this.parseLeonardoPromptResponse(response);
190
+
191
+ await Promise.all(
192
+ parsedPrompts.map(async (promptData, index) => {
193
+ const archetypeIndex = index + 1;
194
+
195
+ const maleKey = buildCosmicMirrorArchetypeKVKey(
196
+ 'en-us',
197
+ combinationString,
198
+ 'male',
199
+ archetypeIndex
200
+ );
201
+ const femaleKey = buildCosmicMirrorArchetypeKVKey(
202
+ 'en-us',
203
+ combinationString,
204
+ 'female',
205
+ archetypeIndex
206
+ );
207
+ const nonBinaryKey = buildCosmicMirrorArchetypeKVKey(
208
+ 'en-us',
209
+ combinationString,
210
+ 'non-binary',
211
+ archetypeIndex
212
+ );
213
+
214
+ const updateKV = async (key: string, updatedPrompt: string) => {
215
+ const existingEntry = await kvStore.get<KVArchetype>(key);
216
+ if (existingEntry) {
217
+ await kvStore.put(
218
+ key,
219
+ JSON.stringify({
220
+ ...existingEntry,
221
+ leonardoPrompt: updatedPrompt,
222
+ })
223
+ );
224
+ }
225
+ };
226
+
227
+ await Promise.all([
228
+ updateKV(maleKey, promptData.malePrompt),
229
+ updateKV(femaleKey, promptData.femalePrompt),
230
+ updateKV(nonBinaryKey, promptData.nonBinaryPrompt),
231
+ ]);
232
+ })
233
+ );
234
+
235
+ console.log(
236
+ `Leonardo prompts stored for archetypes of: ${combinationString}`
237
+ );
238
+ }
239
+
240
+ private parseLeonardoPromptResponse(response: string): Array<{
241
+ malePrompt: string;
242
+ femalePrompt: string;
243
+ nonBinaryPrompt: string;
244
+ }> {
245
+ console.log('Parsing Leonardo prompt response from ChatGPT');
246
+
247
+ const parsedPrompts: Array<{
248
+ malePrompt: string;
249
+ femalePrompt: string;
250
+ nonBinaryPrompt: string;
251
+ }> = [];
252
+
253
+ const entries = response.split(/\n\d+\.\w{1,2}\n/).filter(Boolean);
254
+
255
+ for (let i = 0; i < entries.length; i += 3) {
256
+ const malePrompt = entries[i]?.trim();
257
+ const femalePrompt = entries[i + 1]?.trim();
258
+ const nonBinaryPrompt = entries[i + 2]?.trim();
259
+
260
+ if (malePrompt && femalePrompt && nonBinaryPrompt) {
261
+ parsedPrompts.push({ malePrompt, femalePrompt, nonBinaryPrompt });
262
+ }
263
+ }
264
+
265
+ return parsedPrompts;
266
+ }
267
+
268
+ async generateImages(combinationString: string): Promise<void> {
269
+ const kvBaseKey = `archetypes:${combinationString}`;
270
+ console.log(
271
+ `Generating images for archetypes of combination: ${combinationString}`
272
+ );
273
+
274
+ await Promise.all(
275
+ [1, 2, 3].map(async (index) => {
276
+ const kvKey = `${kvBaseKey}:${index}`;
277
+ const archetype = await this.context
278
+ .kvCosmicMirrorArchetypesStore()
279
+ .get<KVArchetype>(kvKey, 'json');
280
+ if (!archetype || !archetype.leonardoPrompt) {
281
+ throw new Error(
282
+ `Missing Leonardo prompt for archetype ${index} of combination: ${combinationString}`
283
+ );
284
+ }
285
+ // Add image generation logic
286
+ })
287
+ );
288
+ }
289
+ }
@@ -1,6 +1,8 @@
1
1
  import { inject, injectable } from 'inversify';
2
2
  import 'reflect-metadata';
3
+ import { Languages } from '../../types';
3
4
  import { KVConcept, sizes } from '../../types/scopes/legacy';
5
+ import { buildConceptKVKey } from '../../utils/KVKeysBuilders';
4
6
  import { AppContext } from '../base/AppContext';
5
7
 
6
8
  @injectable()
@@ -11,12 +13,13 @@ export class ConceptService {
11
13
  * Generate basic info for a concept: name, description, and poem.
12
14
  */
13
15
  async generateBasicInfo(
16
+ language: Languages,
14
17
  conceptSlug: string,
15
18
  combinationString: string
16
19
  ): Promise<void> {
17
- const kvKey = `concepts:${conceptSlug}:${combinationString}`;
20
+ const kvKey = buildConceptKVKey(language, conceptSlug, combinationString);
18
21
  console.log(
19
- `Generating basic info for concept: ${conceptSlug}, combination: ${combinationString}`
22
+ `Generating basic info for concept: ${conceptSlug}, combination: ${combinationString}, language: ${language}`
20
23
  );
21
24
 
22
25
  const messages = this.context.buildLLMMessages().generateConceptBasicInfo({
@@ -33,13 +36,12 @@ export class ConceptService {
33
36
 
34
37
  const { name, description, poem } = this.parseBasicInfoResponse(response);
35
38
 
36
- // Save basic info to KV
37
39
  const concept = await this.getKVConcept(kvKey);
38
40
  Object.assign(concept, { name, description, poem, status: 'idle' });
39
41
 
40
42
  await this.context.kvConceptsStore().put(kvKey, JSON.stringify(concept));
41
43
  console.log(
42
- `Basic info stored for concept: ${conceptSlug}, combination: ${combinationString}`
44
+ `Basic info stored for concept: ${conceptSlug}, combination: ${combinationString}, language: ${language}`
43
45
  );
44
46
  }
45
47
 
@@ -68,12 +70,13 @@ export class ConceptService {
68
70
  * Generate the Leonardo prompt for a concept.
69
71
  */
70
72
  async generatePrompt(
73
+ language: Languages,
71
74
  conceptSlug: string,
72
75
  combinationString: string
73
76
  ): Promise<void> {
74
- const kvKey = `concepts:${conceptSlug}:${combinationString}`;
77
+ const kvKey = buildConceptKVKey(language, conceptSlug, combinationString);
75
78
  console.log(
76
- `Generating Leonardo prompt for concept: ${conceptSlug}, combination: ${combinationString}`
79
+ `Generating Leonardo prompt for concept: ${conceptSlug}, combination: ${combinationString}, language: ${language}`
77
80
  );
78
81
 
79
82
  const concept = await this.getKVConcept(kvKey);
@@ -100,7 +103,7 @@ export class ConceptService {
100
103
  concept.leonardoPrompt = response.trim();
101
104
  await this.context.kvConceptsStore().put(kvKey, JSON.stringify(concept));
102
105
  console.log(
103
- `Leonardo prompt stored for concept: ${conceptSlug}, combination: ${combinationString}`
106
+ `Leonardo prompt stored for concept: ${conceptSlug}, combination: ${combinationString}, language: ${language}`
104
107
  );
105
108
  }
106
109
 
@@ -108,12 +111,13 @@ export class ConceptService {
108
111
  * Generate additional content for a concept.
109
112
  */
110
113
  async generateContent(
114
+ language: Languages,
111
115
  conceptSlug: string,
112
116
  combinationString: string
113
117
  ): Promise<void> {
114
- const kvKey = `concepts:${conceptSlug}:${combinationString}`;
118
+ const kvKey = buildConceptKVKey(language, conceptSlug, combinationString);
115
119
  console.log(
116
- `Generating additional content for concept: ${conceptSlug}, combination: ${combinationString}`
120
+ `Generating additional content for concept: ${conceptSlug}, combination: ${combinationString}, language: ${language}`
117
121
  );
118
122
 
119
123
  const concept = await this.getKVConcept(kvKey);
@@ -139,7 +143,7 @@ export class ConceptService {
139
143
  concept.content = response.trim();
140
144
  await this.context.kvConceptsStore().put(kvKey, JSON.stringify(concept));
141
145
  console.log(
142
- `Content stored for concept: ${conceptSlug}, combination: ${combinationString}`
146
+ `Content stored for concept: ${conceptSlug}, combination: ${combinationString}, language: ${language}`
143
147
  );
144
148
  }
145
149
 
@@ -147,12 +151,13 @@ export class ConceptService {
147
151
  * Queue image generation for a concept.
148
152
  */
149
153
  async generateImages(
154
+ language: Languages,
150
155
  conceptSlug: string,
151
156
  combinationString: string
152
157
  ): Promise<void> {
153
- const kvKey = `concepts:${conceptSlug}:${combinationString}`;
158
+ const kvKey = buildConceptKVKey(language, conceptSlug, combinationString);
154
159
  console.log(
155
- `Queuing image generation for concept: ${conceptSlug}, combination: ${combinationString}`
160
+ `Queuing image generation for concept: ${conceptSlug}, combination: ${combinationString}, language: ${language}`
156
161
  );
157
162
 
158
163
  const concept = await this.getKVConcept(kvKey);
@@ -171,7 +176,7 @@ export class ConceptService {
171
176
  });
172
177
 
173
178
  console.log(
174
- `Post images queued for concept: ${conceptSlug}, combination: ${combinationString}`
179
+ `Post images queued for concept: ${conceptSlug}, combination: ${combinationString}, language: ${language}`
175
180
  );
176
181
  }
177
182
 
@@ -182,6 +187,7 @@ export class ConceptService {
182
187
  const existingData = await this.context
183
188
  .kvConceptsStore()
184
189
  .get<KVConcept>(kvKey, 'json');
190
+
185
191
  if (existingData) {
186
192
  return existingData;
187
193
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zodic/shared",
3
- "version": "0.0.74",
3
+ "version": "0.0.76",
4
4
  "module": "index.ts",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -28,10 +28,11 @@ export type CentralBindings = {
28
28
  CONCEPT_GENERATION_QUEUE: Queue;
29
29
 
30
30
  PROMPT_IMAGE_DESCRIBER: string;
31
- PROMPT_GENERATE_ARCHETYPE: string;
32
- PROMPT_GENERATE_LEONARDO: string;
31
+ PROMPT_GENERATE_ARCHETYPE_BASIC_INFO: string;
32
+ PROMPT_GENERATE_ARCHETYPE_CONTENT: string;
33
+ PROMPT_GENERATE_ARCHETYPE_LEONARDO_PROMPTS: string;
33
34
  NEGATIVE_PROMPT_LEONARDO: string;
34
- PROMPT_GENERATE_USER_LUMINOUS_SELF: string;
35
+ PROMPT_PERSONALIZE_COSMIC_MIRROR_LEONARDO_PROMPT: string;
35
36
  AI: Ai;
36
37
  DB: D1Database;
37
38
  DRIZZLE: DrizzleD1Database;
@@ -90,10 +91,10 @@ export type BackendBindings = Env &
90
91
  | 'KV_CONCEPTS'
91
92
  | 'KV_LEONARDO_PROMPTS'
92
93
  | 'PROMPT_IMAGE_DESCRIBER'
93
- | 'PROMPT_GENERATE_ARCHETYPE'
94
- | 'PROMPT_GENERATE_LEONARDO'
94
+ | 'PROMPT_GENERATE_ARCHETYPE_CONTENT'
95
+ | 'PROMPT_GENERATE_ARCHETYPE_LEONARDO_PROMPTS'
95
96
  | 'NEGATIVE_PROMPT_LEONARDO'
96
- | 'PROMPT_GENERATE_USER_LUMINOUS_SELF'
97
+ | 'PROMPT_PERSONALIZE_COSMIC_MIRROR_LEONARDO_PROMPT'
97
98
  | 'DB'
98
99
  | 'JWT_SECRET'
99
100
  | 'GOOGLE_API_KEY'
@@ -115,6 +116,7 @@ export type BackendBindings = Env &
115
116
  | 'CONCEPT_GENERATION_QUEUE'
116
117
  | 'KV_CONCEPTS_MANAGEMENT'
117
118
  | 'DEEPSEEK_API_KEY'
119
+ | 'PROMPT_GENERATE_ARCHETYPE_BASIC_INFO'
118
120
  >;
119
121
 
120
122
  export type BackendCtx = Context<
@@ -0,0 +1,18 @@
1
+ import { Gender, Languages } from '../types';
2
+
3
+ export const buildCosmicMirrorArchetypeKVKey = (
4
+ lang: Languages,
5
+ crown: string,
6
+ gender: Gender,
7
+ index: number
8
+ ): string => {
9
+ return `cosmic_mirror:${lang}:${crown}:${gender}:${index}`;
10
+ };
11
+
12
+ export const buildConceptKVKey = (
13
+ lang: Languages,
14
+ conceptSlug: string,
15
+ combinationString: string
16
+ ): string => {
17
+ return `concepts:${lang}:${conceptSlug}:${combinationString}`;
18
+ };
@@ -9,7 +9,7 @@ export const buildLLMMessages = (env: BackendBindings) => ({
9
9
  }: Crown): ChatMessages => [
10
10
  {
11
11
  role: 'system',
12
- content: env.PROMPT_GENERATE_ARCHETYPE,
12
+ content: env.PROMPT_GENERATE_ARCHETYPE_BASIC_INFO,
13
13
  },
14
14
  {
15
15
  role: 'user',
@@ -21,29 +21,59 @@ export const buildLLMMessages = (env: BackendBindings) => ({
21
21
  },
22
22
  ],
23
23
  generateCosmicMirrorArchetypesLeonardoPrompts: (
24
- archetypes: Array<{ name: string; description: string }>
24
+ archetypes: Array<{ name: string; visualDescription: string }>
25
25
  ): ChatMessages => [
26
26
  {
27
27
  role: 'system',
28
- content: env.PROMPT_GENERATE_LEONARDO,
28
+ content: env.PROMPT_GENERATE_ARCHETYPE_LEONARDO_PROMPTS,
29
29
  },
30
30
  {
31
31
  role: 'user',
32
32
  content: `
33
33
  1.
34
34
  - Name: ${archetypes[0].name}
35
- - Description: ${archetypes[0].description}
35
+ - Visual Description: ${archetypes[0].visualDescription}
36
36
 
37
37
  2.
38
38
  - Name: ${archetypes[1].name}
39
- - Description: ${archetypes[1].description}
39
+ - Visual Description: ${archetypes[1].visualDescription}
40
40
 
41
41
  3.
42
42
  - Name: ${archetypes[2].name}
43
- - Description: ${archetypes[2].description}
43
+ - Visual Description: ${archetypes[2].visualDescription}
44
44
  `,
45
45
  },
46
46
  ],
47
+ generateCosmicMirrorArchetypeContent: ({
48
+ name,
49
+ description,
50
+ sun,
51
+ ascendant,
52
+ moon,
53
+ }: {
54
+ name: string;
55
+ description: string;
56
+ sun: string;
57
+ ascendant: string;
58
+ moon: string;
59
+ }): ChatMessages => [
60
+ {
61
+ role: 'system',
62
+ content: env.PROMPT_GENERATE_ARCHETYPE_CONTENT,
63
+ },
64
+ {
65
+ role: 'user',
66
+ content: `
67
+ Generate a detailed archetype description using the following inputs:
68
+
69
+ Archetype Name: ${name}
70
+ Archetype Description: ${description}
71
+ Sun Sign: ${sun}
72
+ Ascendant Sign: ${ascendant}
73
+ Moon Sign: ${moon}
74
+ `,
75
+ },
76
+ ],
47
77
  personalizeCosmicMirrorLeonardoPrompt: ({
48
78
  leonardoPrompt,
49
79
  traits,
@@ -53,7 +83,7 @@ export const buildLLMMessages = (env: BackendBindings) => ({
53
83
  }): ChatMessages => [
54
84
  {
55
85
  role: 'system',
56
- content: env.PROMPT_GENERATE_USER_LUMINOUS_SELF,
86
+ content: env.PROMPT_PERSONALIZE_COSMIC_MIRROR_LEONARDO_PROMPT,
57
87
  },
58
88
  {
59
89
  role: 'user',