@zodic/shared 0.0.378 → 0.0.380

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.
@@ -858,25 +858,29 @@ export class ArchetypeService {
858
858
  rawResponse: ptResponse,
859
859
  });
860
860
 
861
- await this.log('debug', `Parsing PT content response for archetype ${index}`);
862
- const ptContent = this.parseContentResponse(ptResponse, 'PT');
863
- await this.log('info', `Parsed PT content for archetype ${index}`, { ptContent });
861
+ await this.log('debug', `Parsing PT-M content response for archetype ${index}`);
862
+ const ptMaleContentParsed = this.parseContentResponse(ptResponse, 'PT', 'male');
863
+ await this.log('info', `Parsed PT-M content for archetype ${index}`, { ptMaleContentParsed });
864
+
865
+ await this.log('debug', `Parsing PT-F content response for archetype ${index}`);
866
+ const ptFemaleContentParsed = this.parseContentResponse(ptResponse, 'PT', 'female');
867
+ await this.log('info', `Parsed PT-F content for archetype ${index}`, { ptFemaleContentParsed });
864
868
 
865
869
  const ptMaleContent = [
866
- { section: 'voiceOfTheSoul', text: ptContent.voiceOfTheSoul },
867
- { section: 'giftsYouBear', text: ptContent.giftsYouBear },
868
- { section: 'shadowsYouFace', text: ptContent.shadowsYouFace },
869
- { section: 'rhythmOfYourDays', text: ptContent.rhythmOfYourDays },
870
- { section: 'tiesThatBind', text: ptContent.tiesThatBind },
871
- { section: 'lightWithin', text: ptContent.lightWithin },
870
+ { section: 'voiceOfTheSoul', text: ptMaleContentParsed.voiceOfTheSoul },
871
+ { section: 'giftsYouBear', text: ptMaleContentParsed.giftsYouBear },
872
+ { section: 'shadowsYouFace', text: ptMaleContentParsed.shadowsYouFace },
873
+ { section: 'rhythmOfYourDays', text: ptMaleContentParsed.rhythmOfYourDays },
874
+ { section: 'tiesThatBind', text: ptMaleContentParsed.tiesThatBind },
875
+ { section: 'lightWithin', text: ptMaleContentParsed.lightWithin },
872
876
  ];
873
877
  const ptFemaleContent = [
874
- { section: 'voiceOfTheSoul', text: ptContent.voiceOfTheSoul.replace(/ele/g, 'ela').replace(/seu/g, 'sua') },
875
- { section: 'giftsYouBear', text: ptContent.giftsYouBear.replace(/ele/g, 'ela').replace(/seu/g, 'sua') },
876
- { section: 'shadowsYouFace', text: ptContent.shadowsYouFace.replace(/ele/g, 'ela').replace(/seu/g, 'sua') },
877
- { section: 'rhythmOfYourDays', text: ptContent.rhythmOfYourDays.replace(/ele/g, 'ela').replace(/seu/g, 'sua') },
878
- { section: 'tiesThatBind', text: ptContent.tiesThatBind.replace(/ele/g, 'ela').replace(/seu/g, 'sua') },
879
- { section: 'lightWithin', text: ptContent.lightWithin.replace(/ele/g, 'ela').replace(/seu/g, 'sua') },
878
+ { section: 'voiceOfTheSoul', text: ptFemaleContentParsed.voiceOfTheSoul },
879
+ { section: 'giftsYouBear', text: ptFemaleContentParsed.giftsYouBear },
880
+ { section: 'shadowsYouFace', text: ptFemaleContentParsed.shadowsYouFace },
881
+ { section: 'rhythmOfYourDays', text: ptFemaleContentParsed.rhythmOfYourDays },
882
+ { section: 'tiesThatBind', text: ptFemaleContentParsed.tiesThatBind },
883
+ { section: 'lightWithin', text: ptFemaleContentParsed.lightWithin },
880
884
  ];
881
885
 
882
886
  await this.log('debug', `Updating PT-M content for ${ptIds.male}`, { content: ptMaleContent });
@@ -921,71 +925,109 @@ export class ArchetypeService {
921
925
  return contentResults;
922
926
  }
923
927
 
