@@ -887,6 +887,77 @@ function getDefaultLevels(language: 'en' | 'id'): {
887887 }
888888}
889889
890+ // Helper function to manually extract criteria from text when JSON parsing fails
891+ function extractCriteriaFromText ( text : string , language : 'en' | 'id' ) : ProjectRubricCriterion [ ] {
892+ const criteria : ProjectRubricCriterion [ ] = [ ]
893+
894+ // Look for numbered items or bullet points that might contain criteria
895+ const lines = text . split ( '\n' )
896+ let currentCriterion : Partial < ProjectRubricCriterion > | null = null
897+
898+ for ( const line of lines ) {
899+ const trimmed = line . trim ( )
900+
901+ // Look for numbered criteria (1., 2., etc.) or bullet points
902+ const criterionMatch = trimmed . match (
903+ / ^ (?: \d + \. | \* | - ) \s * \* ? \* ? ( [ ^ ( ] + ?) (?: \s * \( ( \d + ) % ? \) ) ? \* ? \* ? / ,
904+ )
905+ if ( criterionMatch ) {
906+ // Save previous criterion if exists
907+ if ( currentCriterion && currentCriterion . name ) {
908+ criteria . push ( {
909+ name : currentCriterion . name ,
910+ weight : currentCriterion . weight || 20 ,
911+ levels : currentCriterion . levels || getDefaultLevels ( language ) ,
912+ } )
913+ }
914+
915+ // Start new criterion
916+ currentCriterion = {
917+ name : criterionMatch [ 1 ] . trim ( ) ,
918+ weight : criterionMatch [ 2 ] ? parseInt ( criterionMatch [ 2 ] ) : 20 ,
919+ levels : getDefaultLevels ( language ) ,
920+ }
921+ }
922+ }
923+
924+ // Add last criterion if exists
925+ if ( currentCriterion && currentCriterion . name ) {
926+ criteria . push ( {
927+ name : currentCriterion . name ,
928+ weight : currentCriterion . weight || 20 ,
929+ levels : currentCriterion . levels || getDefaultLevels ( language ) ,
930+ } )
931+ }
932+
933+ return criteria
934+ }
935+
936+ // Helper function to get default level descriptions
937+ function getDefaultLevels ( language : 'en' | 'id' ) : {
938+ excellent : string
939+ good : string
940+ average : string
941+ acceptable : string
942+ poor : string
943+ } {
944+ return language === 'id'
945+ ? {
946+ excellent : 'Menunjukkan pemahaman yang luar biasa dan penerapan yang sangat baik' ,
947+ good : 'Menunjukkan pemahaman yang baik dan penerapan yang tepat' ,
948+ average : 'Menunjukkan pemahaman yang memadai dengan beberapa kekurangan' ,
949+ acceptable : 'Menunjukkan pemahaman dasar dengan kekurangan yang jelas' ,
950+ poor : 'Menunjukkan pemahaman yang terbatas atau tidak memadai' ,
951+ }
952+ : {
953+ excellent : 'Demonstrates exceptional understanding and excellent application' ,
954+ good : 'Shows good understanding and appropriate application' ,
955+ average : 'Shows adequate understanding with some shortcomings' ,
956+ acceptable : 'Shows basic understanding with clear deficiencies' ,
957+ poor : 'Shows limited or inadequate understanding' ,
958+ }
959+ }
960+
890961// Add a new function to generate each section of the rubric separately
891962async function generateRubricSection (
892963 section : 'report' | 'demo' | 'individual' ,
0 commit comments