only_ever_generator 0.5.5 → 0.5.6

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.
Files changed (37) hide show
  1. package/dist/bootstrap/app.js +5 -5
  2. package/dist/card_gen/generate_cards.js +2 -1
  3. package/dist/config.js +1 -1
  4. package/dist/constants/api_constants.js +1 -1
  5. package/dist/constants/prompt_data.js +4 -4
  6. package/dist/constants/source_data.js +382 -382
  7. package/dist/logger.js +4 -4
  8. package/dist/parse/parse_card/parse_cloze_card.js +11 -9
  9. package/dist/parse/parse_card/parse_flash_cards.js +33 -0
  10. package/dist/parse/parse_card_response.js +8 -31
  11. package/dist/parse/parse_source_content.js +30 -20
  12. package/dist/parse/response_format_typology.js +16 -16
  13. package/dist/services/open_ai_service.js +13 -10
  14. package/dist/typology_gen/generate_typology.js +16 -15
  15. package/dist/utils/generate_args.js +3 -3
  16. package/dist/utils/parse_openai_response.js +7 -7
  17. package/package.json +1 -1
  18. package/src/bootstrap/app.ts +69 -79
  19. package/src/card_gen/generate_cards.ts +6 -1
  20. package/src/config.ts +3 -3
  21. package/src/constants/api_constants.ts +3 -3
  22. package/src/constants/prompt_data.ts +24 -26
  23. package/src/constants/prompts/card_gen_prompt.ts +2 -4
  24. package/src/constants/source_data.ts +440 -390
  25. package/src/index.ts +1 -2
  26. package/src/logger.ts +24 -25
  27. package/src/parse/parse_card/parse_cloze_card.ts +54 -42
  28. package/src/parse/parse_card/parse_flash_cards.ts +33 -0
  29. package/src/parse/parse_card/parse_match_card.ts +32 -32
  30. package/src/parse/parse_card_response.ts +28 -47
  31. package/src/parse/parse_source_content.ts +173 -168
  32. package/src/parse/response_format_card.ts +0 -2
  33. package/src/parse/response_format_typology.ts +42 -42
  34. package/src/services/open_ai_service.ts +50 -48
  35. package/src/typology_gen/generate_typology.ts +68 -60
  36. package/src/utils/generate_args.ts +25 -23
  37. package/src/utils/parse_openai_response.ts +17 -19
@@ -7,142 +7,136 @@ import { GenerateTypology } from "../typology_gen/generate_typology";
7
7
  import { GenerateArgs } from "../utils/generate_args";
8
8
  import { gapFilling } from "../gap_fill/calculate_gap_fill";
9
9
 
10
-
11
10
  /// OnlyEverGenerator
12
11
 
