only_ever_generator 0.4.8 → 0.5.0

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/src/index.ts CHANGED
@@ -12,6 +12,7 @@ import { OnlyEverGenerator } from "./bootstrap/app";
12
12
  // import { returnPromptData } from "./constants/prompt_data";
13
13
  // import { GenerateCards } from "./card_gen/generate_cards";
14
14
  // import { OpenAiService } from "./services/open_ai_service";
15
+ // import { ParseCardResponse } from "./parse/parse_card_response";
15
16
 
16
17
  /// While Publishing the package , and using this code as a separate npm module
17
18
  /// uncomment the below line and comment all the others, expect the import of OnlyEverGenerator
@@ -44,35 +45,36 @@ import { OnlyEverGenerator } from "./bootstrap/app";
44
45
  // app.get("/parseCardData", async(req,res)=>{
45
46
  // let cardResp = returnCardResponse();
46
47
  // let headings = returnHeadings();
48
+
47
49
  // cardResp.metadata = {
48
50
  // "req_time": cardResp.generated_at ?? new Date(),
49
- // "req_type": cardResp.type,
51
+ // "req_type": "card",
50
52
  // "req_tokens": cardResp.usage_data?.prompt_tokens,
51
53
  // "res_tokens": cardResp.usage_data?.completion_tokens,
52
54
  // "model": '40-mini'
53
55
  // };
54
- // let parsedData = new GenerateCards(new OpenAiService("","")).parse(cardResp,false,headings);
56
+ // let parsedData = new ParseCardResponse().parse(cardResp,false);
55
57
  // res.send(parsedData)
56
58
  // });
57
59
 
58
- // // app.get("/typology", async (req, res) => {
59
- // // {
60
- // // let typologyPrompt = returnTypologyPrompt();
61
- // // let cardPrompt = returnCardGenPrompt();
62
- // // let args = new GenerateArgs(
63
- // // true,
64
- // // true,
65
- // // false,
66
- // // {
67
- // // typology_prompt: typologyPrompt,
68
- // // card_gen_prompt: cardPrompt,
69
- // // summary_prompt: "",
70
- // // }
71
- // // )
72
- // // let typologyRequest = await oeGen.generate(false, true);
73
- // // res.send(typologyRequest);
74
- // // }
75
- // // });
60
+ // app.get("/typology", async (req, res) => {
61
+ // {
62
+ // let typologyPrompt = returnTypologyPrompt();
63
+ // let cardPrompt = returnCardGenPrompt();
64
+ // let args = new GenerateArgs(
65
+ // true,
66
+ // true,
67
+ // false,
68
+ // {
69
+ // typology_prompt: typologyPrompt,
70
+ // card_gen_prompt: cardPrompt,
71
+ // summary_prompt: "",
72
+ // }
73
+ // )
74
+ // let typologyRequest = await oeGen.generate(false, true);
75
+ // res.send(typologyRequest);
76
+ // }
77
+ // });
76
78
 
77
79
  // app.listen(port, () => {
78
80
  // console.log(`Example app listening at http://localhost:${port}`);