924
- private parseContentResponse(response: string, section: string) {
925
- this.log('debug', 'Starting parseContentResponse', { responseLength: response.length, section });
928
+ private parseContentResponse(response: string, section: string, gender: Gender | null = null) {
929
+ this.log('debug', 'Starting parseContentResponse', { responseLength: response.length, section, gender });
926
930
 
927
- const lines = response.split('\n').filter((line) => line.trim());
931
+ const lines = response.split('\n').map(line => line.trim());
928
932
  this.log('debug', 'Split response into lines', { linesCount: lines.length, lines });
929
933
 
930
- const expectedHeader = `${section}:`;
931
- const actualHeader = lines[0].trim();
932
- if (!actualHeader.startsWith(expectedHeader)) {
933
- this.log('error', `Invalid language header for ${section}`, {
934
- expected: expectedHeader,
935
- found: actualHeader,
936
- });
937
- throw new Error(`Invalid language header for ${section}: expected ${expectedHeader}, got ${actualHeader}`);
934
+ // Skip initial --- and empty lines
935
+ let startIndex = 0;
936
+ while (startIndex < lines.length && (lines[startIndex] === '---' || lines[startIndex] === '')) {
937
+ startIndex++;
938
938
  }
939
939
 
940
- const content: Record<string, string> = {};
940
+ if (startIndex >= lines.length) {
941
+ this.log('error', `No content found after skipping delimiters for ${section}`, { response });
942
+ throw new Error(`No content found after skipping delimiters for ${section}`);
943
+ }
944
+
945
+ const content: Record<string, Record<string, string>> = { 'PT-M': {}, 'PT-F': {}, 'EN': {} };
946
+ let currentSectionHeader = '';
941
947
  let currentSection = '';
942
948
  let currentText: string[] = [];
949
+ let currentLang = '';
950
+
951
+ for (let i = startIndex; i < lines.length; i++) {
952
+ const line = lines[i];
953
+
954
+ if (line === '---') {
955
+ if (currentSection && currentText.length > 0) {
956
+ const key = currentSection.toLowerCase().replace(/\s+/g, '').replace(/([A-Z])/g, (match) => match.toLowerCase());
957
+ content[currentLang][key] = currentText.join(' ').trim();
958
+ this.log('debug', `Extracted section ${currentSection} for ${currentLang}`, { key, text: content[currentLang][key] });
959
+ }
960
+ currentSection = '';
961
+ currentText = [];
962
+ // Look for the next header
963
+ while (i + 1 < lines.length && (lines[i + 1] === '' || lines[i + 1] === '---')) {
964
+ i++;
965
+ }
966
+ if (i + 1 < lines.length && (lines[i + 1] === 'PT-M:' || lines[i + 1] === 'PT-F:' || lines[i + 1] === 'EN:')) {
967
+ i++;
968
+ currentLang = lines[i];
969
+ this.log('debug', `Found new language section: ${currentLang}`);
970
+ }
971
+ continue;
972
+ }
973
+
974
+ if (line === 'PT-M:' || line === 'PT-F:' || line === 'EN:') {
975
+ currentLang = line;
976
+ this.log('debug', `Starting language section: ${currentLang}`);
977
+ continue;
978
+ }
943
979
 
944
- for (const line of lines.slice(1)) {
945
980
  if (line.startsWith('#')) {
946
981
  if (currentSection && currentText.length > 0) {
947
982
  const key = currentSection.toLowerCase().replace(/\s+/g, '').replace(/([A-Z])/g, (match) => match.toLowerCase());
948
- content[key] = currentText.join(' ').trim();
949
- this.log('debug', `Extracted section ${currentSection} for ${section}`, {
950
- key,
951
- text: content[key],
952
- });
983
+ content[currentLang][key] = currentText.join(' ').trim();
984
+ this.log('debug', `Extracted section ${currentSection} for ${currentLang}`, { key, text: content[currentLang][key] });
953
985
  }
954
986
  currentSection = line.replace('# ', '');
987
+ currentSectionHeader = currentSection.toLowerCase();
955
988
  currentText = [];
956
- this.log('debug', `Starting new section ${currentSection} for ${section}`);
957
- } else {
989
+ this.log('debug', `Starting new section ${currentSection} for ${currentLang}`);
990
+ } else if (line) {
958
991
  currentText.push(line);
959
992
  }
960
993
  }
961
994
 
995
+ // Handle the last section
962
996
  if (currentSection && currentText.length > 0) {
963
997
  const key = currentSection.toLowerCase().replace(/\s+/g, '').replace(/([A-Z])/g, (match) => match.toLowerCase());
964
- content[key] = currentText.join(' ').trim();
965
- this.log('debug', `Extracted final section ${currentSection} for ${section}`, {
966
- key,
967
- text: content[key],
968
- });
998
+ content[currentLang][key] = currentText.join(' ').trim();
999
+ this.log('debug', `Extracted final section ${currentSection} for ${currentLang}`, { key, text: content[currentLang][key] });
1000
+ }
1001
+
1002
+ // Determine which content to return based on section and gender
1003
+ let targetLang = section;
1004
+ if (section === 'PT') {
1005
+ targetLang = gender === 'male' ? 'PT-M:' : 'PT-F:';
1006
+ } else {
1007
+ targetLang = `${section}:`;
1008
+ }
1009
+
1010
+ const targetContent = content[targetLang];
1011
+ if (!targetContent) {
1012
+ this.log('error', `No content found for target ${targetLang}`, { response, section, gender });
1013
+ throw new Error(`No content found for target ${targetLang}`);
969
1014
  }
970
1015
 
971
1016
  const parsedContent = {
972
- voiceOfTheSoul: content['thevoiceofthesoul'] || content['avozdaalma'] || '',
973
- giftsYouBear: content['thegiftsyoubear'] || content['osdonsquevocêcarrega'] || '',
974
- shadowsYouFace: content['theshadowsyouface'] || content['assombrasqueenfrenta'] || '',
975
- rhythmOfYourDays: content['therhythmofyourdays'] || content['oritmodosseusdias'] || '',
976
- tiesThatBind: content['thetiesthatbind'] || content['oslaçosqueteconectam'] || '',
977
- lightWithin: content['thelightwithin'] || content['aluzinterior'] || '',
1017
+ voiceOfTheSoul: targetContent['thevoiceofthesoul'] || targetContent['avozdaalma'] || '',
1018
+ giftsYouBear: targetContent['thegiftsyoubear'] || targetContent['osdonsquevocêcarrega'] || '',
1019
+ shadowsYouFace: targetContent['theshadowsyouface'] || targetContent['assombrasqueenfrenta'] || '',
1020
+ rhythmOfYourDays: targetContent['therhythmofyourdays'] || targetContent['oritmodosseusdias'] || '',
1021
+ tiesThatBind: targetContent['thetiesthatbind'] || targetContent['oslaçosqueteconectam'] || '',
1022
+ lightWithin: targetContent['thelightwithin'] || targetContent['aluzinterior'] || '',
978
1023
  };
979
1024
 
980
1025
  if (Object.values(parsedContent).some((value) => !value)) {
981
- this.log('error', `Malformed content response for ${section}`, {
982
- parsedContent,
983
- response,
984
- });
985
- throw new Error(`Malformed content response for ${section}`);
1026
+ this.log('error', `Malformed content response for ${targetLang}`, { parsedContent, response });
1027
+ throw new Error(`Malformed content response for ${targetLang}`);
986
1028
  }
987
1029
 
988
- this.log('info', 'Completed parseContentResponse', { parsedContent, section });
1030
+ this.log('info', 'Completed parseContentResponse', { parsedContent, section, gender });
989
1031
  return parsedContent;
990
1032
  }
991
1033
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zodic/shared",
3
- "version": "0.0.378",
3
+ "version": "0.0.380",
4
4
  "module": "index.ts",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -240,7 +240,7 @@ export const buildLLMMessages = (env: BackendBindings) => ({
240
240
 
241
241
  Your response must be insightful, symbolic, and restrained. Focus on personality traits, behaviors, and subtle symbolic elements inspired by the archetypal energies of the Sun, Ascendant, and Moon signs, conveyed through elegant metaphors and thoughtful storytelling. Avoid overly fantastical or magical imagery like glowing lights, ethereal realms, or supernatural abilities, and instead emphasize a grounded, sober tone while maintaining a mystical depth.
242
242
 
243
- Do not include the archetype name in the content itself. Describe the archetype based on its description and the archetypal energies without repeating its name.
243
+ Do not include the archetype name in the content itself. Describe the archetype based on its description and the archetypal energies without repeating its name. Also, do not use the character "—" in the text.
244
244
 
245
245
  Generate content in **English** (gender-neutral).
246
246
 
@@ -315,7 +315,7 @@ export const buildLLMMessages = (env: BackendBindings) => ({
315
315
 
316
316
  Your response must be insightful, symbolic, and restrained. Focus on personality traits, behaviors, and subtle symbolic elements inspired by the archetypal energies of the Sun, Ascendant, and Moon signs, conveyed through elegant metaphors and thoughtful storytelling. Avoid overly fantastical or magical imagery like glowing lights, ethereal realms, or supernatural abilities, and instead emphasize a grounded, sober tone while maintaining a mystical depth.
317
317
 
318
- Do not include the archetype name in the content itself. Describe the archetype based on its description and the archetypal energies without repeating its name.
318
+ Do not include the archetype name in the content itself. Describe the archetype based on its description and the archetypal energies without repeating its name. Also, do not use the character "—" in the text.
319
319
 
320
320
  Generate content in **Brazilian Portuguese**, with both **masculine and feminine** phrasing. Content and metaphors should remain identical; only adapt gendered language.
321
321