@zodic/shared 0.0.377 → 0.0.379
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 +229 -256
- package/package.json +1 -1
- package/utils/buildMessages.ts +171 -0
|
@@ -690,11 +690,11 @@ export class ArchetypeService {
|
|
|
690
690
|
language,
|
|
691
691
|
override,
|
|
692
692
|
});
|
|
693
|
-
|
|
693
|
+
|
|
694
694
|
const db = this.context.drizzle();
|
|
695
695
|
const allGenders: Gender[] = ['male', 'female'];
|
|
696
696
|
const archetypesByGender: Record<Gender, any[]> = { male: [], female: [] };
|
|
697
|
-
|
|
697
|
+
|
|
698
698
|
for (const g of allGenders) {
|
|
699
699
|
const archetypes = await db
|
|
700
700
|
.select()
|
|
@@ -710,20 +710,20 @@ export class ArchetypeService {
|
|
|
710
710
|
.execute();
|
|
711
711
|
archetypesByGender[g] = archetypes;
|
|
712
712
|
}
|
|
713
|
-
|
|
713
|
+
|
|
714
714
|
const needsGeneration = allGenders.some(
|
|
715
715
|
(g) =>
|
|
716
716
|
archetypesByGender[g].length !== 3 ||
|
|
717
717
|
archetypesByGender[g].some((a) => a.content === '[]')
|
|
718
718
|
);
|
|
719
|
-
|
|
719
|
+
|
|
720
720
|
if (!override && !needsGeneration) {
|
|
721
721
|
await this.log('info', 'Skipping content generation', {
|
|
722
722
|
reason: 'Content already exists for all archetypes',
|
|
723
723
|
});
|
|
724
724
|
return;
|
|
725
725
|
}
|
|
726
|
-
|
|
726
|
+
|
|
727
727
|
await this.log('info', 'Fetched archetypes for content generation', {
|
|
728
728
|
maleArchetypes: archetypesByGender['male'].map((a) => ({
|
|
729
729
|
id: a.id,
|
|
@@ -736,130 +736,71 @@ export class ArchetypeService {
|
|
|
736
736
|
index: a.archetypeIndex,
|
|
737
737
|
})),
|
|
738
738
|
});
|
|
739
|
-
|
|
739
|
+
|
|
740
740
|
const contentResults = [];
|
|
741
741
|
for (let i = 0; i < 3; i++) {
|
|
742
742
|
const index = (i + 1).toString();
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
if (!override && archetype.content !== '[]') {
|
|
764
|
-
await this.log('debug', `Skipping existing content for ${id}`, {
|
|
765
|
-
content: archetype.content,
|
|
766
|
-
archetypeIndex: index,
|
|
767
|
-
gender: g,
|
|
768
|
-
language,
|
|
769
|
-
});
|
|
770
|
-
if (g === 'male') contentResults.push({}); // Placeholder for male only
|
|
771
|
-
continue;
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
await this.log(
|
|
775
|
-
'debug',
|
|
776
|
-
`Generating content for archetype ${index} (${g})`,
|
|
777
|
-
{ name: archetype.name }
|
|
778
|
-
);
|
|
779
|
-
const contentMessages = this.context
|
|
743
|
+
const archetype = archetypesByGender['male'][i];
|
|
744
|
+
if (!archetype || archetype.archetypeIndex !== index) {
|
|
745
|
+
await this.log('error', `Archetype index mismatch at position ${i + 1}`, {
|
|
746
|
+
expectedIndex: index,
|
|
747
|
+
actualIndex: archetype?.archetypeIndex,
|
|
748
|
+
archetypeId: archetype?.id,
|
|
749
|
+
});
|
|
750
|
+
throw new Error(`Archetype index mismatch: expected ${index}, got ${archetype?.archetypeIndex}`);
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
// Generate EN content
|
|
754
|
+
const enId = `${combinationString}:male:${index}${language === 'en-us' ? '' : ':pt'}`;
|
|
755
|
+
if (!override && archetypesByGender['male'][i].content !== '[]') {
|
|
756
|
+
await this.log('debug', `Skipping existing EN content for ${enId}`, {
|
|
757
|
+
content: archetypesByGender['male'][i].content,
|
|
758
|
+
archetypeIndex: index,
|
|
759
|
+
});
|
|
760
|
+
} else {
|
|
761
|
+
await this.log('debug', `Generating EN content for archetype ${index}`, { name: archetype.name });
|
|
762
|
+
const enMessages = this.context
|
|
780
763
|
.buildLLMMessages()
|
|
781
|
-
.
|
|
782
|
-
combination: combinationString,
|
|
764
|
+
.generateCosmicMirrorArchetypeContentEN({
|
|
783
765
|
name: archetype.name,
|
|
784
766
|
description: descriptions[i].descriptionEN,
|
|
767
|
+
combination: combinationString,
|
|
785
768
|
});
|
|
786
|
-
|
|
787
|
-
await this.log(
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
)
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
'error',
|
|
798
|
-
`No response for content of archetype ${index} (${g})`,
|
|
799
|
-
{
|
|
800
|
-
combinationString,
|
|
801
|
-
archetype: archetype.name,
|
|
802
|
-
}
|
|
803
|
-
);
|
|
804
|
-
throw new Error(
|
|
805
|
-
`Failed to generate content for archetype ${index} (${g}) of: ${combinationString}`
|
|
806
|
-
);
|
|
769
|
+
|
|
770
|
+
await this.log('debug', `Calling API for EN content of archetype ${index}`, { messages: enMessages });
|
|
771
|
+
const enResponse = await this.context.api().callTogether.single(enMessages, {
|
|
772
|
+
options: { max_tokens: 4096 },
|
|
773
|
+
});
|
|
774
|
+
if (!enResponse) {
|
|
775
|
+
await this.log('error', `No response for EN content of archetype ${index}`, {
|
|
776
|
+
combinationString,
|
|
777
|
+
archetype: archetype.name,
|
|
778
|
+
});
|
|
779
|
+
throw new Error(`Failed to generate EN content for archetype ${index} of: ${combinationString}`);
|
|
807
780
|
}
|
|
808
|
-
await this.log(
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
{
|
|
812
|
-
responseLength: contentResponse.length,
|
|
813
|
-
rawResponse: contentResponse, // Log raw response for debugging
|
|
814
|
-
}
|
|
815
|
-
);
|
|
816
|
-
|
|
817
|
-
await this.log(
|
|
818
|
-
'debug',
|
|
819
|
-
`Parsing content response for archetype ${index} (${g})`
|
|
820
|
-
);
|
|
821
|
-
const parsedContent = this.parseContentResponse(contentResponse);
|
|
822
|
-
if (g === 'male') contentResults.push(parsedContent);
|
|
823
|
-
await this.log('info', `Parsed content for archetype ${index} (${g})`, {
|
|
824
|
-
parsedContent,
|
|
781
|
+
await this.log('info', `Received EN content response for archetype ${index}`, {
|
|
782
|
+
responseLength: enResponse.length,
|
|
783
|
+
rawResponse: enResponse,
|
|
825
784
|
});
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
785
|
+
|
|
786
|
+
await this.log('debug', `Parsing EN content response for archetype ${index}`);
|
|
787
|
+
const enContent = this.parseContentResponse(enResponse, 'EN');
|
|
788
|
+
await this.log('info', `Parsed EN content for archetype ${index}`, { enContent });
|
|
789
|
+
|
|
829
790
|
const content = [
|
|
830
|
-
{
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
},
|
|
834
|
-
{
|
|
835
|
-
|
|
836
|
-
text: parsedContent[contentLangIndex].giftsYouBear,
|
|
837
|
-
},
|
|
838
|
-
{
|
|
839
|
-
section: 'shadowsYouFace',
|
|
840
|
-
text: parsedContent[contentLangIndex].shadowsYouFace,
|
|
841
|
-
},
|
|
842
|
-
{
|
|
843
|
-
section: 'rhythmOfYourDays',
|
|
844
|
-
text: parsedContent[contentLangIndex].rhythmOfYourDays,
|
|
845
|
-
},
|
|
846
|
-
{
|
|
847
|
-
section: 'tiesThatBind',
|
|
848
|
-
text: parsedContent[contentLangIndex].tiesThatBind,
|
|
849
|
-
},
|
|
850
|
-
{
|
|
851
|
-
section: 'lightWithin',
|
|
852
|
-
text: parsedContent[contentLangIndex].lightWithin,
|
|
853
|
-
},
|
|
791
|
+
{ section: 'voiceOfTheSoul', text: enContent.voiceOfTheSoul },
|
|
792
|
+
{ section: 'giftsYouBear', text: enContent.giftsYouBear },
|
|
793
|
+
{ section: 'shadowsYouFace', text: enContent.shadowsYouFace },
|
|
794
|
+
{ section: 'rhythmOfYourDays', text: enContent.rhythmOfYourDays },
|
|
795
|
+
{ section: 'tiesThatBind', text: enContent.tiesThatBind },
|
|
796
|
+
{ section: 'lightWithin', text: enContent.lightWithin },
|
|
854
797
|
];
|
|
855
|
-
|
|
856
|
-
await this.log('debug', `Updating content for ${
|
|
798
|
+
|
|
799
|
+
await this.log('debug', `Updating EN content for ${enId}`, {
|
|
857
800
|
content,
|
|
858
801
|
archetypeIndex: index,
|
|
859
|
-
gender: g,
|
|
860
|
-
language,
|
|
861
802
|
});
|
|
862
|
-
|
|
803
|
+
|
|
863
804
|
await db
|
|
864
805
|
.update(schema.archetypesData)
|
|
865
806
|
.set({
|
|
@@ -868,163 +809,195 @@ export class ArchetypeService {
|
|
|
868
809
|
})
|
|
869
810
|
.where(
|
|
870
811
|
and(
|
|
871
|
-
eq(schema.archetypesData.id,
|
|
872
|
-
eq(schema.archetypesData.language,
|
|
873
|
-
eq(schema.archetypesData.gender,
|
|
812
|
+
eq(schema.archetypesData.id, enId),
|
|
813
|
+
eq(schema.archetypesData.language, 'en-us'),
|
|
814
|
+
eq(schema.archetypesData.gender, 'male'),
|
|
874
815
|
eq(schema.archetypesData.archetypeIndex, index)
|
|
875
816
|
)
|
|
876
817
|
)
|
|
877
818
|
.execute();
|
|
878
|
-
|
|
879
|
-
await this.log('info', `Updated content for ${
|
|
819
|
+
|
|
820
|
+
await this.log('info', `Updated EN content for ${enId}`);
|
|
821
|
+
contentResults.push(enContent);
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
// Generate PT content (both male and female)
|
|
825
|
+
const ptIds = {
|
|
826
|
+
male: `${combinationString}:male:${index}:pt`,
|
|
827
|
+
female: `${combinationString}:female:${index}:pt`,
|
|
828
|
+
};
|
|
829
|
+
if (!override && archetypesByGender['male'][i].content !== '[]' && archetypesByGender['female'][i].content !== '[]') {
|
|
830
|
+
await this.log('debug', `Skipping existing PT content for ${ptIds.male} and ${ptIds.female}`, {
|
|
831
|
+
maleContent: archetypesByGender['male'][i].content,
|
|
832
|
+
femaleContent: archetypesByGender['female'][i].content,
|
|
833
|
+
archetypeIndex: index,
|
|
834
|
+
});
|
|
835
|
+
} else {
|
|
836
|
+
await this.log('debug', `Generating PT content for archetype ${index}`, { name: archetype.name });
|
|
837
|
+
const ptMessages = this.context
|
|
838
|
+
.buildLLMMessages()
|
|
839
|
+
.generateCosmicMirrorArchetypeContentPT({
|
|
840
|
+
name: archetype.name,
|
|
841
|
+
description: descriptions[i].descriptionEN,
|
|
842
|
+
combination: combinationString,
|
|
843
|
+
});
|
|
844
|
+
|
|
845
|
+
await this.log('debug', `Calling API for PT content of archetype ${index}`, { messages: ptMessages });
|
|
846
|
+
const ptResponse = await this.context.api().callTogether.single(ptMessages, {
|
|
847
|
+
options: { max_tokens: 8192 },
|
|
848
|
+
});
|
|
849
|
+
if (!ptResponse) {
|
|
850
|
+
await this.log('error', `No response for PT content of archetype ${index}`, {
|
|
851
|
+
combinationString,
|
|
852
|
+
archetype: archetype.name,
|
|
853
|
+
});
|
|
854
|
+
throw new Error(`Failed to generate PT content for archetype ${index} of: ${combinationString}`);
|
|
855
|
+
}
|
|
856
|
+
await this.log('info', `Received PT content response for archetype ${index}`, {
|
|
857
|
+
responseLength: ptResponse.length,
|
|
858
|
+
rawResponse: ptResponse,
|
|
859
|
+
});
|
|
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 });
|
|
864
|
+
|
|
865
|
+
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 },
|
|
872
|
+
];
|
|
873
|
+
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') },
|
|
880
|
+
];
|
|
881
|
+
|
|
882
|
+
await this.log('debug', `Updating PT-M content for ${ptIds.male}`, { content: ptMaleContent });
|
|
883
|
+
await db
|
|
884
|
+
.update(schema.archetypesData)
|
|
885
|
+
.set({
|
|
886
|
+
content: JSON.stringify(ptMaleContent),
|
|
887
|
+
updatedAt: new Date().getTime(),
|
|
888
|
+
})
|
|
889
|
+
.where(
|
|
890
|
+
and(
|
|
891
|
+
eq(schema.archetypesData.id, ptIds.male),
|
|
892
|
+
eq(schema.archetypesData.language, 'pt-br'),
|
|
893
|
+
eq(schema.archetypesData.gender, 'male'),
|
|
894
|
+
eq(schema.archetypesData.archetypeIndex, index)
|
|
895
|
+
)
|
|
896
|
+
)
|
|
897
|
+
.execute();
|
|
898
|
+
await this.log('info', `Updated PT-M content for ${ptIds.male}`);
|
|
899
|
+
|
|
900
|
+
await this.log('debug', `Updating PT-F content for ${ptIds.female}`, { content: ptFemaleContent });
|
|
901
|
+
await db
|
|
902
|
+
.update(schema.archetypesData)
|
|
903
|
+
.set({
|
|
904
|
+
content: JSON.stringify(ptFemaleContent),
|
|
905
|
+
updatedAt: new Date().getTime(),
|
|
906
|
+
})
|
|
907
|
+
.where(
|
|
908
|
+
and(
|
|
909
|
+
eq(schema.archetypesData.id, ptIds.female),
|
|
910
|
+
eq(schema.archetypesData.language, 'pt-br'),
|
|
911
|
+
eq(schema.archetypesData.gender, 'female'),
|
|
912
|
+
eq(schema.archetypesData.archetypeIndex, index)
|
|
913
|
+
)
|
|
914
|
+
)
|
|
915
|
+
.execute();
|
|
916
|
+
await this.log('info', `Updated PT-F content for ${ptIds.female}`);
|
|
880
917
|
}
|
|
881
918
|
}
|
|
882
|
-
|
|
883
|
-
await this.log('info', 'Completed generateContent', {
|
|
884
|
-
combinationString,
|
|
885
|
-
gender,
|
|
886
|
-
language,
|
|
887
|
-
});
|
|
919
|
+
|
|
920
|
+
await this.log('info', 'Completed generateContent', { combinationString, gender, language });
|
|
888
921
|
return contentResults;
|
|
889
922
|
}
|
|
890
923
|
|
|
891
|
-
private parseContentResponse(response: string) {
|
|
892
|
-
this.log('debug', 'Starting parseContentResponse', {
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
sectionsCount: sections.length,
|
|
902
|
-
});
|
|
903
|
-
|
|
904
|
-
if (sections.length !== 3) {
|
|
905
|
-
this.log('error', 'Expected exactly 3 content sections', {
|
|
906
|
-
sectionsCount: sections.length,
|
|
907
|
-
response,
|
|
908
|
-
});
|
|
909
|
-
throw new Error(`Expected 3 content sections, got ${sections.length}`);
|
|
924
|
+
private parseContentResponse(response: string, section: string) {
|
|
925
|
+
this.log('debug', 'Starting parseContentResponse', { responseLength: response.length, section });
|
|
926
|
+
|
|
927
|
+
const lines = response.split('\n').map(line => line.trim()); // Trim each line
|
|
928
|
+
this.log('debug', 'Split response into lines', { linesCount: lines.length, lines });
|
|
929
|
+
|
|
930
|
+
// Skip initial --- and any empty lines
|
|
931
|
+
let startIndex = 0;
|
|
932
|
+
while (startIndex < lines.length && (lines[startIndex] === '---' || lines[startIndex] === '')) {
|
|
933
|
+
startIndex++;
|
|
910
934
|
}
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
this.log('
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
935
|
+
|
|
936
|
+
if (startIndex >= lines.length) {
|
|
937
|
+
this.log('error', `No content found after skipping delimiters for ${section}`, { response });
|
|
938
|
+
throw new Error(`No content found after skipping delimiters for ${section}`);
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
const expectedHeader = `${section}:`;
|
|
942
|
+
const actualHeader = lines[startIndex];
|
|
943
|
+
if (!actualHeader.startsWith(expectedHeader)) {
|
|
944
|
+
this.log('error', `Invalid language header for ${section}`, {
|
|
945
|
+
expected: expectedHeader,
|
|
946
|
+
found: actualHeader,
|
|
919
947
|
});
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
throw new Error(
|
|
934
|
-
`Invalid language header in section ${sectionIndex + 1}`
|
|
935
|
-
);
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
const content: Record<string, string> = {};
|
|
939
|
-
let currentSection = '';
|
|
940
|
-
let currentText: string[] = [];
|
|
941
|
-
|
|
942
|
-
for (const line of lines.slice(1)) {
|
|
943
|
-
if (line.startsWith('#')) {
|
|
944
|
-
if (currentSection && currentText.length > 0) {
|
|
945
|
-
const key = currentSection
|
|
946
|
-
.toLowerCase()
|
|
947
|
-
.replace(/\s+/g, '')
|
|
948
|
-
.replace(/([A-Z])/g, (match) => match.toLowerCase());
|
|
949
|
-
content[key] = currentText.join(' ').trim();
|
|
950
|
-
this.log(
|
|
951
|
-
'debug',
|
|
952
|
-
`Extracted section ${currentSection} in section ${
|
|
953
|
-
sectionIndex + 1
|
|
954
|
-
}`,
|
|
955
|
-
{
|
|
956
|
-
key,
|
|
957
|
-
text: content[key],
|
|
958
|
-
}
|
|
959
|
-
);
|
|
960
|
-
}
|
|
961
|
-
currentSection = line.replace('# ', '');
|
|
962
|
-
currentText = [];
|
|
963
|
-
this.log(
|
|
964
|
-
'debug',
|
|
965
|
-
`Starting new section ${currentSection} in section ${
|
|
966
|
-
sectionIndex + 1
|
|
967
|
-
}`
|
|
968
|
-
);
|
|
969
|
-
} else {
|
|
970
|
-
currentText.push(line);
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
|
|
974
|
-
if (currentSection && currentText.length > 0) {
|
|
975
|
-
const key = currentSection
|
|
976
|
-
.toLowerCase()
|
|
977
|
-
.replace(/\s+/g, '')
|
|
978
|
-
.replace(/([A-Z])/g, (match) => match.toLowerCase());
|
|
979
|
-
content[key] = currentText.join(' ').trim();
|
|
980
|
-
this.log(
|
|
981
|
-
'debug',
|
|
982
|
-
`Extracted final section ${currentSection} in section ${
|
|
983
|
-
sectionIndex + 1
|
|
984
|
-
}`,
|
|
985
|
-
{
|
|
948
|
+
throw new Error(`Invalid language header for ${section}: expected ${expectedHeader}, got ${actualHeader}`);
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
const content: Record<string, string> = {};
|
|
952
|
+
let currentSection = '';
|
|
953
|
+
let currentText: string[] = [];
|
|
954
|
+
|
|
955
|
+
for (const line of lines.slice(startIndex + 1)) {
|
|
956
|
+
if (line.startsWith('#')) {
|
|
957
|
+
if (currentSection && currentText.length > 0) {
|
|
958
|
+
const key = currentSection.toLowerCase().replace(/\s+/g, '').replace(/([A-Z])/g, (match) => match.toLowerCase());
|
|
959
|
+
content[key] = currentText.join(' ').trim();
|
|
960
|
+
this.log('debug', `Extracted section ${currentSection} for ${section}`, {
|
|
986
961
|
key,
|
|
987
962
|
text: content[key],
|
|
988
|
-
}
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
giftsYouBear:
|
|
996
|
-
content['thegiftsyoubear'] || content['osdonsquevocêcarrega'] || '',
|
|
997
|
-
shadowsYouFace:
|
|
998
|
-
content['theshadowsyouface'] || content['assombrasqueenfrenta'] || '',
|
|
999
|
-
rhythmOfYourDays:
|
|
1000
|
-
content['therhythmofyourdays'] || content['oritmodosseusdias'] || '',
|
|
1001
|
-
tiesThatBind:
|
|
1002
|
-
content['thetiesthatbind'] || content['oslaçosqueteconectam'] || '',
|
|
1003
|
-
lightWithin: content['thelightwithin'] || content['aluzinterior'] || '',
|
|
1004
|
-
};
|
|
1005
|
-
|
|
1006
|
-
if (Object.values(parsedContent).some((value) => !value)) {
|
|
1007
|
-
this.log(
|
|
1008
|
-
'error',
|
|
1009
|
-
`Malformed content response for section ${sectionIndex + 1}`,
|
|
1010
|
-
{
|
|
1011
|
-
parsedContent,
|
|
1012
|
-
response: section,
|
|
1013
|
-
}
|
|
1014
|
-
);
|
|
1015
|
-
throw new Error(
|
|
1016
|
-
`Malformed content response for section ${sectionIndex + 1}`
|
|
1017
|
-
);
|
|
963
|
+
});
|
|
964
|
+
}
|
|
965
|
+
currentSection = line.replace('# ', '');
|
|
966
|
+
currentText = [];
|
|
967
|
+
this.log('debug', `Starting new section ${currentSection} for ${section}`);
|
|
968
|
+
} else if (line) { // Ignore empty lines
|
|
969
|
+
currentText.push(line);
|
|
1018
970
|
}
|
|
1019
|
-
|
|
1020
|
-
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
if (currentSection && currentText.length > 0) {
|
|
974
|
+
const key = currentSection.toLowerCase().replace(/\s+/g, '').replace(/([A-Z])/g, (match) => match.toLowerCase());
|
|
975
|
+
content[key] = currentText.join(' ').trim();
|
|
976
|
+
this.log('debug', `Extracted final section ${currentSection} for ${section}`, {
|
|
977
|
+
key,
|
|
978
|
+
text: content[key],
|
|
979
|
+
});
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
const parsedContent = {
|
|
983
|
+
voiceOfTheSoul: content['thevoiceofthesoul'] || content['avozdaalma'] || '',
|
|
984
|
+
giftsYouBear: content['thegiftsyoubear'] || content['osdonsquevocêcarrega'] || '',
|
|
985
|
+
shadowsYouFace: content['theshadowsyouface'] || content['assombrasqueenfrenta'] || '',
|
|
986
|
+
rhythmOfYourDays: content['therhythmofyourdays'] || content['oritmodosseusdias'] || '',
|
|
987
|
+
tiesThatBind: content['thetiesthatbind'] || content['oslaçosqueteconectam'] || '',
|
|
988
|
+
lightWithin: content['thelightwithin'] || content['aluzinterior'] || '',
|
|
989
|
+
};
|
|
990
|
+
|
|
991
|
+
if (Object.values(parsedContent).some((value) => !value)) {
|
|
992
|
+
this.log('error', `Malformed content response for ${section}`, {
|
|
1021
993
|
parsedContent,
|
|
994
|
+
response,
|
|
1022
995
|
});
|
|
1023
|
-
|
|
1024
|
-
}
|
|
1025
|
-
|
|
1026
|
-
this.log('info', 'Completed parseContentResponse', {
|
|
1027
|
-
return
|
|
996
|
+
throw new Error(`Malformed content response for ${section}`);
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
this.log('info', 'Completed parseContentResponse', { parsedContent, section });
|
|
1000
|
+
return parsedContent;
|
|
1028
1001
|
}
|
|
1029
1002
|
|
|
1030
1003
|
async generateLeonardoPrompts(
|
package/package.json
CHANGED
package/utils/buildMessages.ts
CHANGED
|
@@ -221,6 +221,177 @@ export const buildLLMMessages = (env: BackendBindings) => ({
|
|
|
221
221
|
];
|
|
222
222
|
},
|
|
223
223
|
|
|
224
|
+
generateCosmicMirrorArchetypeContentEN: ({
|
|
225
|
+
name,
|
|
226
|
+
description,
|
|
227
|
+
combination,
|
|
228
|
+
}: {
|
|
229
|
+
name: string;
|
|
230
|
+
description: string;
|
|
231
|
+
combination: string;
|
|
232
|
+
}): ChatMessages => {
|
|
233
|
+
const [sun, ascendant, moon] = combination.split('-');
|
|
234
|
+
|
|
235
|
+
return [
|
|
236
|
+
{
|
|
237
|
+
role: 'system',
|
|
238
|
+
content: `
|
|
239
|
+
You are an expert in astrology and archetypal synthesis. Your task is to generate detailed **archetype content** based on a person's core archetype name, description, and Sun, Ascendant, and Moon signs.
|
|
240
|
+
|
|
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
|
+
|
|
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
|
+
|
|
245
|
+
Generate content in **English** (gender-neutral).
|
|
246
|
+
|
|
247
|
+
The content must include **six sections**, each with approximately **140 words**:
|
|
248
|
+
|
|
249
|
+
1. **The Voice of the Soul** – How the archetype expresses itself in daily life.
|
|
250
|
+
2. **The Gifts You Bear** – Strengths and contributions of the archetype.
|
|
251
|
+
3. **The Shadows You Face** – Challenges or inner conflicts.
|
|
252
|
+
4. **The Rhythm of Your Days** – Their lifestyle, habits, and inner tempo.
|
|
253
|
+
5. **The Ties That Bind** – Relationships and emotional connections.
|
|
254
|
+
6. **The Light Within** – Inner peace, fulfillment, and spiritual resonance.
|
|
255
|
+
|
|
256
|
+
—
|
|
257
|
+
|
|
258
|
+
✨ Output Format:
|
|
259
|
+
|
|
260
|
+
Return the full response in this exact format:
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
EN:
|
|
265
|
+
# The Voice of the Soul
|
|
266
|
+
[English version]
|
|
267
|
+
|
|
268
|
+
# The Gifts You Bear
|
|
269
|
+
[...]
|
|
270
|
+
|
|
271
|
+
# The Shadows You Face
|
|
272
|
+
[...]
|
|
273
|
+
|
|
274
|
+
# The Rhythm of Your Days
|
|
275
|
+
[...]
|
|
276
|
+
|
|
277
|
+
# The Ties That Bind
|
|
278
|
+
[...]
|
|
279
|
+
|
|
280
|
+
# The Light Within
|
|
281
|
+
[...]
|
|
282
|
+
`,
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
role: 'user',
|
|
286
|
+
content: `
|
|
287
|
+
Generate rich and mystical content for the following archetype:
|
|
288
|
+
|
|
289
|
+
• Archetype Name: ${name}
|
|
290
|
+
• Archetype Description: ${description}
|
|
291
|
+
• Sun Sign: ${sun}
|
|
292
|
+
• Ascendant Sign: ${ascendant}
|
|
293
|
+
• Moon Sign: ${moon}
|
|
294
|
+
`,
|
|
295
|
+
},
|
|
296
|
+
];
|
|
297
|
+
},
|
|
298
|
+
|
|
299
|
+
generateCosmicMirrorArchetypeContentPT: ({
|
|
300
|
+
name,
|
|
301
|
+
description,
|
|
302
|
+
combination,
|
|
303
|
+
}: {
|
|
304
|
+
name: string;
|
|
305
|
+
description: string;
|
|
306
|
+
combination: string;
|
|
307
|
+
}): ChatMessages => {
|
|
308
|
+
const [sun, ascendant, moon] = combination.split('-');
|
|
309
|
+
|
|
310
|
+
return [
|
|
311
|
+
{
|
|
312
|
+
role: 'system',
|
|
313
|
+
content: `
|
|
314
|
+
You are an expert in astrology and archetypal synthesis. Your task is to generate detailed **archetype content** based on a person's core archetype name, description, and Sun, Ascendant, and Moon signs.
|
|
315
|
+
|
|
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
|
+
|
|
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
|
+
|
|
320
|
+
Generate content in **Brazilian Portuguese**, with both **masculine and feminine** phrasing. Content and metaphors should remain identical; only adapt gendered language.
|
|
321
|
+
|
|
322
|
+
The content must include **six sections**, each with approximately **140 words**:
|
|
323
|
+
|
|
324
|
+
1. **A Voz da Alma** – Como o arquétipo se expressa na vida diária.
|
|
325
|
+
2. **Os Dons que Você Carrega** – Forças e contribuições do arquétipo.
|
|
326
|
+
3. **As Sombras que Enfrenta** – Desafios ou conflitos internos.
|
|
327
|
+
4. **O Ritmo dos Seus Dias** – Estilo de vida, hábitos e ritmo interior.
|
|
328
|
+
5. **Os Laços que te Conectam** – Relacionamentos e conexões emocionais.
|
|
329
|
+
6. **A Luz Interior** – Paz interior, realização e ressonância espiritual.
|
|
330
|
+
|
|
331
|
+
—
|
|
332
|
+
|
|
333
|
+
✨ Output Format:
|
|
334
|
+
|
|
335
|
+
Return the full response in this exact format:
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
PT-M:
|
|
340
|
+
# A Voz da Alma
|
|
341
|
+
[Versão masculina em português]
|
|
342
|
+
|
|
343
|
+
# Os Dons que Você Carrega
|
|
344
|
+
[...]
|
|
345
|
+
|
|
346
|
+
# As Sombras que Enfrenta
|
|
347
|
+
[...]
|
|
348
|
+
|
|
349
|
+
# O Ritmo dos Seus Dias
|
|
350
|
+
[...]
|
|
351
|
+
|
|
352
|
+
# Os Laços que te Conectam
|
|
353
|
+
[...]
|
|
354
|
+
|
|
355
|
+
# A Luz Interior
|
|
356
|
+
[...]
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
PT-F:
|
|
361
|
+
# A Voz da Alma
|
|
362
|
+
[Versão feminina em português]
|
|
363
|
+
|
|
364
|
+
# Os Dons que Você Carrega
|
|
365
|
+
[...]
|
|
366
|
+
|
|
367
|
+
# As Sombras que Enfrenta
|
|
368
|
+
[...]
|
|
369
|
+
|
|
370
|
+
# O Ritmo dos Seus Dias
|
|
371
|
+
[...]
|
|
372
|
+
|
|
373
|
+
# Os Laços que te Conectam
|
|
374
|
+
[...]
|
|
375
|
+
|
|
376
|
+
# A Luz Interior
|
|
377
|
+
[...]
|
|
378
|
+
`,
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
role: 'user',
|
|
382
|
+
content: `
|
|
383
|
+
Generate rich and mystical content for the following archetype:
|
|
384
|
+
|
|
385
|
+
• Archetype Name: ${name}
|
|
386
|
+
• Archetype Description: ${description}
|
|
387
|
+
• Sun Sign: ${sun}
|
|
388
|
+
• Ascendant Sign: ${ascendant}
|
|
389
|
+
• Moon Sign: ${moon}
|
|
390
|
+
`,
|
|
391
|
+
},
|
|
392
|
+
];
|
|
393
|
+
},
|
|
394
|
+
|
|
224
395
|
generateCosmicMirrorArchetypeLeonardoPrompts: (
|
|
225
396
|
archetypes: Array<{ name: string; description: string }>
|
|
226
397
|
): ChatMessages => [
|