@@ -0,0 +1,90 @@
1
+ export class ParseClozeCard {
2
+ parse(data: any) {
3
+ try {
4
+ let displayTitle = this._generateClozeCardDisplayTitle(
5
+ data.card_content.prompt,
6
+ data.card_content.options
7
+ );
8
+ let clozeCardData = {
9
+ type: {
10
+ category: "learning",
11
+ sub_type: data.type,
12
+ },
13
+ heading: data.card_reference,
14
+ displayTitle: displayTitle,
15
+ content: {
16
+ question: data.card_content.prompt,
17
+ options: data.card_content.options,
18
+ },
19
+ concepts: data.concepts,
20
+ facts: data.facts,
21
+ bloomLevel: data.bloom_level,
22
+ };
23
+
24
+ return this._validateCloze(clozeCardData);
25
+ } catch (e) {
26
+ return null;
27
+ }
28
+ }
29
+
30
+ _generateClozeCardDisplayTitle(question: string, answers: Array<any>) {
31
+ let optionsString = "";
32
+ if (answers.length !== 0) {
33
+ optionsString = answers
34
+ .map((item: { option: any }) => {
35
+ if (item.option !== undefined) {
36
+ return item.option;
37
+ } else {
38
+ return "";
39
+ }
40
+ })
41
+ .join(", ");
42
+ }
43
+
44
+ return `${question} ---- ${optionsString}`;
45
+ }
46
+
47
+ /// validate the cloze card
48
+ // 1. Has Empty cloze
49
+ // 2. has Duplicate Clozes
50
+ // 3. doesnt have any valid option,
51
+ // 4. Question length 320
52
+ // 5. More than 6 options
53
+ // 6. Less than 2 options
54
+ // 7. Max character for individual cloze: 90
55
+
56
+ _validateCloze(clozeCard: any) {
57
+ let clozeRegex = /\{\{c(\d+):([^}]+)\}\}/g;
58
+
59
+ try {
60
+ /// validate emptu cloze
61
+ let options = clozeCard.content.options ?? [];
62
+ let question = clozeCard.content.question;
63
+ if (options.length < 2 || options.length > 6) {
64
+ throw Error("Number of cloze options are invalid");
65
+ }
66
+
67
+ /// There are no correct clozes// or null cloze or empty cloze
68
+ let correctOptions = options.find(
69
+ (e: any) => e.cloze != "null" && e.cloze != null && e.cloze.trim() != ""
70
+ );
71
+ if (correctOptions) {
72
+ } else {
73
+ throw Error(" No valid clozes exists");
74
+ }
75
+
76
+ let rightClozes = options.filter((e: any) => e.cloze.startsWith("c"));
77
+
78
+ /// matches our cloze syntax
79
+ let clozeMatches = [...question.matchAll(clozeRegex)];
80
+ if (clozeMatches.length == 0) {
81
+ throw Error("Question Invalid");
82
+ } else if (clozeMatches.length != rightClozes.length) {
83
+ throw Error(" Clozes in question doesnt match to clozes in options");
84
+ }
85
+ return clozeCard;
86
+ } catch (e) {
87
+ return false;
88
+ }
89
+ }
90
+ }
@@ -0,0 +1,59 @@
1
+ import { match } from "assert";
2
+
3
+ export class ParseMatchCard {
4
+ parse(cardData: any) {
5
+ try {
6
+ let content = cardData.card_content;
7
+
8
+ let displayTitle = this._generateMatchCardDisplayTitle(content);
9
+ let matchCard = {
10
+ type: {
11
+ category: "learning",
12
+ sub_type: cardData.type,
13
+ },
14
+ heading: cardData.card_reference,
15
+ content: content,
16
+ // content: cardData.card_content,
17
+ displayTitle: displayTitle,
18
+ concepts: cardData.concepts,
19
+ facts: cardData.facts,
20
+ bloomLevel: cardData.bloom_level,
21
+ };
22
+
23
+ return this._validateMatch(matchCard);
24
+ } catch (e) {
25
+ return null;
26
+ }
27
+ }
28
+
29
+ _generateMatchCardDisplayTitle(answers: any) {
30
+ let titles: string[] = [];
31
+ let counter = 65;
32
+ for (let data of answers) {
33
+ let value = data.right_item.join(",");
34
+ let leftData = data.left_item;
35
+ let letter = String.fromCharCode(counter);
36
+ titles.push(`${letter}. ${leftData} -- ${value}`);
37
+ counter++;
38
+ }
39
+ let displayTitle = titles.join(",");
40
+ return displayTitle;
41
+ }
42
+
43
+ _validateMatch(matchCard: any){
44
+ let matches = matchCard.content;
45
+ try{
46
+ for(let elem of matches){
47
+ if(elem.left_item.length > 24 || elem.left_item.length == 0){
48
+ throw Error("Invalid Length of left item ");
49
+ }else if(elem.right_item[0].length>24 || elem.right_item[0].length == 0){
50
+ throw Error(" Invalid Length of right item")
51
+ }
52
+
53
+ }
54
+ return matchCard;
55
+ }catch(e){
56
+ return null;
57
+ }
58
+ }
59
+ }
@@ -0,0 +1,105 @@
1
+ export class ParseMcqCard {
2
+ parse(data: any) {
3
+ try {
4
+ let mcqAnswers = [];
5
+ if (
6
+ data.card_content.choices !== undefined &&
7
+ data.card_content.choices.length != 0
8
+ ) {
9
+ for (let choice of data.card_content.choices) {
10
+ let answer = {
11
+ answer: choice.choice,
12
+ is_correct: choice.is_correct,
13
+ };
14
+ mcqAnswers.push(answer);
15
+ }
16
+ }
17
+
18
+ let displayTitle = this._generateMcqCardDisplayTitle(
19
+ data.card_content.prompt,
20
+ mcqAnswers
21
+ );
22
+ let mcqCard = {
23
+ type: {
24
+ category: "learning",
25
+ sub_type: data.type,
26
+ },
27
+ heading: data.card_reference,
28
+ displayTitle: displayTitle,
29
+ content: {
30
+ question: data.card_content.prompt,
31
+ answers: mcqAnswers,
32
+ },
33
+ concepts: data.concepts,
34
+ facts: data.facts,
35
+ bloomLevel: data.bloom_level,
36
+ };
37
+ // return mcqCard;
38
+ const isValid = this._validate(mcqCard);
39
+ if (isValid == true) {
40
+ return mcqCard;
41
+ } else {
42
+ return null;
43
+ }
44
+ } catch (e) {
45
+ return null;
46
+ }
47
+ }
48
+
49
+ _generateMcqCardDisplayTitle(question: string, answers: any) {
50
+ let answersString = [];
51
+ if (answers.length != 0) {
52
+ for (let option of answers) {
53
+ let currentIndex = answers.indexOf(option) + 1;
54
+ let temp = `${currentIndex} . ${option.answer} `;
55
+ answersString.push(temp);
56
+ }
57
+ let resultString = answersString.join("");
58
+ let finalDisplayTitle = `${question} ---- ${resultString}`;
59
+ return finalDisplayTitle;
60
+ } else {
61
+ return question;
62
+ }
63
+ }
64
+
65
+ /// validate mcq card
66
+ // 1. Check if atleast 1 correct answer exists
67
+ // 2. Length of answer shouldnt exceed 24 chars
68
+ // 3. Length of question shouldnt exceed 90 chars
69
+ // 4. If Any option is Empty
70
+ _validate(mcqCard: any) {
71
+ try {
72
+ let isQuestionValid = mcqCard.content.question.length <= 90;
73
+ if (!isQuestionValid) {
74
+ throw new Error("Question length exceeded");
75
+ }
76
+
77
+ /// check if all are wrong answers
78
+ let exists = this._checkIfAllAnswersAreWrong(mcqCard.content.answers);
79
+ if (exists) {
80
+ } else {
81
+ throw new Error("Every answers are wrong");
82
+ }
83
+
84
+ /// check if answers are of length <40 or is 0
85
+ let answerWhoseLengthisGreaterThan40or0 = (
86
+ mcqCard.content.answers ?? []
87
+ ).find((e: any) => e.answer.length == 0 || e.answer.length > 40);
88
+ if (answerWhoseLengthisGreaterThan40or0) {
89
+ throw new Error("Option has length more than 40 or is Empty");
90
+ }
91
+ return true;
92
+ } catch (e) {
93
+ return false;
94
+ }
95
+ }
96
+
97
+ _checkIfAllAnswersAreWrong(answers: any[]) {
98
+ let rightAnswer = answers.find((e) => e.is_correct == true);
99
+ if (rightAnswer) {
100
+ return true;
101
+ } else {
102
+ return false;
103
+ }
104
+ }
105
+ }