@zodic/shared 0.0.230 → 0.0.232
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/ConceptService.ts +19 -19
- package/package.json +1 -1
|
@@ -554,19 +554,19 @@ export class ConceptService {
|
|
|
554
554
|
console.log(
|
|
555
555
|
`📌 [START] Parsing structured content for ${conceptSlug} from ChatGPT response.`
|
|
556
556
|
);
|
|
557
|
-
|
|
557
|
+
|
|
558
558
|
// ✅ Step 1: Clean artifacts before processing
|
|
559
559
|
let cleanedResponse = response
|
|
560
560
|
.replace(/[*#•]/g, '') // Remove bullet points, bold markers, headings
|
|
561
561
|
.replace(/---+/g, '') // Remove dividers (like "---")
|
|
562
562
|
.replace(/\n\s*\n/g, '\n\n') // Normalize multiple line breaks
|
|
563
563
|
.trim();
|
|
564
|
-
|
|
564
|
+
|
|
565
565
|
console.log(
|
|
566
566
|
'🔹 [CLEANED RESPONSE]:',
|
|
567
567
|
cleanedResponse.slice(0, 500) + '...'
|
|
568
568
|
);
|
|
569
|
-
|
|
569
|
+
|
|
570
570
|
// ✅ Step 2: Define Section Titles Per Concept
|
|
571
571
|
const conceptSections: Record<string, { en: string[]; pt: string[] }> = {
|
|
572
572
|
crown: {
|
|
@@ -666,28 +666,28 @@ export class ConceptService {
|
|
|
666
666
|
],
|
|
667
667
|
},
|
|
668
668
|
};
|
|
669
|
-
|
|
669
|
+
|
|
670
670
|
const sectionsEN = conceptSections[conceptSlug]?.en;
|
|
671
671
|
const sectionsPT = conceptSections[conceptSlug]?.pt;
|
|
672
|
-
|
|
672
|
+
|
|
673
673
|
if (!sectionsEN || !sectionsPT) {
|
|
674
674
|
throw new Error(`❌ Unknown concept: ${conceptSlug}`);
|
|
675
675
|
}
|
|
676
|
-
|
|
676
|
+
|
|
677
677
|
// ✅ Step 3: Extract English and Portuguese content separately
|
|
678
678
|
const enMatches = cleanedResponse.match(/EN:\s*([\s\S]+?)\s*PT:/);
|
|
679
679
|
const ptMatches = cleanedResponse.match(/PT:\s*([\s\S]+)/);
|
|
680
|
-
|
|
680
|
+
|
|
681
681
|
if (!enMatches || !ptMatches) {
|
|
682
682
|
console.error(
|
|
683
683
|
'❌ [ERROR] Missing English or Portuguese content in response.'
|
|
684
684
|
);
|
|
685
685
|
throw new Error('❌ Missing English or Portuguese content in response.');
|
|
686
686
|
}
|
|
687
|
-
|
|
687
|
+
|
|
688
688
|
const enContent = enMatches[1].trim();
|
|
689
689
|
const ptContent = ptMatches[1].trim();
|
|
690
|
-
|
|
690
|
+
|
|
691
691
|
console.log(
|
|
692
692
|
'✅ [MATCH SUCCESS] Extracted English Content:',
|
|
693
693
|
enContent.slice(0, 500) + '...'
|
|
@@ -696,40 +696,40 @@ export class ConceptService {
|
|
|
696
696
|
'✅ [MATCH SUCCESS] Extracted Portuguese Content:',
|
|
697
697
|
ptContent.slice(0, 500) + '...'
|
|
698
698
|
);
|
|
699
|
-
|
|
699
|
+
|
|
700
700
|
// ✅ Step 4: Extract structured sections
|
|
701
701
|
function extractSections(text: string, sectionTitles: string[]) {
|
|
702
702
|
return sectionTitles.map((title) => {
|
|
703
703
|
console.log(`🔍 [PROCESSING] Extracting section: "${title}"`);
|
|
704
|
-
|
|
704
|
+
|
|
705
705
|
// ✅ Improved regex: Detects sections even if AI formatting changes
|
|
706
706
|
const regex = new RegExp(
|
|
707
707
|
`\\d+\\.\\s*${title}:\\s*([\\s\\S]+?)(?=\\n\\d+\\.\\s*[A-Z]|$)`
|
|
708
708
|
);
|
|
709
709
|
const match = text.match(regex);
|
|
710
|
-
|
|
710
|
+
|
|
711
711
|
if (!match) {
|
|
712
712
|
console.warn(`⚠️ [WARNING] Missing section: "${title}"`);
|
|
713
713
|
return { type: 'section', title, content: ['❌ Section Missing'] };
|
|
714
714
|
}
|
|
715
|
-
|
|
715
|
+
|
|
716
716
|
// ✅ Split content into paragraphs and clean them
|
|
717
717
|
const paragraphs = match[1]
|
|
718
718
|
.trim()
|
|
719
719
|
.split(/\n{2,}/) // Handles cases where paragraphs are separated by multiple new lines
|
|
720
720
|
.map((p) => p.trim())
|
|
721
721
|
.filter((p) => p.length > 0); // Removes empty paragraphs
|
|
722
|
-
|
|
722
|
+
|
|
723
723
|
console.log(`✅ [EXTRACTED] "${title}" - Parsed Content:`, paragraphs);
|
|
724
|
-
|
|
724
|
+
|
|
725
725
|
return { type: 'section', title, content: paragraphs };
|
|
726
726
|
});
|
|
727
727
|
}
|
|
728
|
-
|
|
728
|
+
|
|
729
729
|
// ✅ Return parsed and cleaned structured content
|
|
730
730
|
const structuredContentEN = extractSections(enContent, sectionsEN);
|
|
731
731
|
const structuredContentPT = extractSections(ptContent, sectionsPT);
|
|
732
|
-
|
|
732
|
+
|
|
733
733
|
console.log(
|
|
734
734
|
'🎯 [FINAL RESULT] Parsed English Content:',
|
|
735
735
|
JSON.stringify(structuredContentEN, null, 2)
|
|
@@ -738,11 +738,11 @@ export class ConceptService {
|
|
|
738
738
|
'🎯 [FINAL RESULT] Parsed Portuguese Content:',
|
|
739
739
|
JSON.stringify(structuredContentPT, null, 2)
|
|
740
740
|
);
|
|
741
|
-
|
|
741
|
+
|
|
742
742
|
console.log(
|
|
743
743
|
'✅ [COMPLETE] Structured content parsing finished successfully.'
|
|
744
744
|
);
|
|
745
|
-
|
|
745
|
+
|
|
746
746
|
return {
|
|
747
747
|
structuredContentEN,
|
|
748
748
|
structuredContentPT,
|