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
@@ -1,197 +1,202 @@
1
- export class ParseSourceContent{
2
- public content: any;
3
- /// Format of Content
4
- // content: {
5
- // title: source.title,
6
- // headings: source.headings,
7
- // content: source.content,
8
- // fields: fields,
9
- // taxonomy: source.source_taxonomy,
10
- // type: source.source_type
11
- // },
12
-
13
-
14
- titles_to_remove = ['See also', 'References', 'Further reading', 'External links', 'Notes and references', 'Bibliography', 'Notes', 'Cited sources'];
15
- block_types_toremove = ['table','empty_line'];
16
- constructor(sourceContent:any){
17
- this.content = sourceContent;
1
+ export class ParseSourceContent {
2
+ public content: any;
3
+ /// Format of Content
4
+ // content: {
5
+ // title: source.title,
6
+ // headings: source.headings,
7
+ // content: source.content,
8
+ // fields: fields,
9
+ // taxonomy: source.source_taxonomy,
10
+ // type: source.source_type
11
+ // },
12
+
13
+ titles_to_remove = [
14
+ "See also",
15
+ "References",
16
+ "Further reading",
17
+ "External links",
18
+ "Notes and references",
19
+ "Bibliography",
20
+ "Notes",
21
+ "Cited sources",
22
+ ];
23
+ block_types_toremove = ["table", "empty_line"];
24
+ constructor(sourceContent: any) {
25
+ this.content = sourceContent;
26
+ }
27
+
28
+ parseData() {
29
+ let sourceType = this.content.type;
30
+ let afterSanitized;
31
+ if (sourceType == "video") {
32
+ afterSanitized = this.parseVideoContent(this.content.content);
33
+ } else {
34
+ let dataAfterRemovingUnWantedBlocks = this.removeSectionsByTitle(
35
+ this.content.content
36
+ );
37
+ afterSanitized = this.sanitizeBlocks(dataAfterRemovingUnWantedBlocks);
18
38
  }
19
-
20
- parseData() {
21
- let sourceType = this.content.type;
22
- let afterSanitized;
23
- if(sourceType == "video"){
24
- afterSanitized = this.parseVideoContent(this.content.content);
25
- }else{
26
- let dataAfterRemovingUnWantedBlocks = this.removeSectionsByTitle(this.content.content);
27
- afterSanitized = this.sanitizeBlocks(dataAfterRemovingUnWantedBlocks);
28
- }
29
- return {
30
- type: this.content.type,
31
- title: this.content.title,
32
- content: afterSanitized,
33
- headings: this.content.headings,
34
- taxonomy: this.content.taxonomy,
35
- }
39
+ return {
40
+ type: this.content.type,
41
+ title: this.content.title,
42
+ content: afterSanitized,
43
+ headings: this.content.headings,
44
+ taxonomy: this.content.taxonomy,
45
+ };
46
+ }
47
+
48
+ removeSectionsByTitle(data: Array<any>) {
49
+ let dataAfterRemoving = [];
50
+ for (let elem of data) {
51
+ if (
52
+ elem.block_type == "heading" &&
53
+ this.titles_to_remove.includes(elem.content)
54
+ ) {
55
+ continue;
56
+ }
57
+ /// remove unwanted blcok types , for now `table` and `empty_line`
58
+ if (this.block_types_toremove.includes(elem.block_type)) {
59
+ continue;
60
+ }
61
+ if (elem.children) {
62
+ elem.children = this.removeSectionsByTitle(elem.children);
63
+ }
64
+ dataAfterRemoving.push(elem);
36
65
  }
37
-
38
- removeSectionsByTitle(data: Array<any>){
39
- let dataAfterRemoving = [];
40
- for(let elem of data){
41
- if(elem.block_type == 'heading' && this.titles_to_remove.includes(elem.content)){
42
- continue;
43
- }
44
- /// remove unwanted blcok types , for now `table` and `empty_line`
45
- if(this.block_types_toremove.includes(elem.block_type)){
46
- continue;
47
- }
48
- if(elem.children){
49
- elem.children = this.removeSectionsByTitle(elem.children)
50
-
51
- }
52
- dataAfterRemoving.push(elem)
53
-
66
+ return dataAfterRemoving;
67
+ }
68
+
69
+ sanitizeTextContent(content: String) {
70
+ // Remove newline characters
71
+ content = content.replace(/\\n/g, " ");
72
+
73
+ // Remove internal link references, keeping only the link text
74
+ // Pattern explanation: [[link|text|index|wiki]] --> text
75
+ content = content.replace(/\[\[.*?\|(.*?)\|.*?\|wiki\]\]/g, "$1");
76
+
77
+ // Remove external links, keeping only the link text
78
+ // Pattern explanation: [url text] --> text
79
+ content = content.replace(/\[http[s]?:\/\/[^\s]+ ([^\]]+)\]/g, "$1");
80
+
81
+ // Remove Markdown link references, keeping only the link text
82
+ // Pattern explanation: ![link text](url) --> link text
83
+ content = content.replace(/\!\[([^\]]+)\]\([^\)]+\)/g, "$1");
84
+
85
+ return content;
86
+ }
87
+
88
+ sanitizeBlocks(blocks: Array<any>) {
89
+ let sanitizedBlocks = <any>[];
90
+ blocks = blocks.filter((item) => item.block_type != "table");
91
+ blocks.forEach((block) => {
92
+ let sanitizedBlock: any = {};
93
+ for (let key in block) {
94
+ let value = block[key];
95
+ if (typeof value === "string") {
96
+ sanitizedBlock[key] = this.sanitizeTextContent(value);
97
+ } else if (Array.isArray(value)) {
98
+ sanitizedBlock[key] = this.sanitizeBlocks(value);
99
+ } else {
100
+ sanitizedBlock[key] = value;
54
101
  }
55
- return dataAfterRemoving;
56
- }
57
-
58
- sanitizeTextContent(content: String) {
59
- // Remove newline characters
60
- content = content.replace(/\\n/g, ' ');
61
-
62
- // Remove internal link references, keeping only the link text
63
- // Pattern explanation: [[link|text|index|wiki]] --> text
64
- content = content.replace(/\[\[.*?\|(.*?)\|.*?\|wiki\]\]/g, '$1');
65
-
66
- // Remove external links, keeping only the link text
67
- // Pattern explanation: [url text] --> text
68
- content = content.replace(/\[http[s]?:\/\/[^\s]+ ([^\]]+)\]/g, '$1');
69
-
70
- // Remove Markdown link references, keeping only the link text
71
- // Pattern explanation: ![link text](url) --> link text
72
- content = content.replace(/\!\[([^\]]+)\]\([^\)]+\)/g, '$1');
73
-
74
- return content;
75
- }
76
-
77
- sanitizeBlocks(blocks: Array<any>) {
78
- let sanitizedBlocks = <any>[] ;
79
- blocks = blocks.filter((item)=> item.block_type != 'table');
80
- blocks.forEach(block => {
81
-
82
- let sanitizedBlock: any = {};
83
- for (let key in block) {
84
- let value = block[key];
85
- if (typeof value === 'string') {
86
- sanitizedBlock[key] = this.sanitizeTextContent(value);
87
- } else if (Array.isArray(value)) {
88
- sanitizedBlock[key] = this.sanitizeBlocks(value);
89
- } else {
90
- sanitizedBlock[key] = value;
91
- }
92
- }
93
- sanitizedBlocks.push(sanitizedBlock);
94
- });
95
- return sanitizedBlocks;
96
- }
102
+ }
103
+ sanitizedBlocks.push(sanitizedBlock);
104
+ });
105
+ return sanitizedBlocks;
106
+ }
107
+
108
+ parseVideoContent(data: Array<any>) {
109
+ let finalChapters: Array<any> = [];
110
+ // let cleanedData = this.cleanTranscript(timeCodes);
111
+ data.forEach((e) => {
112
+ let combinedContent = this.cleanTranscript(e);
113
+ finalChapters.push({
114
+ startTime: e.startTime,
115
+ endTime: e.endTime,
116
+ content: combinedContent,
117
+ title: e.content,
118
+ });
119
+ });
97
120
 
98
- parseVideoContent(data: Array<any>){
99
- let finalChapters :Array<any> = [];
100
- // let cleanedData = this.cleanTranscript(timeCodes);
101
- data.forEach((e)=>{
102
- let combinedContent = this.cleanTranscript(e);
103
- finalChapters.push({
104
- "startTime": e.startTime,
105
- "endTime": e.endTime,
106
- "content": combinedContent,
107
- "title": e.content
108
- });
109
- });
110
-
111
- return finalChapters;
112
-
113
-
114
- }
121
+ return finalChapters;
122
+ }
115
123
 
