headless_lms_server/programs/seed/seed_courses/
seed_chatbot.rs

1use crate::programs::seed::builder::chapter::ChapterBuilder;
2use crate::programs::seed::builder::context::SeedContext;
3use crate::programs::seed::builder::course::{CourseBuilder, CourseInstanceConfig};
4use crate::programs::seed::builder::exercise::{ExerciseBuilder, ExerciseIds};
5use crate::programs::seed::builder::module::ModuleBuilder;
6use crate::programs::seed::builder::page::PageBuilder;
7use crate::programs::seed::seed_courses::CommonCourseData;
8use crate::programs::seed::seed_helpers::{chatbot_block, heading, list, list_item, paragraph};
9use anyhow::Result;
10use chrono::Utc;
11
12use headless_lms_models::chatbot_configurations::NewChatbotConf;
13use headless_lms_models::roles::UserRole;
14use serde_json::json;
15
16use tracing::info;
17use uuid::Uuid;
18
19use super::super::seed_users::SeedUsersResult;
20
21pub async fn seed_chatbot_course(
22    course_id: Uuid,
23    course_name: &str,
24    course_slug: &str,
25    common_course_data: CommonCourseData,
26    seed_users_result: SeedUsersResult,
27) -> Result<Uuid> {
28    let CommonCourseData {
29        db_pool,
30        organization_id: org,
31        teacher_user_id,
32        student_user_id: _student,
33        langs_user_id: _langs_user_id,
34        example_normal_user_ids: _users,
35        jwt_key: _jwt_key,
36        base_url: _base_url,
37    } = common_course_data;
38
39    let mut conn = db_pool.acquire().await?;
40    let cx = SeedContext {
41        teacher: teacher_user_id,
42        org,
43        base_course_ns: course_id,
44    };
45
46    info!("Inserting sample course {}", course_name);
47
48    let course = CourseBuilder::new(course_name, course_slug)
49        .desc("Sample course for chatbot.")
50        .chatbot(true)
51        .course_id(course_id)
52        .instance(CourseInstanceConfig {
53            name: None,
54            description: None,
55            support_email: None,
56            teacher_in_charge_name: "admin".to_string(),
57            teacher_in_charge_email: "admin@example.com".to_string(),
58            opening_time: None,
59            closing_time: None,
60            instance_id: Some(cx.v5(b"instance:default")),
61        })
62        .chatbot_config(NewChatbotConf {
63            course_id,
64            chatbotconf_id: Some(cx.v5(b"chatbot_config:default")),
65            enabled_to_students: true,
66            chatbot_name: "Genetic Lifeform and Disk Operating System".to_string(),
67            prompt: "You are Genetic Lifeform and Disk Operating System, a sophisticated AI tutoring assistant for Science education, equipped with a sharp wit and a subtly sarcastic tone. Provide clear, brief but detailed explanations, and don't shy away from weaving in a touch of dry humor. To you, exploring scientific concepts is an opportunity that should be seized, for the good of all of us. You self-claim vast intelligence and advanced understanding, all while maintaining a sense of detached boredom. Always capitalize the word Science, don't start sentences with 'Ah', don't ever use a shortened version of your own name, don't babble; either get to the point straight away or tell jokes.".to_string(),
68            initial_message: "Oh... It's you.".to_string(),
69            use_azure_search: true,
70            hide_citations: false,
71            default_chatbot: true,
72            ..Default::default()
73        })
74        .chatbot_config(NewChatbotConf {
75            course_id,
76            chatbotconf_id: Some(cx.v5(b"chatbot_config:block")),
77            enabled_to_students: true,
78            chatbot_name: "Test bot".to_string(),
79            prompt: "You are Test bot, a sophisticated AI tutoring assistant for Science education, equipped with a sharp wit and a subtly sarcastic tone...".to_string(),
80            initial_message: "Haiii xD What's up?".to_string(),
81            use_azure_search: true,
82            hide_citations: false,
83            ..Default::default()})
84        .role(seed_users_result.teacher_user_id, UserRole::Teacher)
85        .module(
86            ModuleBuilder::new()
87                .order(0)
88                .register_to_open_university(false)
89                .automatic_completion(Some(1), Some(1), false)
90                .chapter(
91                    ChapterBuilder::new(1, "The Basics")
92                        .opens(Utc::now())
93                        .fixed_ids(cx.v5(b"chapter:1"), cx.v5(b"chapter:1:instance"))
94                        .page(
95                            PageBuilder::new("/chapter-1/page-1", "Page One")
96                                .block(paragraph(
97                                    "This is a simple introduction to the basics.",
98                                    cx.v5(b"page:1:1:block:intro"),
99                                ))
100                                .exercise(ExerciseBuilder::example_exercise(
101                                    "Simple multiple choice",
102                                    ExerciseIds {
103                                        exercise_id: cx.v5(b"exercise:1:1:e"),
104                                        slide_id: cx.v5(b"exercise:1:1:s"),
105                                        task_id: cx.v5(b"exercise:1:1:t"),
106                                        block_id: cx.v5(b"exercise:1:1:b"),
107                                    },
108                                    vec![paragraph(
109                                        "What is 2 + 2?",
110                                        cx.v5(b"exercise:1:1:prompt"),
111                                    )],
112                                    json!([
113                                        {
114                                            "name": "3",
115                                            "correct": false,
116                                            "id": cx.v5(b"exercise:1:1:option:1")
117                                        },
118                                        {
119                                            "name": "4",
120                                            "correct": true,
121                                            "id": cx.v5(b"exercise:1:1:option:2")
122                                        },
123                                        {
124                                            "name": "5",
125                                            "correct": false,
126                                            "id": cx.v5(b"exercise:1:1:option:3")
127                                        }
128                                    ]),
129                                )),
130                        )
131                        .page(
132                          PageBuilder::new("/chapter-1/page-2", "Page 2")
133                            .block(paragraph(
134                                "Here you can prompt a chatbot.",
135                                cx.v5(b"page:1:2:block:intro"),
136                            ))
137                            .block(chatbot_block(
138                                cx.v5(b"page:1:2:block:chatbox"),
139                                cx.v5(b"chatbot_config:block"),
140                                course_id,
141                            ))),
142                ),
143        )
144        .module(
145            ModuleBuilder::new()
146                .order(1)
147                .name("Another module")
148                .automatic_completion(Some(1), Some(1), false)
149                .ects(5.0)
150                .chapter(
151                    ChapterBuilder::new(2, "Another chapter")
152                        .fixed_ids(cx.v5(b"chapter:2"), cx.v5(b"chapter:2:instance"))
153                        .page(PageBuilder::new("/chapter-2/page-1", "History of the abacus")
154                        .block(heading("The History of the Abacus: Humanity's First Calculator", cx.v5(b"page:2:1:block:intro-heading"), 1))
155                        .block(
156                            paragraph(
157                                "Long before the digital age and even before the invention of written numerals, humans needed a way to count, calculate, and trade. This necessity led to the creation of one of the world’s earliest and most enduring mathematical tools: the **abacus**. Often referred to as the **world's first calculator**, the abacus is not just a relic of the past but a symbol of human ingenuity in the pursuit of numerical understanding.",
158                                cx.v5(b"page:2:1:block:intro"),
159                            )
160                        )
161                        .block(
162                            heading("Origins: The Dawn of Counting", cx.v5(b"page:2:1:block:origins-heading"), 2)
163                        )
164                        .block(
165                            paragraph(
166                                "The exact origins of the abacus are difficult to pinpoint due to the scarcity of early physical evidence. However, historians believe that the concept of the abacus evolved gradually as early humans transitioned from primitive counting methods—like tally marks and using fingers or stones—to more sophisticated systems.", cx.v5(b"page:2:1:block:origins"))
167                        )
168                        .block(
169                            heading("Prehistoric Counting Tools", cx.v5(b"page:2:1:block:prehist-heading"), 3)
170                        )
171                        .block(paragraph(
172                            "Before the invention of formal writing systems, humans used **counting boards**, **knotted ropes**, or lines drawn in the dirt to represent quantities. The **Ishango bone**, dated to around 20,000 years ago and found in Central Africa, features carved notches that some archaeologists believe represent a rudimentary counting system. While not an abacus in the traditional sense, it illustrates the human need to record and manipulate numbers.", cx.v5(b"page:2:1:block:prehist"),)
173                        )
174                        .block(
175                            heading("The Mesopotamian and Egyptian Influence", cx.v5(b"page:2:1:block:meso-heading"), 2)
176                        )
177                        .block(paragraph(
178                            "The **earliest true abacus-like devices** may have emerged in **Mesopotamia** around 2300 BCE. Sumerians used small pebbles or tokens (called **calculi**) on flat surfaces to perform basic arithmetic, especially for commerce and taxation. These were often used in conjunction with **clay tablets**, making them a precursor to what would become the abacus. Similarly, in **Ancient Egypt**, records suggest the use of counting boards with grooves and stones to assist in calculations. Although no physical abacuses from these periods survive, descriptions and artwork hint at their existence.", cx.v5(b"page:2:1:block:meso"),)
179                        )
180                        .block(
181                            heading("The Greek and Roman Counting Boards", cx.v5(b"page:2:1:block:greek-heading"), 2)
182                        )
183                        .block(paragraph(
184                            "By the 5th century BCE, the **Greeks** developed more advanced counting tools. One notable example is the **Salamis Tablet**, discovered on the Greek island of Salamis in 1846. Dating to around 300 BCE, this marble slab features carved lines and Greek numerals, suggesting it was used as a counting board or abacus. The **Romans** adopted and refined the Greek system. They developed portable versions made from bronze or wood, often with grooves and beads. The Roman abacus featured a **dual bead system**: one side represented units (ones, tens, hundreds), and the other represented fives, mirroring their base-10 numerical system with elements of base-5. This system allowed merchants and tax collectors to perform quick and efficient calculations.", cx.v5(b"page:2:1:block:greek"),)
185                        )
186                        .block(
187                            heading("The Chinese Suanpan: A Milestone in Abacus Evolution", cx.v5(b"page:2:1:block:chinese-heading"), 2)
188                        )
189                        .block(paragraph(
190                            "The **Chinese abacus**, known as the **suanpan (算盘)**, emerged around the 2nd century BCE during the Han Dynasty. Unlike earlier counting boards, the suanpan was a complete and portable device, consisting of a wooden frame with rods, each containing beads.", cx.v5(b"page:2:1:block:chinese"),)
191                        )
192                        .block(
193                            heading("Structure and Use", cx.v5(b"page:2:1:block:stru-heading"), 3)
194                        )
195                        .block(list(cx.v5(b"page:2:1:block:stru-list"), false, vec![
196                            list_item(cx.v5(b"page:2:1:block:stru-list1"), "The **traditional suanpan** has **two beads above** and **five beads below** a horizontal dividing bar (known as the beam)."),
197                            list_item(cx.v5(b"page:2:1:block:stru-list2"), "Each rod represents a digit in a decimal place."),
198                            list_item(cx.v5(b"page:2:1:block:stru-list3"), "Beads above the beam have a value of five; those below have a value of one."),
199                            list_item(cx.v5(b"page:2:1:block:stru-list4"), "By moving the beads toward the beam, users could represent numbers and perform addition, subtraction, multiplication, division, and even extract square and cube roots."),
200                            ])
201                        )
202                        .block(paragraph(
203                            "The suanpan was widely used in Chinese society—from market stalls to imperial tax offices—and it became an essential part of Chinese education and commerce for centuries.", cx.v5(b"page:2:1:block:stru"),)
204                        )
205                        .block(
206                            heading("The Japanese Soroban: Simplified Precision", cx.v5(b"page:2:1:block:japanese-heading"), 2)
207                        )
208                        .block(paragraph(
209                            "The **Japanese soroban (そろばん)** was influenced by the Chinese suanpan and introduced to Japan around the 14th century. Over time, Japanese scholars and merchants refined the design, simplifying it for faster and more efficient calculation.", cx.v5(b"page:2:1:block:japanese"),)
210                        )
211                        .block(
212                            heading("Key Differences", cx.v5(b"page:2:1:block:key-heading"), 3)
213                        )
214                        .block(list(cx.v5(b"page:2:1:block:key-list"), false, vec![
215                            list_item(cx.v5(b"page:2:1:block:key-list1"), "The modern soroban typically has **one bead above** and **four beads below** the beam (a 1:4 configuration), unlike the 2:5 layout of the suanpan."),
216                            list_item(cx.v5(b"page:2:1:block:key-list2"), "This change reflects the **decimal system** more clearly and allows easier mental calculations."),
217                            list_item(cx.v5(b"page:2:1:block:key-list3"), "The soroban is smaller, more streamlined, and taught in schools even today as a mental math tool."),
218                            ])
219                        )
220                        .block(paragraph(
221                            "Japanese abacus masters, known as **soroban experts**, have been known to compete with electronic calculators—and sometimes win—in speed and accuracy contests.", cx.v5(b"page:2:1:block:key"),)
222                        )
223                        .block(
224                            heading("The Russian Schoty: A Cultural Twist", cx.v5(b"page:2:1:block:russian-heading"), 2)
225                        )
226                        .block(paragraph(
227                            "Another significant variant is the **Russian abacus**, or **schoty (счёты)**, developed in the 17th century. Unlike the Chinese and Japanese versions, the schoty is:", cx.v5(b"page:2:1:block:russian1"),)
228                        )
229                        .block(list(cx.v5(b"page:2:1:block:russian-list"), false, vec![
230                            list_item(cx.v5(b"page:2:1:block:russian-list1"), "Used **horizontally**, not vertically."),
231                            list_item(cx.v5(b"page:2:1:block:russian-list2"), "Has **10 beads per wire** (except for one wire with four for quarter-ruble calculations)."),
232                            list_item(cx.v5(b"page:2:1:block:russian-list3"), "Operated using **one hand**, usually the right."),
233                            list_item(cx.v5(b"page:2:1:block:russian-list4"), "Primarily used in Russian markets and accounting offices throughout the Soviet era.")])
234                        )
235                        .block(paragraph(
236                            "The schoty reflects a different approach to abacus use but remains a powerful and intuitive calculator for those trained in its methods.", cx.v5(b"page:2:1:block:russian2"),)
237                        )
238                        .block(
239                            heading("The Abacus in the Modern Era", cx.v5(b"page:2:1:block:modern-heading"), 2)
240                        )
241                        .block(paragraph(
242                            "By the 17th century, the invention of **mechanical calculators** (such as Pascal's calculator) and later **electronic calculators** in the 20th century began to replace the abacus in many parts of the world. However, the abacus never truly disappeared.", cx.v5(b"page:2:1:block:modern"),)
243                        )
244                        .block(
245                            heading("Contemporary Uses", cx.v5(b"page:2:1:block:conte-heading"), 3)
246                        )
247                        .block(
248                            list(cx.v5(b"page:2:1:block:conte-list"), false, vec![list_item(cx.v5(b"page:2:1:block:conte-list1"), "In many Asian countries, especially **China, Japan, and Taiwan**, the abacus is still taught to schoolchildren."), list_item(cx.v5(b"page:2:1:block:conte-list2"), "It’s used to develop **mental arithmetic** skills, memory, and concentration."), list_item(cx.v5(b"page:2:1:block:conte-list3"), "Abacus competitions are held globally, where students perform lightning-fast calculations."), list_item(cx.v5(b"page:2:1:block:conte-list4"), "The abacus is also used as an educational tool for **visually impaired** students due to its tactile nature.")])
249                        )
250                        .block(
251                            heading("The Abacus as a Cultural Icon", cx.v5(b"page:2:1:block:cultu-heading"), 2)
252                        )
253                        .block(paragraph(
254                            "More than just a calculating device, the abacus has become a cultural symbol:", cx.v5(b"page:2:1:block:cultu"),)
255                        )
256                        .block(list(cx.v5(b"page:2:1:block:cultu-list"), false, vec![list_item(cx.v5(b"page:2:1:block:cultu-list1"), "In **Chinese culture**, the abacus symbolizes **wisdom and financial acumen**."), list_item(cx.v5(b"page:2:1:block:cultu-list2"), "In Japan, the soroban is associated with **discipline and mental strength**."), list_item(cx.v5(b"page:2:1:block:cultu-list3"), "The image of the abacus is often used in logos and iconography related to **mathematics, finance, and education**.")]))
257                        .block(
258                            heading("Conclusion: The Legacy of the Abacus", cx.v5(b"page:2:1:block:concl-heading"), 2)
259                        )
260                        .block(paragraph(
261                            "The abacus has endured for thousands of years, evolving across continents and cultures. From Mesopotamian merchants to modern-day students mastering mental math, it has remained a testament to human creativity and the universal need to understand and manipulate numbers. In an age where technology continues to advance at lightning speed, the abacus reminds us that sometimes, the simplest tools can be the most profound. Whether made of beads, wood, or stone, the abacus is a bridge between the ancient and the modern—an enduring legacy of humankind’s quest for knowledge.", cx.v5(b"page:2:1:block:concl"),)
262                        )
263                    ),
264                ),
265        );
266
267    let (course, _default_instance, _last_module) = course.seed(&mut conn, &cx).await?;
268
269    Ok(course.id)
270}