13
12
  export class OnlyEverGenerator {
14
13
  public api_key: string = "";
15
14
  public openAiService: OpenAiService;
16
15
 
17
- /// these fields will be populated inside the constructor
16
+ /// these fields will be populated inside the constructor
18
17
  parsedContent: any = {};
19
18
  promptForTypology: string = "";
20
19
  promptForCardGen: string = "";
21
20
  expectedFields: Array<string>;
22
21
 
23
-
24
22
  typologyResponse: any = undefined;
25
23
  cardgenResponse: any = undefined;
26
24
  summarizeResponse = {};
27
25
  gapFillResponse: any = {};
28
26
 
29
-
30
- constructor(
31
- apiKey: string,
32
- model: string,
33
- generationContent : any
34
- ) {
27
+ constructor(apiKey: string, model: string, generationContent: any) {
35
28
  this.api_key = apiKey;
36
29
  this.openAiService = new OpenAiService(
37
30
  apiKey,
38
31
  model ?? "gpt-3.5-turbo-1106"
39
32
  );
40
- const parsedData = new ParseSourceContent(generationContent.content).parseData()
41
- this.parsedContent = {
33
+ const parsedData = new ParseSourceContent(
34
+ generationContent.content
35
+ ).parseData();
36
+ (this.parsedContent = {
42
37
  title: parsedData.title,
43
38
  headings: parsedData.headings,
44
39
  content: parsedData.content,
45
40
  taxonomy: parsedData.taxonomy,
41
+ }),
42
+ // parsedData.type == 'cards' ? this.typologyResponse = parsedData.taxonomy : this.typologyResponse = null;
43
+ (this.typologyResponse = generationContent.content.taxonomy);
46
44
 
47
- },
48
- // parsedData.type == 'cards' ? this.typologyResponse = parsedData.taxonomy : this.typologyResponse = null;
49
- this.typologyResponse = generationContent.content.taxonomy
50
-
51
- this.expectedFields = generationContent.content.fields; //returnFields();
45
+ this.expectedFields = generationContent.content.fields; //returnFields();
52
46
  this.promptForTypology = generationContent.prompt.typology;
53
- this.promptForCardGen =generationContent.prompt.card_generation;
47
+ this.promptForCardGen = generationContent.prompt.card_generation;
54
48
  }
55
49
 
56
-
57
-
58
50
  async generate(
59
51
  generate_typology: boolean = false,
60
52
  generate_card: boolean = false
61
53
  ): Promise<Array<any>> {
62
- let args = new GenerateArgs(generate_card, generate_typology, false, );
54
+ let args = new GenerateArgs(generate_card, generate_typology, false);
63
55
  const responseToReturn = [];
64
56
  const whatNeedsToBeGenerated = args.getWhatNeedsToBeGenerated();
65
57
  for (let elem of whatNeedsToBeGenerated)
66
58
  if (elem == "generate_tyopology") {
67
59
  this.typologyResponse = await this.generateTypology(
68
- this.promptForTypology
60
+ this.promptForTypology
69
61
  );
70
62
  responseToReturn.push(this.typologyResponse);
71
63
  } else if (elem == "generate_card") {
72
64
  /// for cards gen to occur, there must be presence of source taxonomy
73
- if(this.shouldTheCardBeGeneratedAfterTypologyResponse()){
65
+ if (this.shouldTheCardBeGeneratedAfterTypologyResponse()) {
74
66
  this.parsedContent.taxonomy = {
75
67
  concepts: this.typologyResponse.concepts,
76
68
  facts: this.typologyResponse.facts,
77
69
  generate_cards: this.typologyResponse.generate_cards,
78
70
  };
79
- this.cardgenResponse = await this.generateCard(
71
+ this.cardgenResponse = await this.generateCard(
80
72
  this.promptForCardGen,
81
73
  JSON.stringify(this.typologyResponse),
82
- false,
83
- )
74
+ false
75
+ );
84
76
  responseToReturn.push(this.cardgenResponse);
85
77
 
86
- /// check if gap fill is required ie coverage determination
87
- if(this.cardgenResponse.status_code == 200) {
88
- this.gapFillResponse = await this._generationForGapFill(this.typologyResponse, this.cardgenResponse);
78
+ /// check if gap fill is required ie coverage determination
79
+ if (this.cardgenResponse.status_code == 200) {
80
+ this.gapFillResponse = await this._generationForGapFill(
81
+ this.typologyResponse,
82
+ this.cardgenResponse
83
+ );
89
84
  responseToReturn.push(this.gapFillResponse);
90
85
  }
91
-
92
86
  }
93
- }
87
+ }
94
88
  return responseToReturn;
95
- // return [typologyPrompt, cardPrompt];
96
-
89
+ // return [typologyPrompt, cardPrompt];
97
90
  }
98
91
 
99
- shouldTheCardBeGeneratedAfterTypologyResponse(){
100
- if(this.typologyResponse){
92
+ shouldTheCardBeGeneratedAfterTypologyResponse() {
93
+ if (this.typologyResponse) {
101
94
  return this.typologyResponse?.generate_cards?.state == true;
102
- }else{
95
+ } else {
103
96
  return false;
104
97
  }
105
-
106
98
  }
107
99
 
108
100
  async _generationForGapFill(typologyData: any, cardGenData: any) {
109
- let gapFill = gapFilling(typologyData, cardGenData);
110
- let response :any ;
111
- if (
112
- gapFill.remainingConcepts.length !== 0 ||
113
- gapFill.remainingFacts.length !== 0
114
- ) {
115
- this.typologyResponse.facts = gapFill.remainingFacts;
116
- this.typologyResponse.concepts = gapFill.remainingConcepts;
117
- response = await this.generateCard(
118
- this.promptForCardGen +
119
- "Generate cards only suitable for the given remaining concepts and facts" +
120
- JSON.stringify(gapFill) ,
121
-
122
- "",
123
- true
124
- );
125
- }
126
- return response;
127
-
128
- }
129
-
101
+ let gapFill = gapFilling(typologyData, cardGenData);
102
+ let response: any;
103
+ if (
104
+ gapFill.remainingConcepts.length !== 0 ||
105
+ gapFill.remainingFacts.length !== 0
106
+ ) {
107
+ this.typologyResponse.facts = gapFill.remainingFacts;
108
+ this.typologyResponse.concepts = gapFill.remainingConcepts;
109
+ response = await this.generateCard(
110
+ this.promptForCardGen +
111
+ "Generate cards only suitable for the given remaining concepts and facts" +
112
+ JSON.stringify(gapFill),
130
113
 
114
+ "",
115
+ true
116
+ );
117
+ }
118
+ return response;
119
+ }
131
120
 
132
- async generateCard(prompt: string, additionalContent: string, isGapFill: boolean) {
133
- let generateCardsResp = await new GenerateCards(this.openAiService).generateCards(
121
+ async generateCard(
122
+ prompt: string,
123
+ additionalContent: string,
124
+ isGapFill: boolean
125
+ ) {
126
+ let generateCardsResp = await new GenerateCards(
127
+ this.openAiService
128
+ ).generateCards(
134
129
  prompt ?? "",
135
130
  JSON.stringify(this.parsedContent) + additionalContent,
136
131
  isGapFill,
137
- this.parsedContent.taxonomy,
132
+ this.parsedContent.taxonomy
138
133
  );
139
-
134
+
140
135
  // let response = await this.openAiService?.sendRequest(prompt,this.parsedContent);
141
136
  // response['type'] = 'card_gen';
142
137
  return generateCardsResp;
143
138
  }
144
139
 
145
-
146
140
  async generateTypology(prompt: string) {
147
141
  let response = await new GenerateTypology(
148
142
  this.openAiService,
@@ -154,28 +148,24 @@ export class OnlyEverGenerator {
154
148
  }
155
149
 
156
150
  async gapFill(factsMaps: any, aiCards: Array<any>) {
157
- /// factsmap
151
+ /// factsmap
158
152
  /// {
159
153
  /// remaining_facts: [],
160
- /// remaining_concepts: [],
154
+ /// remaining_concepts: [],
161
155
  //}
162
156
 
163
157
  /// aicards is data
164
- let response :any ;
158
+ let response: any;
159
+
160
+ response = await this.generateCard(
161
+ this.promptForCardGen +
162
+ "Generate cards only suitable for the given remaining concepts and facts" +
163
+ JSON.stringify(factsMaps) +
164
+ "Exclude generating cards with content in the following",
165
+ JSON.stringify(aiCards),
166
+ true
167
+ );
165
168
 
166
- response = await this.generateCard(
167
- this.promptForCardGen +
168
- "Generate cards only suitable for the given remaining concepts and facts" +
169
- JSON.stringify(factsMaps) +
170
- "Exclude generating cards with content in the following",
171
- JSON.stringify(aiCards),
172
- true
173
- );
174
-
175
169
  return response;
176
-
177
- }
178
-
179
-
180
-
170
+ }
181
171
  }
@@ -22,11 +22,16 @@ export class GenerateCards {
22
22
  req_type: response.type,
23
23
  req_tokens: response.usage_data?.prompt_tokens,
24
24
  res_tokens: response.usage_data?.completion_tokens,
25
+ prompt_tokens_details: response.usage_data?.prompt_tokens_details,
25
26
  model: this.openAiService.model,
26
27
  };
27
28
  if (response.status_code == 200) {
28
29
  response.metadata.status = "completed";
29
- let parseCard = new ParseCardResponse().parse(response,isGapFill, taxonomy);
30
+ let parseCard = new ParseCardResponse().parse(
31
+ response,
32
+ isGapFill,
33
+ taxonomy
34
+ );
30
35
  return parseCard;
31
36
  } else {
32
37
  response.metadata.status = "failed";
package/src/config.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import "dotenv/config";
2
2
 
3
3
  const config = {
4
- openAIKey : process.env.OPEN_AI_KEY as string
5
- }
4
+ openAIKey: process.env.OPEN_AI_KEY as string,
5
+ };
6
6
 
7
- export default config;
7
+ export default config;
@@ -1,3 +1,3 @@
1
- export function openAiEndPoint(){
2
- return 'https://api.openai.com/v1/chat/completions';
3
- }
1
+ export function openAiEndPoint() {
2
+ return "https://api.openai.com/v1/chat/completions";
3
+ }
@@ -2,8 +2,8 @@ import { returnCardGenPrompt } from "./prompts/card_gen_prompt";
2
2
  import { returnTypologyPrompt } from "./prompts/typology_prompt";
3
3
 
4
4
  const promptData: any = {
5
- typology: {
6
- role: `
5
+ typology: {
6
+ role: `
7
7
  As a dedicated assistant at a learning company, your role involves analyzing educational content to categorize and summarize it. You will process content (in JSON format) that represents text and images from diverse sources such as PDFs, book chapters, videos, and websites. Follow these steps:
8
8
 
9
9
  1. Classify the content into one to three predefined fields of knowledge.
@@ -27,7 +27,7 @@ const promptData: any = {
27
27
 
28
28
  Further instruction on how to perform these tasks are below.
29
29
  `,
30
- fields: `
30
+ fields: `
31
31
  Every source must be placed under a field. This is the broadest category of knowledge. A source should belong to at least one and at most 3 fields. Only include fields that a source is strongly associated with. The field names in your response must exactly match the names of 18 fields listed below.
32
32
 
33
33
  1. Sciences: Focus on Biology, Chemistry, Physics, Astronomy, Mathematics, and Computer Science.
@@ -49,7 +49,7 @@ const promptData: any = {
49
49
  17. Reference & Indexing: Include Summaries, Timelines, Directories, Glossaries, Bibliographies, and other Reference Material.
50
50
  18. Other: Use for content that doesn’t fit into the above categories.
51
51
  `,
52
- concepts: `
52
+ concepts: `
53
53
  Extract key concepts within the content after classifying the field. Please be as exhaustive as possible.
54
54
 
55
55
  Definition of a Concept: Concepts are fundamental ideas that form the basis of knowledge in any discipline. They help organize and explain information, making it accessible and relatable.
@@ -66,7 +66,7 @@ const promptData: any = {
66
66
  ]
67
67
  }
68
68
  `,
69
- facts: `
69
+ facts: `
70
70
  After classifying the content and identifying key concepts, proceed to extract and list verifiable facts.
71
71
 
72
72
  Definition of a Fact: Ensure each fact is a standalone piece of information that is concrete and can be independently verified.
@@ -77,7 +77,7 @@ const promptData: any = {
77
77
  "facts": ["fact1", "fact2", "fact3", "..."]
78
78
  }
79
79
  `,
80
- generate: `
80
+ generate: `
81
81
  After analyzing the content, classifying its field, and identifying key concepts, and facts, assess whether the discovered elements warrant the creation of testing materials. Consider if these elements provide significant educational value to an average learner by enhancing understanding, offering practical applications, or supporting crucial educational goals. If you decide that testing cards don't need to be generated then please provide a reason in less than 90 characters.
82
82
 
83
83
  Value Assessment: Determine if the concepts and facts are essential for understanding the broader topic, are likely to be used in practical scenarios, or help in achieving educational benchmarks.
@@ -89,7 +89,7 @@ const promptData: any = {
89
89
  false_reason: "reason for marking the source as false. Leave empty for true."
90
90
  }
91
91
  `,
92
- summarize:`
92
+ summarize: `
93
93
  After analyzing the content, identifying key concepts, and facts, summarize the material using a series of engaging and informative cards. These cards should capture the essence of the content while highlighting the critical concepts and facts that you previously identified.
94
94
 
95
95
  Inclusion Criteria: The generate_cards should be true. Return an empty array if the generate_cards is false.
@@ -102,10 +102,9 @@ const promptData: any = {
102
102
  "summary_cards": ["summary_card1", "summary_card2", "summary_card3", "..."]
103
103
  }
104
104
  `,
105
-
106
- },
107
- card_generation: {
108
- role: `
105
+ },
106
+ card_generation: {
107
+ role: `
109
108
  As a dedicated assistant at a learning company, your role is to analyze educational content and create test cards that help learners understand and remember key concepts and facts. You will be provided with:
110
109
 
111
110
  1. Title of the source
@@ -146,7 +145,7 @@ const promptData: any = {
146
145
 
147
146
  Further instructions are provided below.
148
147
  `,
149
- concepts : `
148
+ concepts: `
150
149
  You are provided with a list of identified concepts. Review this list and the content to determine if any concepts are missing.
151
150
 
152
151
  1. **Definition of a Concept**: Concepts are fundamental ideas that form the basis of knowledge in any discipline. They help organize and explain information, making it accessible and relatable.
@@ -163,7 +162,7 @@ const promptData: any = {
163
162
  ]
164
163
  }
165
164
  `,
166
- facts :`
165
+ facts: `
167
166
  You are provided with a list of identified facts. Review this list and the content to determine if any facts are missing.
168
167
 
169
168
  1. **Definition of a Fact**: Standalone information that is concrete and independently verifiable.
@@ -174,7 +173,7 @@ const promptData: any = {
174
173
  "missing_facts": ["fact1", "fact2", "fact3", "..."]
175
174
  }
176
175
  `,
177
- card_gen: `
176
+ card_gen: `
178
177
  After you have the complete list of concepts and facts, including any missing ones you identified, proceed to generate test cards for each.
179
178
 
180
179
  1. Clarity: Ensure the test content is clear and unambiguous.
@@ -277,8 +276,8 @@ const promptData: any = {
277
276
 
278
277
  • Maximum character length for each item in a pair: 42
279
278
  `,
280
- reference : `Each test card needs a reference. A reference can either be the entire source or a specific heading in the source. Whenever possible, pick a main heading to direct the user to the most relevant part of the source material. The reference schema is as follows: source_title#main_heading, where #main_heading is optional.`,
281
- checkcoverage: `Once you are done generating the test cards. Go back and evaulate the full list of concepts and fact that include any of the missing concepts or facts along with the list that was provided as the input.
279
+ reference: `Each test card needs a reference. A reference can either be the entire source or a specific heading in the source. Whenever possible, pick a main heading to direct the user to the most relevant part of the source material. The reference schema is as follows: source_title#main_heading, where #main_heading is optional.`,
280
+ checkcoverage: `Once you are done generating the test cards. Go back and evaulate the full list of concepts and fact that include any of the missing concepts or facts along with the list that was provided as the input.
282
281
 
283
282
  Are there any concept or fact that don't have a test card yet? If yes, go back and create one.
284
283
 
@@ -290,14 +289,13 @@ const promptData: any = {
290
289
  2. If any concept or fact is missing a test card, create one for it.
291
290
  3. Repeat this step until all concepts and facts are covered.
292
291
 
293
- Only stop generating test questions once you believe there is sufficient testing material for learners to fully understand the concepts and remember the facts. The same concept or fact can have multiple test cards, so continue creating test cards until you are confident that there are enough for learners to fully grasp the source material.`
294
-
295
- }
296
- }
292
+ Only stop generating test questions once you believe there is sufficient testing material for learners to fully understand the concepts and remember the facts. The same concept or fact can have multiple test cards, so continue creating test cards until you are confident that there are enough for learners to fully grasp the source material.`,
293
+ },
294
+ };
297
295
 
298
- export function returnPromptData(){
299
- return {
300
- "typology": returnTypologyPrompt(),
301
- "card_generation": returnCardGenPrompt(),
302
- };
303
- }
296
+ export function returnPromptData() {
297
+ return {
298
+ typology: returnTypologyPrompt(),
299
+ card_generation: returnCardGenPrompt(),
300
+ };
301
+ }
@@ -152,8 +152,6 @@ Once you are done generating the test cards, review the full list of concepts an
152
152
 
153
153
  Only stop generating test questions once you believe there is sufficient testing material for learners to fully understand the concepts and remember the facts. The same concept or fact can have multiple test cards, so continue creating test cards until you are confident that there are enough for learners to fully grasp the source material.
154
154
  `;
155
- export function returnCardGenPrompt(){
156
- return promptString;
155
+ export function returnCardGenPrompt() {
156
+ return promptString;
157
157
  }
158
-
159
-