@zodic/shared 0.0.142 → 0.0.144

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.
@@ -4,7 +4,7 @@ import 'reflect-metadata';
4
4
  import { v4 as uuidv4 } from 'uuid';
5
5
  import { schema } from '../..';
6
6
  import { Concept, ControlNetConfig, Languages } from '../../types';
7
- import { KVConcept, sizes } from '../../types/scopes/legacy';
7
+ import { KVConcept, sizes, StructuredConceptContent } from '../../types/scopes/legacy';
8
8
  import { leonardoInitImages } from '../../utils/initImages';
9
9
  import { buildConceptKVKey } from '../../utils/KVKeysBuilders';
10
10
  import { AppContext } from '../base/AppContext';
@@ -124,33 +124,33 @@ export class ConceptService {
124
124
  private parseBasicInfoResponse(response: string): {
125
125
  nameEN: string;
126
126
  descriptionEN: string;
127
- poemEN: string;
127
+ poemEN: string[];
128
128
  namePT: string;
129
129
  descriptionPT: string;
130
- poemPT: string;
130
+ poemPT: string[];
131
131
  } {
132
132
  console.log('📌 Parsing basic info response from ChatGPT:', response);
133
-
133
+
134
134
  const enMatch = response.match(
135
135
  /EN:\s*•\s*Name:\s*(.+?)\s*•\s*Description:\s*([\s\S]+?)\s*•\s*Poetic Passage:\s*([\s\S]+?)\s*(?=PT:|$)/
136
136
  );
137
137
  const ptMatch = response.match(
138
138
  /PT:\s*•\s*Nome:\s*(.+?)\s*•\s*Descrição:\s*([\s\S]+?)\s*•\s*Passagem Poética:\s*([\s\S]+)/
139
139
  );
140
-
140
+
141
141
  if (!enMatch || !ptMatch) {
142
142
  console.error('❌ Invalid basic info response format:', response);
143
143
  throw new Error('Invalid basic info response format');
144
144
  }
145
-
145
+
146
146
  const nameEN = enMatch[1].trim();
147
147
  const descriptionEN = enMatch[2].trim();
148
- const poemEN = enMatch[3].trim();
149
-
148
+ const poemEN = enMatch[3].trim().split(/\n+/).map(line => line.trim()); // ✅ Split into array
149
+
150
150
  const namePT = ptMatch[1].trim();
151
151
  const descriptionPT = ptMatch[2].trim();
152
- const poemPT = ptMatch[3].trim();
153
-
152
+ const poemPT = ptMatch[3].trim().split(/\n+/).map(line => line.trim()); // ✅ Split into array
153
+
154
154
  console.log('✅ Successfully parsed basic info:', {
155
155
  nameEN,
156
156
  descriptionEN,
@@ -159,7 +159,7 @@ export class ConceptService {
159
159
  descriptionPT,
160
160
  poemPT,
161
161
  });
162
-
162
+
163
163
  return { nameEN, descriptionEN, poemEN, namePT, descriptionPT, poemPT };
164
164
  }
165
165
 
@@ -267,15 +267,20 @@ export class ConceptService {
267
267
 
268
268
  phase = "parsing"; // ✅ Switch to parsing phase
269
269
 
270
- // ✅ Store content in KV
271
- Object.assign(conceptEN, { content: response.trim() });
272
- Object.assign(conceptPT, { content: response.trim() });
270
+ // ✅ Parse structured content for both languages
271
+ const { structuredContentEN, structuredContentPT } =
272
+ this.parseStructuredContent(response);
273
273
 
274
+ // 🌍 Store English content
275
+ Object.assign(conceptEN, { content: structuredContentEN });
274
276
  await kvStore.put(kvKeyEN, JSON.stringify(conceptEN));
277
+
278
+ // 🇧🇷 Store Portuguese content
279
+ Object.assign(conceptPT, { content: structuredContentPT });
275
280
  await kvStore.put(kvKeyPT, JSON.stringify(conceptPT));
276
281
 
277
282
  console.log(
278
- `✅ Content stored for ${conceptSlug}, combination: ${combinationString}, in both languages.`
283
+ `✅ Structured content stored for ${conceptSlug}, combination: ${combinationString}, in both languages.`
279
284
  );
280
285
  return; // ✅ Exit loop if successful
281
286
 
@@ -303,6 +308,61 @@ export class ConceptService {
303
308
  }
304
309
  }
305
310
 
311
+ private parseStructuredContent(response: string): {
312
+ structuredContentEN: StructuredConceptContent;
313
+ structuredContentPT: StructuredConceptContent;
314
+ } {
315
+ console.log('📌 Parsing structured content from ChatGPT response:', response);
316
+
317
+ const sections = [
318
+ "Core Identity",
319
+ "Strengths and Challenges",
320
+ "Path to Fulfillment",
321
+ "Emotional Depth",
322
+ "Vision and Aspirations"
323
+ ];
324
+
325
+ const sectionsPT = [
326
+ "Identidade Essencial",
327
+ "Forças e Desafios",
328
+ "Caminho para a Plenitude",
329
+ "Profundidade Emocional",
330
+ "Visão e Aspirações"
331
+ ];
332
+
333
+ // ✅ Match English and Portuguese content separately
334
+ const enMatches = response.match(/EN:\s*([\s\S]+?)\s*PT:/);
335
+ const ptMatches = response.match(/PT:\s*([\s\S]+)/);
336
+
337
+ if (!enMatches || !ptMatches) {
338
+ throw new Error("❌ Missing English or Portuguese content in response.");
339
+ }
340
+
341
+ const enContent = enMatches[1].trim();
342
+ const ptContent = ptMatches[1].trim();
343
+
344
+ function extractSections(text: string, sectionTitles: string[]) {
345
+ return sectionTitles.map((title) => {
346
+ const regex = new RegExp(`${title}:\\s*([\\s\\S]+?)(?=\\n\\d|$)`);
347
+ const match = text.match(regex);
348
+
349
+ if (!match) {
350
+ return { type: "section", title, content: ["❌ Section Missing"] };
351
+ }
352
+
353
+ // ✅ Split content into paragraphs
354
+ const paragraphs = match[1].trim().split(/\n\n+/).map((p) => p.trim());
355
+
356
+ return { type: "section", title, content: paragraphs };
357
+ });
358
+ }
359
+
360
+ return {
361
+ structuredContentEN: extractSections(enContent, sections),
362
+ structuredContentPT: extractSections(ptContent, sectionsPT),
363
+ };
364
+ }
365
+
306
366
  /**
307
367
  * Queue image generation for a concept.
308
368
  */
@@ -470,8 +530,8 @@ export class ConceptService {
470
530
  return {
471
531
  name: '',
472
532
  description: '',
473
- content: '',
474
- poem: '',
533
+ content: [],
534
+ poem: [],
475
535
  leonardoPrompt: '',
476
536
  postImages: [],
477
537
  reelImages: [null, null, null],
@@ -9,7 +9,8 @@ export class ConceptWorkflow {
9
9
  async processSingle(
10
10
  conceptSlug: Concept,
11
11
  combinationString: string,
12
- phase: ConceptPhase
12
+ phase: ConceptPhase,
13
+ override?: boolean
13
14
  ) {
14
15
  console.log(
15
16
  `Processing single concept for slug: ${conceptSlug}, combination: ${combinationString}, phase: ${phase}`
@@ -20,13 +21,15 @@ export class ConceptWorkflow {
20
21
  case 'basic-info':
21
22
  await this.conceptService.generateBasicInfo(
22
23
  conceptSlug,
23
- combinationString
24
+ combinationString,
25
+ override
24
26
  );
25
27
  break;
26
28
  case 'content':
27
29
  await this.conceptService.generateContent(
28
30
  conceptSlug,
29
- combinationString
31
+ combinationString,
32
+ override
30
33
  );
31
34
  break;
32
35
  case 'leonardo-prompt':
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zodic/shared",
3
- "version": "0.0.142",
3
+ "version": "0.0.144",
4
4
  "module": "index.ts",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -109,14 +109,20 @@ export type KVArchetype = {
109
109
  export type KVConcept = {
110
110
  name: string;
111
111
  description: string;
112
- content: string;
113
- poem: string;
112
+ content: StructuredConceptContent;
113
+ poem: string[]; // Now an array of strings (each line as an element)
114
114
  leonardoPrompt: string;
115
- postImages: LeonardoImage[]; // Pre-generated in sequence
116
- reelImages: Array<LeonardoImage | null>; // Initially null, aligned by index
115
+ postImages: LeonardoImage[];
116
+ reelImages: Array<LeonardoImage | null>;
117
117
  status: 'idle' | 'generating' | 'completed';
118
118
  };
119
119
 
120
+ export type StructuredConceptContent = {
121
+ type: string;
122
+ title: string;
123
+ content: string[];
124
+ }[];
125
+
120
126
  export type KVGenerationObject = {
121
127
  crown: string;
122
128
  gender: Gender;
@@ -143,11 +143,12 @@ export const buildLLMMessages = (env: BackendBindings) => ({
143
143
  }: {
144
144
  name: string;
145
145
  description: string;
146
- poem: string;
146
+ poem: string[];
147
147
  conceptSlug: Concept;
148
148
  combination: string;
149
149
  }): ChatMessages => {
150
150
  const zodiacCombination = mapConceptToPlanets(conceptSlug, combination);
151
+ const formattedPoem = poem.map((line) => `${line}`).join('\n');
151
152
 
152
153
  return [
153
154
  {
@@ -157,14 +158,15 @@ export const buildLLMMessages = (env: BackendBindings) => ({
157
158
  {
158
159
  role: 'user',
159
160
  content: `
160
- Concept Details:
161
- - Combination: ${zodiacCombination}
162
- - Name: ${name}
163
- - Description: ${description}
164
- - Poem: ${poem}
165
-
166
- Generate additional content to elaborate on this concept for frontend display.
167
- `,
161
+ Concept Details:
162
+ - Combination: ${zodiacCombination}
163
+ - Name: ${name}
164
+ - Description: ${description}
165
+ - Poem:
166
+ ${formattedPoem}
167
+
168
+ Generate additional content to elaborate on this concept for frontend display.
169
+ `,
168
170
  },
169
171
  ];
170
172
  },