@learnpack/learnpack 5.0.320 → 5.0.322

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.
@@ -1,639 +1,639 @@
1
- import axios from "axios"
2
- import { writeFile } from "fs/promises"
3
- import Console from "../utils/console"
4
- import { PackageInfo } from "./creatorUtilities"
5
- import * as fs from "fs"
6
- import * as path from "path"
7
- import { RIGOBOT_HOST } from "./api"
8
-
9
- type TCreateReadmeInputs = {
10
- title: string;
11
- output_lang: string;
12
- list_of_exercises: string;
13
- tutorial_description: string;
14
- include_quiz: string;
15
- lesson_description: string;
16
- prev_lesson: string;
17
- };
18
-
19
- export const createReadme = async (
20
- token: string,
21
- inputs: TCreateReadmeInputs,
22
- purpose: string,
23
- webhookUrl?: string
24
- ) => {
25
- try {
26
- const response = await axios.post(
27
- `${RIGOBOT_HOST}/v1/prompting/completion/create-sequencial-readme/`,
28
- {
29
- inputs,
30
- include_purpose_objective: true,
31
- execute_async: !!webhookUrl,
32
- purpose_slug: purpose,
33
- webhook_url: webhookUrl,
34
- },
35
- {
36
- headers: {
37
- "Content-Type": "application/json",
38
- Authorization: "Token " + token.trim(),
39
- },
40
- }
41
- )
42
- return response.data
43
- } catch (error) {
44
- console.error(error)
45
- return null
46
- }
47
- }
48
-
49
- export const hasCreatorPermission = async (token: string) => {
50
- Console.debug("Checking if user has creator permission")
51
- try {
52
- const response = await axios.get(
53
- `${RIGOBOT_HOST}/v1/learnpack/permissions/creator`,
54
- {
55
- headers: {
56
- "Content-Type": "application/json",
57
- Authorization: "Token " + token,
58
- },
59
- }
60
- )
61
-
62
- // If the status code is 403, it means no permission
63
- if (response.status === 403) return false
64
-
65
- Console.debug("The user is a creator! 🎉")
66
- return true
67
- } catch (error) {
68
- Console.error(error as string)
69
- return false
70
- }
71
- }
72
-
73
- type TGenerateImageParams = {
74
- prompt: string;
75
- callbackUrl: string;
76
- };
77
-
78
- export const generateImage = async (
79
- token: string,
80
- { prompt, callbackUrl }: TGenerateImageParams
81
- ) => {
82
- try {
83
- const response = await axios.post(
84
- `${RIGOBOT_HOST}/v1/learnpack/tools/images`,
85
- {
86
- prompt,
87
- webhook_callback_url: callbackUrl,
88
- provider: "bfl",
89
- model: "flux-pro-1.1",
90
- },
91
- {
92
- headers: {
93
- "Content-Type": "application/json",
94
- Authorization: "Token " + token,
95
- },
96
- }
97
- )
98
-
99
- return response.data
100
- } catch (error) {
101
- Console.debug(error)
102
- return null
103
- }
104
- }
105
-
106
- export async function downloadImage(
107
- imageUrl: string,
108
- savePath: string
109
- ): Promise<void> {
110
- const response = await axios.get(imageUrl, { responseType: "arraybuffer" })
111
-
112
- const buffer = Buffer.from(response.data, "binary")
113
-
114
- await writeFile(savePath, buffer)
115
- }
116
-
117
- type TTranslateInputs = {
118
- text_to_translate: string;
119
- output_language: string;
120
- };
121
- export const translateExercise = async (
122
- token: string,
123
- inputs: TTranslateInputs,
124
- webhookUrl: string
125
- ) => {
126
- const response = await axios.post(
127
- `${RIGOBOT_HOST}/v1/prompting/completion/translate-asset-markdown/`,
128
- {
129
- inputs: inputs,
130
- include_purpose_objective: false,
131
- execute_async: true,
132
- webhook_url: webhookUrl,
133
- },
134
- {
135
- headers: {
136
- "Content-Type": "application/json",
137
- Authorization: "Token " + token,
138
- },
139
- }
140
- )
141
-
142
- return response.data
143
- }
144
-
145
- type TGenerateCourseIntroductionInputs = {
146
- course_title: string;
147
- lessons_context: string;
148
- };
149
-
150
- export const generateCourseIntroduction = async (
151
- token: string,
152
- inputs: TGenerateCourseIntroductionInputs
153
- ) => {
154
- const response = await axios.post(
155
- `${RIGOBOT_HOST}/v1/prompting/completion/192/`,
156
- {
157
- inputs: inputs,
158
- include_purpose_objective: false,
159
- execute_async: false,
160
- },
161
- {
162
- headers: {
163
- "Content-Type": "application/json",
164
- Authorization: "Token " + token,
165
- },
166
- }
167
- )
168
-
169
- return response.data
170
- }
171
-
172
- type TInteractiveCreationInputs = {
173
- courseInfo: string;
174
- prevInteractions: string;
175
- };
176
- export const interactiveCreation = async (
177
- token: string,
178
- inputs: TInteractiveCreationInputs
179
- ) => {
180
- const response = await axios.post(
181
- `${RIGOBOT_HOST}/v1/prompting/completion/390/`,
182
- {
183
- inputs: inputs,
184
- include_purpose_objective: false,
185
- execute_async: false,
186
- },
187
- {
188
- headers: {
189
- "Content-Type": "application/json",
190
- Authorization: "Token " + token,
191
- },
192
- }
193
- )
194
-
195
- return response.data
196
- }
197
-
198
- type TCreateCodeFileInputs = {
199
- readme: string;
200
- tutorial_info: string;
201
- };
202
-
203
- export const createCodeFile = async (
204
- token: string,
205
- inputs: TCreateCodeFileInputs
206
- ) => {
207
- const response = await axios.post(
208
- `${RIGOBOT_HOST}/v1/prompting/completion/456/`,
209
- {
210
- inputs: inputs,
211
- include_purpose_objective: false,
212
- execute_async: false,
213
- },
214
- {
215
- headers: {
216
- "Content-Type": "application/json",
217
- Authorization: "Token " + token,
218
- },
219
- }
220
- )
221
-
222
- return response.data
223
- }
224
-
225
- type TCreateCodingReadmeInputs = {
226
- title: string;
227
- output_lang: string;
228
- prev_lesson: string;
229
- tutorial_info: string;
230
- list_of_exercises: string;
231
- lesson_description: string;
232
- };
233
- export const createCodingReadme = async (
234
- token: string,
235
- inputs: TCreateCodingReadmeInputs,
236
- purpose: string,
237
- webhookUrl?: string
238
- ) => {
239
- const response = await axios.post(
240
- `${RIGOBOT_HOST}/v1/prompting/completion/create-coding-exercise/`,
241
- {
242
- inputs,
243
- include_purpose_objective: true,
244
- purpose_slug: purpose,
245
- execute_async: !!webhookUrl,
246
- webhook_url: webhookUrl,
247
- },
248
- {
249
- headers: {
250
- "Content-Type": "application/json",
251
- Authorization: "Token " + token,
252
- },
253
- }
254
- )
255
-
256
- return response.data
257
- }
258
-
259
- type TReadmeCreatorInputs = {
260
- tutorial_description: string;
261
- list_of_exercises: string;
262
- output_lang: string;
263
- title: string;
264
- lesson_description: string;
265
- kind: string;
266
- last_lesson: string;
267
- };
268
-
269
- export const readmeCreator = async (
270
- token: string,
271
- inputs: TReadmeCreatorInputs,
272
- purpose: string,
273
- webhookUrl?: string
274
- ) => {
275
- if (inputs.kind === "quiz" || inputs.kind === "read") {
276
- const createReadmeInputs: TCreateReadmeInputs = {
277
- title: inputs.title,
278
- output_lang: inputs.output_lang,
279
- list_of_exercises: inputs.list_of_exercises,
280
- tutorial_description: inputs.tutorial_description,
281
- include_quiz: inputs.kind === "quiz" ? "true" : "false",
282
- lesson_description: inputs.lesson_description,
283
- prev_lesson: inputs.last_lesson,
284
- }
285
- return createReadme(token, createReadmeInputs, purpose, webhookUrl)
286
- }
287
-
288
- if (inputs.kind === "code") {
289
- return createCodingReadme(
290
- token,
291
- {
292
- title: inputs.title,
293
- output_lang: inputs.output_lang,
294
- list_of_exercises: inputs.list_of_exercises,
295
- tutorial_info: inputs.tutorial_description,
296
- lesson_description: inputs.lesson_description,
297
- prev_lesson: inputs.last_lesson,
298
- },
299
- purpose,
300
- webhookUrl
301
- )
302
- }
303
-
304
- throw new Error("Invalid kind of lesson")
305
- }
306
-
307
- type TCreateStructuredPreviewReadmeInputs = {
308
- tutorial_info: string;
309
- };
310
-
311
- export const createStructuredPreviewReadme = async (
312
- token: string,
313
- inputs: TCreateStructuredPreviewReadmeInputs,
314
- webhookUrl?: string
315
- ) => {
316
- const response = await axios.post(
317
- `${RIGOBOT_HOST}/v1/prompting/completion/write-course-introduction-readme/`,
318
- {
319
- inputs: inputs,
320
- include_purpose_objective: false,
321
- webhook_url: webhookUrl,
322
- },
323
- {
324
- headers: {
325
- "Content-Type": "application/json",
326
- Authorization: "Token " + token.trim(),
327
- },
328
- }
329
- )
330
-
331
- return response.data
332
- }
333
-
334
- export const translateCourseMetadata = async (
335
- token: string,
336
- inputs: {
337
- title: string;
338
- description: string;
339
- new_languages: string;
340
- }
341
- ) => {
342
- const response = await axios.post(
343
- `${RIGOBOT_HOST}/v1/prompting/completion/translate-course-metadata/`,
344
- { inputs, include_purpose_objective: false, execute_async: false },
345
- {
346
- headers: {
347
- "Content-Type": "application/json",
348
- Authorization: "Token " + token,
349
- },
350
- }
351
- )
352
-
353
- return response.data
354
- }
355
-
356
- export async function createPreviewReadme(
357
- tutorialDir: string,
358
- packageInfo: PackageInfo,
359
- rigoToken: string,
360
- readmeContents: string[]
361
- ) {
362
- const readmeFilename = `README.md`
363
-
364
- const readmeContent = await generateCourseIntroduction(rigoToken, {
365
- course_title: packageInfo.title.us,
366
- lessons_context: readmeContents.join("\n"),
367
- })
368
- fs.writeFileSync(
369
- path.join(tutorialDir, readmeFilename),
370
- readmeContent.answer
371
- )
372
- }
373
-
374
- // {"lesson": "The text of the lesson", "number_of_words": "Words lenght of the lesson", "expected_number_words": "The expected number of words"}
375
-
376
- type TReduceReadmeInputs = {
377
- lesson: string;
378
- number_of_words: string;
379
- expected_number_words: string;
380
- fkgl_results: string;
381
- expected_grade_level: string;
382
- };
383
- export async function makeReadmeReadable(
384
- rigoToken: string,
385
- inputs: TReduceReadmeInputs,
386
- purpose: string
387
- ) {
388
- try {
389
- const response = await axios.post(
390
- `${RIGOBOT_HOST}/v1/prompting/completion/588/`,
391
- { inputs, include_purpose_objective: false, execute_async: false },
392
- {
393
- headers: {
394
- "Content-Type": "application/json",
395
- Authorization: "Token " + rigoToken,
396
- },
397
- }
398
- )
399
-
400
- return response.data
401
- } catch (error) {
402
- Console.debug(error)
403
- return null
404
- }
405
- }
406
-
407
- export const isValidRigoToken = async (rigobotToken: string) => {
408
- const rigoUrl = `${RIGOBOT_HOST}/v1/auth/token/${rigobotToken}`
409
- const rigoResp = await fetch(rigoUrl)
410
- if (!rigoResp.ok) {
411
- Console.debug("Invalid Rigobot token", rigoResp.status)
412
- Console.debug(rigoResp.statusText)
413
- return false
414
- }
415
-
416
- return true
417
- }
418
-
419
- type TGenerateCourseShortNameInputs = {
420
- learnJSON: string;
421
- };
422
-
423
- export const generateCourseShortName = async (
424
- token: string,
425
- inputs: TGenerateCourseShortNameInputs
426
- ) => {
427
- const response = await axios.post(
428
- `${RIGOBOT_HOST}/v1/prompting/completion/852/`,
429
- { inputs, include_purpose_objective: false, execute_async: false },
430
- {
431
- headers: {
432
- "Content-Type": "application/json",
433
- Authorization: "Token " + token,
434
- },
435
- }
436
- )
437
-
438
- return response.data
439
- }
440
-
441
- type TFillSidebarJSONInputs = {
442
- needed_translations: string;
443
- sidebar_json: string;
444
- };
445
-
446
- export const fillSidebarJSON = async (
447
- token: string,
448
- inputs: TFillSidebarJSONInputs
449
- ) => {
450
- const response = await axios.post(
451
- `${RIGOBOT_HOST}/v1/prompting/completion/951/`,
452
- { inputs, include_purpose_objective: false, execute_async: false },
453
- {
454
- headers: {
455
- "Content-Type": "application/json",
456
- Authorization: "Token " + token,
457
- },
458
- }
459
- )
460
-
461
- return response.data
462
- }
463
-
464
- export const isPackageAuthor = async (
465
- token: string,
466
- packageSlug: string
467
- ): Promise<{ isAuthor: boolean; status: number }> => {
468
- const url = `${RIGOBOT_HOST}/v1/learnpack/package/${packageSlug}/`
469
-
470
- const headers = {
471
- Authorization: `Token ${token}`,
472
- }
473
-
474
- try {
475
- const response = await axios.get(url, { headers })
476
- return { isAuthor: response.status === 200, status: response.status }
477
- } catch (error: any) {
478
- const status = error?.response?.status || 500
479
- console.error("Error fetching package:", error)
480
- return { isAuthor: false, status }
481
- }
482
- }
483
-
484
- type TGetLanguageCodesInputs = {
485
- raw_languages: string;
486
- };
487
- export const getLanguageCodes = async (
488
- token: string,
489
- inputs: TGetLanguageCodesInputs
490
- ) => {
491
- const response = await axios.post(
492
- `${RIGOBOT_HOST}/v1/prompting/completion/get-language-codes/`,
493
- { inputs, include_purpose_objective: false, execute_async: false },
494
- {
495
- headers: {
496
- "Content-Type": "application/json",
497
- Authorization: "Token " + token,
498
- },
499
- }
500
- )
501
-
502
- return response.data
503
- }
504
-
505
- // New two-phase generation functions
506
-
507
- type TInitialContentGeneratorInputs = {
508
- // prev_lesson: string;
509
- output_language: string;
510
- current_syllabus: string;
511
- lesson_description: string;
512
- };
513
-
514
- export const initialContentGenerator = async (
515
- token: string,
516
- inputs: TInitialContentGeneratorInputs,
517
- webhookUrl?: string,
518
- endpointSlug = "initial-step-content-generator"
519
- ) => {
520
- try {
521
- const response = await axios.post(
522
- `${RIGOBOT_HOST}/v1/prompting/completion/${endpointSlug}/`,
523
- {
524
- inputs,
525
- include_purpose_objective: false,
526
- execute_async: !!webhookUrl,
527
- webhook_url: webhookUrl,
528
- },
529
- {
530
- headers: {
531
- "Content-Type": "application/json",
532
- Authorization: "Token " + token.trim(),
533
- },
534
- }
535
- )
536
- return response.data
537
- } catch (error) {
538
- console.error("Error in initialContentGenerator:", error)
539
- return null
540
- }
541
- }
542
-
543
- type TAddInteractivityInputs = {
544
- components: string;
545
- prev_lesson: string;
546
- initial_lesson: string;
547
- output_language: string;
548
- current_syllabus: string;
549
- };
550
-
551
- export const addInteractivity = async (
552
- token: string,
553
- inputs: TAddInteractivityInputs,
554
- webhookUrl?: string
555
- ) => {
556
- try {
557
- const response = await axios.post(
558
- `${RIGOBOT_HOST}/v1/prompting/completion/lesson-refiner/`,
559
- {
560
- inputs,
561
- include_purpose_objective: false,
562
- execute_async: !!webhookUrl,
563
- webhook_url: webhookUrl,
564
- },
565
- {
566
- headers: {
567
- "Content-Type": "application/json",
568
- Authorization: "Token " + token.trim(),
569
- },
570
- }
571
- )
572
- return response.data
573
- } catch (error) {
574
- console.error("Error in addInteractivity:", error)
575
- return null
576
- }
577
- }
578
-
579
- type TGenerateCodeChallengeInputs = {
580
- lesson_content: string;
581
- challenge_proposal: string;
582
- };
583
-
584
- export const generateCodeChallenge = async (
585
- token: string,
586
- inputs: TGenerateCodeChallengeInputs,
587
- webhookUrl?: string
588
- ) => {
589
- try {
590
- const response = await axios.post(
591
- `${RIGOBOT_HOST}/v1/prompting/completion/generate-code-challenge-files/`,
592
- {
593
- inputs,
594
- include_purpose_objective: false,
595
- execute_async: !!webhookUrl,
596
- webhook_url: webhookUrl,
597
- },
598
- {
599
- headers: {
600
- "Content-Type": "application/json",
601
- Authorization: "Token " + token.trim(),
602
- },
603
- }
604
- )
605
- return response.data
606
- } catch (error) {
607
- console.error("Error in generateCodeChallenge:", error)
608
- return null
609
- }
610
- }
611
-
612
- type TCreateStepInputs = {
613
- description: string;
614
- stepIndex: number;
615
- courseInfo: string;
616
- lang: string;
617
- };
618
-
619
- export const generateStepSlug = async (
620
- token: string,
621
- inputs: TCreateStepInputs
622
- ) => {
623
- try {
624
- const response = await axios.post(
625
- `${RIGOBOT_HOST}/v1/prompting/completion/step-slug-generator/`,
626
- { inputs, include_purpose_objective: false, execute_async: false },
627
- {
628
- headers: {
629
- "Content-Type": "application/json",
630
- Authorization: "Token " + token.trim(),
631
- },
632
- }
633
- )
634
- return response.data
635
- } catch (error) {
636
- console.error("Error in createStep:", error)
637
- return null
638
- }
639
- }
1
+ import axios from "axios"
2
+ import { writeFile } from "fs/promises"
3
+ import Console from "../utils/console"
4
+ import { PackageInfo } from "./creatorUtilities"
5
+ import * as fs from "fs"
6
+ import * as path from "path"
7
+ import { RIGOBOT_HOST } from "./api"
8
+
9
+ type TCreateReadmeInputs = {
10
+ title: string;
11
+ output_lang: string;
12
+ list_of_exercises: string;
13
+ tutorial_description: string;
14
+ include_quiz: string;
15
+ lesson_description: string;
16
+ prev_lesson: string;
17
+ };
18
+
19
+ export const createReadme = async (
20
+ token: string,
21
+ inputs: TCreateReadmeInputs,
22
+ purpose: string,
23
+ webhookUrl?: string
24
+ ) => {
25
+ try {
26
+ const response = await axios.post(
27
+ `${RIGOBOT_HOST}/v1/prompting/completion/create-sequencial-readme/`,
28
+ {
29
+ inputs,
30
+ include_purpose_objective: true,
31
+ execute_async: !!webhookUrl,
32
+ purpose_slug: purpose,
33
+ webhook_url: webhookUrl,
34
+ },
35
+ {
36
+ headers: {
37
+ "Content-Type": "application/json",
38
+ Authorization: "Token " + token.trim(),
39
+ },
40
+ }
41
+ )
42
+ return response.data
43
+ } catch (error) {
44
+ console.error(error)
45
+ return null
46
+ }
47
+ }
48
+
49
+ export const hasCreatorPermission = async (token: string) => {
50
+ Console.debug("Checking if user has creator permission")
51
+ try {
52
+ const response = await axios.get(
53
+ `${RIGOBOT_HOST}/v1/learnpack/permissions/creator`,
54
+ {
55
+ headers: {
56
+ "Content-Type": "application/json",
57
+ Authorization: "Token " + token,
58
+ },
59
+ }
60
+ )
61
+
62
+ // If the status code is 403, it means no permission
63
+ if (response.status === 403) return false
64
+
65
+ Console.debug("The user is a creator! 🎉")
66
+ return true
67
+ } catch (error) {
68
+ Console.error(error as string)
69
+ return false
70
+ }
71
+ }
72
+
73
+ type TGenerateImageParams = {
74
+ prompt: string;
75
+ callbackUrl: string;
76
+ };
77
+
78
+ export const generateImage = async (
79
+ token: string,
80
+ { prompt, callbackUrl }: TGenerateImageParams
81
+ ) => {
82
+ try {
83
+ const response = await axios.post(
84
+ `${RIGOBOT_HOST}/v1/learnpack/tools/images`,
85
+ {
86
+ prompt,
87
+ webhook_callback_url: callbackUrl,
88
+ provider: "bfl",
89
+ model: "flux-pro-1.1",
90
+ },
91
+ {
92
+ headers: {
93
+ "Content-Type": "application/json",
94
+ Authorization: "Token " + token,
95
+ },
96
+ }
97
+ )
98
+
99
+ return response.data
100
+ } catch (error) {
101
+ Console.debug(error)
102
+ return null
103
+ }
104
+ }
105
+
106
+ export async function downloadImage(
107
+ imageUrl: string,
108
+ savePath: string
109
+ ): Promise<void> {
110
+ const response = await axios.get(imageUrl, { responseType: "arraybuffer" })
111
+
112
+ const buffer = Buffer.from(response.data, "binary")
113
+
114
+ await writeFile(savePath, buffer)
115
+ }
116
+
117
+ type TTranslateInputs = {
118
+ text_to_translate: string;
119
+ output_language: string;
120
+ };
121
+ export const translateExercise = async (
122
+ token: string,
123
+ inputs: TTranslateInputs,
124
+ webhookUrl: string
125
+ ) => {
126
+ const response = await axios.post(
127
+ `${RIGOBOT_HOST}/v1/prompting/completion/translate-asset-markdown/`,
128
+ {
129
+ inputs: inputs,
130
+ include_purpose_objective: false,
131
+ execute_async: true,
132
+ webhook_url: webhookUrl,
133
+ },
134
+ {
135
+ headers: {
136
+ "Content-Type": "application/json",
137
+ Authorization: "Token " + token,
138
+ },
139
+ }
140
+ )
141
+
142
+ return response.data
143
+ }
144
+
145
+ type TGenerateCourseIntroductionInputs = {
146
+ course_title: string;
147
+ lessons_context: string;
148
+ };
149
+
150
+ export const generateCourseIntroduction = async (
151
+ token: string,
152
+ inputs: TGenerateCourseIntroductionInputs
153
+ ) => {
154
+ const response = await axios.post(
155
+ `${RIGOBOT_HOST}/v1/prompting/completion/192/`,
156
+ {
157
+ inputs: inputs,
158
+ include_purpose_objective: false,
159
+ execute_async: false,
160
+ },
161
+ {
162
+ headers: {
163
+ "Content-Type": "application/json",
164
+ Authorization: "Token " + token,
165
+ },
166
+ }
167
+ )
168
+
169
+ return response.data
170
+ }
171
+
172
+ type TInteractiveCreationInputs = {
173
+ courseInfo: string;
174
+ prevInteractions: string;
175
+ };
176
+ export const interactiveCreation = async (
177
+ token: string,
178
+ inputs: TInteractiveCreationInputs
179
+ ) => {
180
+ const response = await axios.post(
181
+ `${RIGOBOT_HOST}/v1/prompting/completion/390/`,
182
+ {
183
+ inputs: inputs,
184
+ include_purpose_objective: false,
185
+ execute_async: false,
186
+ },
187
+ {
188
+ headers: {
189
+ "Content-Type": "application/json",
190
+ Authorization: "Token " + token,
191
+ },
192
+ }
193
+ )
194
+
195
+ return response.data
196
+ }
197
+
198
+ type TCreateCodeFileInputs = {
199
+ readme: string;
200
+ tutorial_info: string;
201
+ };
202
+
203
+ export const createCodeFile = async (
204
+ token: string,
205
+ inputs: TCreateCodeFileInputs
206
+ ) => {
207
+ const response = await axios.post(
208
+ `${RIGOBOT_HOST}/v1/prompting/completion/456/`,
209
+ {
210
+ inputs: inputs,
211
+ include_purpose_objective: false,
212
+ execute_async: false,
213
+ },
214
+ {
215
+ headers: {
216
+ "Content-Type": "application/json",
217
+ Authorization: "Token " + token,
218
+ },
219
+ }
220
+ )
221
+
222
+ return response.data
223
+ }
224
+
225
+ type TCreateCodingReadmeInputs = {
226
+ title: string;
227
+ output_lang: string;
228
+ prev_lesson: string;
229
+ tutorial_info: string;
230
+ list_of_exercises: string;
231
+ lesson_description: string;
232
+ };
233
+ export const createCodingReadme = async (
234
+ token: string,
235
+ inputs: TCreateCodingReadmeInputs,
236
+ purpose: string,
237
+ webhookUrl?: string
238
+ ) => {
239
+ const response = await axios.post(
240
+ `${RIGOBOT_HOST}/v1/prompting/completion/create-coding-exercise/`,
241
+ {
242
+ inputs,
243
+ include_purpose_objective: true,
244
+ purpose_slug: purpose,
245
+ execute_async: !!webhookUrl,
246
+ webhook_url: webhookUrl,
247
+ },
248
+ {
249
+ headers: {
250
+ "Content-Type": "application/json",
251
+ Authorization: "Token " + token,
252
+ },
253
+ }
254
+ )
255
+
256
+ return response.data
257
+ }
258
+
259
+ type TReadmeCreatorInputs = {
260
+ tutorial_description: string;
261
+ list_of_exercises: string;
262
+ output_lang: string;
263
+ title: string;
264
+ lesson_description: string;
265
+ kind: string;
266
+ last_lesson: string;
267
+ };
268
+
269
+ export const readmeCreator = async (
270
+ token: string,
271
+ inputs: TReadmeCreatorInputs,
272
+ purpose: string,
273
+ webhookUrl?: string
274
+ ) => {
275
+ if (inputs.kind === "quiz" || inputs.kind === "read") {
276
+ const createReadmeInputs: TCreateReadmeInputs = {
277
+ title: inputs.title,
278
+ output_lang: inputs.output_lang,
279
+ list_of_exercises: inputs.list_of_exercises,
280
+ tutorial_description: inputs.tutorial_description,
281
+ include_quiz: inputs.kind === "quiz" ? "true" : "false",
282
+ lesson_description: inputs.lesson_description,
283
+ prev_lesson: inputs.last_lesson,
284
+ }
285
+ return createReadme(token, createReadmeInputs, purpose, webhookUrl)
286
+ }
287
+
288
+ if (inputs.kind === "code") {
289
+ return createCodingReadme(
290
+ token,
291
+ {
292
+ title: inputs.title,
293
+ output_lang: inputs.output_lang,
294
+ list_of_exercises: inputs.list_of_exercises,
295
+ tutorial_info: inputs.tutorial_description,
296
+ lesson_description: inputs.lesson_description,
297
+ prev_lesson: inputs.last_lesson,
298
+ },
299
+ purpose,
300
+ webhookUrl
301
+ )
302
+ }
303
+
304
+ throw new Error("Invalid kind of lesson")
305
+ }
306
+
307
+ type TCreateStructuredPreviewReadmeInputs = {
308
+ tutorial_info: string;
309
+ };
310
+
311
+ export const createStructuredPreviewReadme = async (
312
+ token: string,
313
+ inputs: TCreateStructuredPreviewReadmeInputs,
314
+ webhookUrl?: string
315
+ ) => {
316
+ const response = await axios.post(
317
+ `${RIGOBOT_HOST}/v1/prompting/completion/write-course-introduction-readme/`,
318
+ {
319
+ inputs: inputs,
320
+ include_purpose_objective: false,
321
+ webhook_url: webhookUrl,
322
+ },
323
+ {
324
+ headers: {
325
+ "Content-Type": "application/json",
326
+ Authorization: "Token " + token.trim(),
327
+ },
328
+ }
329
+ )
330
+
331
+ return response.data
332
+ }
333
+
334
+ export const translateCourseMetadata = async (
335
+ token: string,
336
+ inputs: {
337
+ title: string;
338
+ description: string;
339
+ new_languages: string;
340
+ }
341
+ ) => {
342
+ const response = await axios.post(
343
+ `${RIGOBOT_HOST}/v1/prompting/completion/translate-course-metadata/`,
344
+ { inputs, include_purpose_objective: false, execute_async: false },
345
+ {
346
+ headers: {
347
+ "Content-Type": "application/json",
348
+ Authorization: "Token " + token,
349
+ },
350
+ }
351
+ )
352
+
353
+ return response.data
354
+ }
355
+
356
+ export async function createPreviewReadme(
357
+ tutorialDir: string,
358
+ packageInfo: PackageInfo,
359
+ rigoToken: string,
360
+ readmeContents: string[]
361
+ ) {
362
+ const readmeFilename = `README.md`
363
+
364
+ const readmeContent = await generateCourseIntroduction(rigoToken, {
365
+ course_title: packageInfo.title.us,
366
+ lessons_context: readmeContents.join("\n"),
367
+ })
368
+ fs.writeFileSync(
369
+ path.join(tutorialDir, readmeFilename),
370
+ readmeContent.answer
371
+ )
372
+ }
373
+
374
+ // {"lesson": "The text of the lesson", "number_of_words": "Words lenght of the lesson", "expected_number_words": "The expected number of words"}
375
+
376
+ type TReduceReadmeInputs = {
377
+ lesson: string;
378
+ number_of_words: string;
379
+ expected_number_words: string;
380
+ fkgl_results: string;
381
+ expected_grade_level: string;
382
+ };
383
+ export async function makeReadmeReadable(
384
+ rigoToken: string,
385
+ inputs: TReduceReadmeInputs,
386
+ purpose: string
387
+ ) {
388
+ try {
389
+ const response = await axios.post(
390
+ `${RIGOBOT_HOST}/v1/prompting/completion/588/`,
391
+ { inputs, include_purpose_objective: false, execute_async: false },
392
+ {
393
+ headers: {
394
+ "Content-Type": "application/json",
395
+ Authorization: "Token " + rigoToken,
396
+ },
397
+ }
398
+ )
399
+
400
+ return response.data
401
+ } catch (error) {
402
+ Console.debug(error)
403
+ return null
404
+ }
405
+ }
406
+
407
+ export const isValidRigoToken = async (rigobotToken: string) => {
408
+ const rigoUrl = `${RIGOBOT_HOST}/v1/auth/token/${rigobotToken}`
409
+ const rigoResp = await fetch(rigoUrl)
410
+ if (!rigoResp.ok) {
411
+ Console.debug("Invalid Rigobot token", rigoResp.status)
412
+ Console.debug(rigoResp.statusText)
413
+ return false
414
+ }
415
+
416
+ return true
417
+ }
418
+
419
+ type TGenerateCourseShortNameInputs = {
420
+ learnJSON: string;
421
+ };
422
+
423
+ export const generateCourseShortName = async (
424
+ token: string,
425
+ inputs: TGenerateCourseShortNameInputs
426
+ ) => {
427
+ const response = await axios.post(
428
+ `${RIGOBOT_HOST}/v1/prompting/completion/852/`,
429
+ { inputs, include_purpose_objective: false, execute_async: false },
430
+ {
431
+ headers: {
432
+ "Content-Type": "application/json",
433
+ Authorization: "Token " + token,
434
+ },
435
+ }
436
+ )
437
+
438
+ return response.data
439
+ }
440
+
441
+ type TFillSidebarJSONInputs = {
442
+ needed_translations: string;
443
+ sidebar_json: string;
444
+ };
445
+
446
+ export const fillSidebarJSON = async (
447
+ token: string,
448
+ inputs: TFillSidebarJSONInputs
449
+ ) => {
450
+ const response = await axios.post(
451
+ `${RIGOBOT_HOST}/v1/prompting/completion/951/`,
452
+ { inputs, include_purpose_objective: false, execute_async: false },
453
+ {
454
+ headers: {
455
+ "Content-Type": "application/json",
456
+ Authorization: "Token " + token,
457
+ },
458
+ }
459
+ )
460
+
461
+ return response.data
462
+ }
463
+
464
+ export const isPackageAuthor = async (
465
+ token: string,
466
+ packageSlug: string
467
+ ): Promise<{ isAuthor: boolean; status: number }> => {
468
+ const url = `${RIGOBOT_HOST}/v1/learnpack/package/${packageSlug}/`
469
+
470
+ const headers = {
471
+ Authorization: `Token ${token}`,
472
+ }
473
+
474
+ try {
475
+ const response = await axios.get(url, { headers })
476
+ return { isAuthor: response.status === 200, status: response.status }
477
+ } catch (error: any) {
478
+ const status = error?.response?.status || 500
479
+ console.error("Error fetching package:", error)
480
+ return { isAuthor: false, status }
481
+ }
482
+ }
483
+
484
+ type TGetLanguageCodesInputs = {
485
+ raw_languages: string;
486
+ };
487
+ export const getLanguageCodes = async (
488
+ token: string,
489
+ inputs: TGetLanguageCodesInputs
490
+ ) => {
491
+ const response = await axios.post(
492
+ `${RIGOBOT_HOST}/v1/prompting/completion/get-language-codes/`,
493
+ { inputs, include_purpose_objective: false, execute_async: false },
494
+ {
495
+ headers: {
496
+ "Content-Type": "application/json",
497
+ Authorization: "Token " + token,
498
+ },
499
+ }
500
+ )
501
+
502
+ return response.data
503
+ }
504
+
505
+ // New two-phase generation functions
506
+
507
+ type TInitialContentGeneratorInputs = {
508
+ // prev_lesson: string;
509
+ output_language: string;
510
+ current_syllabus: string;
511
+ lesson_description: string;
512
+ };
513
+
514
+ export const initialContentGenerator = async (
515
+ token: string,
516
+ inputs: TInitialContentGeneratorInputs,
517
+ webhookUrl?: string,
518
+ endpointSlug = "initial-step-content-generator"
519
+ ) => {
520
+ try {
521
+ const response = await axios.post(
522
+ `${RIGOBOT_HOST}/v1/prompting/completion/${endpointSlug}/`,
523
+ {
524
+ inputs,
525
+ include_purpose_objective: false,
526
+ execute_async: !!webhookUrl,
527
+ webhook_url: webhookUrl,
528
+ },
529
+ {
530
+ headers: {
531
+ "Content-Type": "application/json",
532
+ Authorization: "Token " + token.trim(),
533
+ },
534
+ }
535
+ )
536
+ return response.data
537
+ } catch (error) {
538
+ console.error("Error in initialContentGenerator:", error)
539
+ return null
540
+ }
541
+ }
542
+
543
+ type TAddInteractivityInputs = {
544
+ components: string;
545
+ prev_lesson: string;
546
+ initial_lesson: string;
547
+ output_language: string;
548
+ current_syllabus: string;
549
+ };
550
+
551
+ export const addInteractivity = async (
552
+ token: string,
553
+ inputs: TAddInteractivityInputs,
554
+ webhookUrl?: string
555
+ ) => {
556
+ try {
557
+ const response = await axios.post(
558
+ `${RIGOBOT_HOST}/v1/prompting/completion/lesson-refiner/`,
559
+ {
560
+ inputs,
561
+ include_purpose_objective: false,
562
+ execute_async: !!webhookUrl,
563
+ webhook_url: webhookUrl,
564
+ },
565
+ {
566
+ headers: {
567
+ "Content-Type": "application/json",
568
+ Authorization: "Token " + token.trim(),
569
+ },
570
+ }
571
+ )
572
+ return response.data
573
+ } catch (error) {
574
+ console.error("Error in addInteractivity:", error)
575
+ return null
576
+ }
577
+ }
578
+
579
+ type TGenerateCodeChallengeInputs = {
580
+ lesson_content: string;
581
+ challenge_proposal: string;
582
+ };
583
+
584
+ export const generateCodeChallenge = async (
585
+ token: string,
586
+ inputs: TGenerateCodeChallengeInputs,
587
+ webhookUrl?: string
588
+ ) => {
589
+ try {
590
+ const response = await axios.post(
591
+ `${RIGOBOT_HOST}/v1/prompting/completion/create-structured-coding-filles/`,
592
+ {
593
+ inputs,
594
+ include_purpose_objective: false,
595
+ execute_async: !!webhookUrl,
596
+ webhook_url: webhookUrl,
597
+ },
598
+ {
599
+ headers: {
600
+ "Content-Type": "application/json",
601
+ Authorization: "Token " + token.trim(),
602
+ },
603
+ }
604
+ )
605
+ return response.data
606
+ } catch (error) {
607
+ console.error("Error in generateCodeChallenge:", error)
608
+ return null
609
+ }
610
+ }
611
+
612
+ type TCreateStepInputs = {
613
+ description: string;
614
+ stepIndex: number;
615
+ courseInfo: string;
616
+ lang: string;
617
+ };
618
+
619
+ export const generateStepSlug = async (
620
+ token: string,
621
+ inputs: TCreateStepInputs
622
+ ) => {
623
+ try {
624
+ const response = await axios.post(
625
+ `${RIGOBOT_HOST}/v1/prompting/completion/step-slug-generator/`,
626
+ { inputs, include_purpose_objective: false, execute_async: false },
627
+ {
628
+ headers: {
629
+ "Content-Type": "application/json",
630
+ Authorization: "Token " + token.trim(),
631
+ },
632
+ }
633
+ )
634
+ return response.data
635
+ } catch (error) {
636
+ console.error("Error in createStep:", error)
637
+ return null
638
+ }
639
+ }