116
- // remove content inside [] which denotes non-speech sounds
117
- isNonSpeech(content: string) {
124
+ // remove content inside [] which denotes non-speech sounds
125
+ isNonSpeech(content: string) {
118
126
  // Check if the content is non-speech (enclosed in square brackets).
119
127
  return /^\[.*\]$/.test(content.trim());
120
- }
128
+ }
121
129
 
122
- // remove non-essential content
123
- cleanTranscript(data: any) {
124
- let finalContent = '';
130
+ // remove non-essential content
131
+ cleanTranscript(data: any) {
132
+ let finalContent = "";
125
133
  let children = data.children ?? [];
126
134
 
127
- children.forEach((e:any)=>{
128
- let content = (e.content || "").trim();
135
+ children.forEach((e: any) => {
136
+ let content = (e.content || "").trim();
129
137
 
130
- if(this.isNonSpeech(content)) return;
138
+ if (this.isNonSpeech(content)) return;
131
139
 
132
- content = content.replace(/\s+/g, ' ');
133
- finalContent += content;
140
+ content = content.replace(/\s+/g, " ");
141
+ finalContent += content;
134
142
  });
135
143
 
136
144
  return finalContent;
137
- }
145
+ }
138
146
 
139
- // collapse the timecode to 30 seconds
147
+ // collapse the timecode to 30 seconds
140
148
  collapseTimeCodes(data: Array<any>, maxDuration = 30.0) {
141
149
  // Collapse time codes into buckets of approximately maxDuration seconds.
142
150
  const collapsedData = [];
143
- let bucketStartTime: number | null = null;
144
- let bucketEndTime : number | null = null;
145
- let bucketContent : Array<any> = [];
151
+ let bucketStartTime: number | null = null;
152
+ let bucketEndTime: number | null = null;
153
+ let bucketContent: Array<any> = [];
146
154
  let bucketDuration = 0.0;
147
155
 
148
- data.forEach(entry => {
149
- const startTime = entry.start_time;
150
- const endTime = entry.end_time;
151
- const content = entry.content;
152
- const entryDuration = endTime - startTime;
153
-
154
- if (bucketStartTime === null) {
155
- // Start a new bucket
156
- bucketStartTime = startTime;
157
- bucketEndTime = endTime;
158
- bucketContent.push(content);
159
- bucketDuration = entryDuration;
160
- } else if ((bucketDuration + entryDuration) <= maxDuration) {
161
- // Add to current bucket
162
- bucketEndTime = endTime;
163
- bucketContent.push(content);
164
- bucketDuration += entryDuration;
165
- } else {
166
- // Close current bucket and start a new one
167
- const collapsedEntry = {
168
- start_time: bucketStartTime,
169
- end_time: bucketEndTime,
170
- content: bucketContent.join(' ')
171
- };
172
- collapsedData.push(collapsedEntry);
173
-
174
- // Start new bucket with current entry
175
- bucketStartTime = startTime;
176
- bucketEndTime = endTime;
177
- bucketContent = [content];
178
- bucketDuration = entryDuration;
179
- }
156
+ data.forEach((entry) => {
157
+ const startTime = entry.start_time;
158
+ const endTime = entry.end_time;
159
+ const content = entry.content;
160
+ const entryDuration = endTime - startTime;
161
+
162
+ if (bucketStartTime === null) {
163
+ // Start a new bucket
164
+ bucketStartTime = startTime;
165
+ bucketEndTime = endTime;
166
+ bucketContent.push(content);
167
+ bucketDuration = entryDuration;
168
+ } else if (bucketDuration + entryDuration <= maxDuration) {
169
+ // Add to current bucket
170
+ bucketEndTime = endTime;
171
+ bucketContent.push(content);
172
+ bucketDuration += entryDuration;
173
+ } else {
174
+ // Close current bucket and start a new one
175
+ const collapsedEntry = {
176
+ start_time: bucketStartTime,
177
+ end_time: bucketEndTime,
178
+ content: bucketContent.join(" "),
179
+ };
180
+ collapsedData.push(collapsedEntry);
181
+
182
+ // Start new bucket with current entry
183
+ bucketStartTime = startTime;
184
+ bucketEndTime = endTime;
185
+ bucketContent = [content];
186
+ bucketDuration = entryDuration;
187
+ }
180
188
  });
181
189
 
182
190
  // Add the last bucket if it exists
183
191
  if (bucketContent.length > 0) {
184
- const collapsedEntry = {
185
- start_time: bucketStartTime,
186
- end_time: bucketEndTime,
187
- content: bucketContent.join(' ')
188
- };
189
- collapsedData.push(collapsedEntry);
192
+ const collapsedEntry = {
193
+ start_time: bucketStartTime,
194
+ end_time: bucketEndTime,
195
+ content: bucketContent.join(" "),
196
+ };
197
+ collapsedData.push(collapsedEntry);
190
198
  }
191
199
 
192
200
  return collapsedData;
201
+ }
193
202
  }
194
-
195
-
196
-
197
- }
@@ -384,5 +384,3 @@ const sourceResp = {
384
384
  generated_at: 1718625081,
385
385
  type: "card_gen",
386
386
  };
387
-
388
-
@@ -1,44 +1,44 @@
1
1
  const typologyResponse = {
2
- "usage_data": {
3
- "prompt_tokens": 11611,
4
- "completion_tokens": 441,
5
- "total_tokens": 12052
6
- },
7
- "generated_content": {
8
- "field": [
9
- "Sciences",
10
- "Technology & Engineering",
11
- "Education, Learning & Personal Development"
12
- ],
13
- "concepts": [
14
- "Electrolysis",
15
- "Faraday's Laws of Electrolysis",
16
- "Electrolytic Cell",
17
- "Decomposition Potential",
18
- "Oxidation and Reduction at the Electrodes",
19
- "Electrolysis of Water",
20
- "Electrolysis of Carbon Dioxide",
21
- "Electrocrystallization"
22
- ],
23
- "facts": [
24
- "Electrolysis is the passing of a direct electric current through an electrolyte producing chemical reactions at the electrodes and decomposition of the materials.",
25
- "In electrolysis, the quantity of the products is proportional to the current, and when two or more electrolytic cells are connected in series to the same power source, the products produced in the cells are proportional to their equivalent weight.",
26
- "The main components required to achieve electrolysis are an electrolyte, electrodes, and an external power source.",
27
- "Faraday's laws of electrolysis detail the amount of the products of electrolysis is related to the number of electrons in the reaction at the electrodes.",
28
- "Decomposition potential or decomposition voltage refers to the minimum voltage between anode and cathode of an electrolytic cell that is needed for electrolysis to occur.",
29
- "The electrochemical reduction of carbon dioxide can produce value-added chemicals such as methane, ethylene, and ethanol."
30
- ],
31
- "generate_cards": true,
32
- "summary_cards": [
33
- "Electrolysis is the process of passing direct electric current through an electrolyte, resulting in chemical reactions and the decomposition of materials.",
34
- "Faraday's laws of electrolysis determine the relationship between the amounts of products generated and the electrons involved in the reaction at the electrodes.",
35
- "Decomposition potential is the minimum voltage required between anode and cathode for electrolysis to occur.",
36
- "The electrochemical reduction of carbon dioxide is a potential method for producing valuable chemicals such as methane, ethylene, and ethanol."
37
- ]
38
- },
39
- "generated_at": "Tue, 20 Jan 1970 21:17:46 GMT"
40
- };
2
+ usage_data: {
3
+ prompt_tokens: 11611,
4
+ completion_tokens: 441,
5
+ total_tokens: 12052,
6
+ },
7
+ generated_content: {
8
+ field: [
9
+ "Sciences",
10
+ "Technology & Engineering",
11
+ "Education, Learning & Personal Development",
12
+ ],
13
+ concepts: [
14
+ "Electrolysis",
15
+ "Faraday's Laws of Electrolysis",
16
+ "Electrolytic Cell",
17
+ "Decomposition Potential",
18
+ "Oxidation and Reduction at the Electrodes",
19
+ "Electrolysis of Water",
20
+ "Electrolysis of Carbon Dioxide",
21
+ "Electrocrystallization",
22
+ ],
23
+ facts: [
24
+ "Electrolysis is the passing of a direct electric current through an electrolyte producing chemical reactions at the electrodes and decomposition of the materials.",
25
+ "In electrolysis, the quantity of the products is proportional to the current, and when two or more electrolytic cells are connected in series to the same power source, the products produced in the cells are proportional to their equivalent weight.",
26
+ "The main components required to achieve electrolysis are an electrolyte, electrodes, and an external power source.",
27
+ "Faraday's laws of electrolysis detail the amount of the products of electrolysis is related to the number of electrons in the reaction at the electrodes.",
28
+ "Decomposition potential or decomposition voltage refers to the minimum voltage between anode and cathode of an electrolytic cell that is needed for electrolysis to occur.",
29
+ "The electrochemical reduction of carbon dioxide can produce value-added chemicals such as methane, ethylene, and ethanol.",
30
+ ],
31
+ generate_cards: true,
32
+ summary_cards: [
33
+ "Electrolysis is the process of passing direct electric current through an electrolyte, resulting in chemical reactions and the decomposition of materials.",
34
+ "Faraday's laws of electrolysis determine the relationship between the amounts of products generated and the electrons involved in the reaction at the electrodes.",
35
+ "Decomposition potential is the minimum voltage required between anode and cathode for electrolysis to occur.",
36
+ "The electrochemical reduction of carbon dioxide is a potential method for producing valuable chemicals such as methane, ethylene, and ethanol.",
37
+ ],
38
+ },
39
+ generated_at: "Tue, 20 Jan 1970 21:17:46 GMT",
40
+ };
41
41
 
42
- export function returnTypologyData(){
43
- return typologyResponse as any;
44
- }
42
+ export function returnTypologyData() {
43
+ return typologyResponse as any;
44
+ }
@@ -1,54 +1,56 @@
1
1
  import axios from "axios";
2
- import { parseOpenAiFailureResponse, parseOpenAiSuccessResponse } from "../utils/parse_openai_response";
2
+ import {
3
+ parseOpenAiFailureResponse,
4
+ parseOpenAiSuccessResponse,
5
+ } from "../utils/parse_openai_response";
3
6
  import { openAiEndPoint } from "../constants/api_constants";
4
7
 
8
+ export class OpenAiService {
9
+ public api_key: string;
10
+ public model: string;
5
11
 
6
- export class OpenAiService{
7
- public api_key: string;
8
- public model: string;
9
-
10
- constructor(apiKey: string, model:string){
11
- this.api_key = apiKey;
12
- this.model =model
13
- }
12
+ constructor(apiKey: string, model: string) {
13
+ this.api_key = apiKey;
14
+ this.model = model;
15
+ }
14
16
 
15
- async sendRequest(prompt: string,content: string){
16
- try{
17
- let message = [
18
- {
19
- "role": "system", "content": prompt
20
- },{
21
- "role": "user", "content": content
22
- }
23
- ];
24
- const url = openAiEndPoint();
25
- let response = await axios.post(
26
- url,
27
- {
28
- "model": this.model,
29
- "messages": message,
30
- "response_format": {"type": "json_object"},
31
- },
32
- {
33
- headers : {
34
- Authorization : "Bearer "+ this.api_key,
35
- "Content-Type" : ['application/json']
36
- },
37
-
38
- }
39
-
40
- );
41
-
42
- if(response.status == 200){
43
- console.log('success');
44
- return parseOpenAiSuccessResponse(response.data) as any
45
-
46
- }else{
47
- console.log('failed');
48
- return response.statusText as any;
49
- }}catch (err:any) {
50
- return parseOpenAiFailureResponse(err.response);
51
- }
52
- }
53
- }
17
+ async sendRequest(prompt: string, content: string) {
18
+ try {
19
+ let message = [
20
+ {
21
+ role: "system",
22
+ content: prompt,
23
+ },
24
+ {
25
+ role: "user",
26
+ content: content,
27
+ },
28
+ ];
29
+ const url = openAiEndPoint();
30
+ let response = await axios.post(
31
+ url,
32
+ {
33
+ model: this.model,
34
+ messages: message,
35
+ response_format: { type: "json_object" },
36
+ },
37
+ {
38
+ headers: {
39
+ Authorization: "Bearer " + this.api_key,
40
+ "Content-Type": ["application/json"],
41
+ },
42
+ }
43
+ );
54
44
 
45
+ if (response.status == 200) {
46
+ console.log("success");
47
+ return parseOpenAiSuccessResponse(response.data) as any;
48
+ } else {
49
+ console.log("failed");
50
+ return response.statusText as any;
51
+ }
52
+ } catch (err: any) {
53
+ return parseOpenAiFailureResponse(err.response);
54
+ }
55
+ }
56
+ }