headless_lms_models/
chatbot_configurations.rs

1use crate::prelude::*;
2
3#[derive(Clone, PartialEq, Deserialize, Serialize)]
4#[cfg_attr(feature = "ts_rs", derive(TS))]
5pub struct ChatbotConfiguration {
6    pub id: Uuid,
7    pub created_at: DateTime<Utc>,
8    pub updated_at: DateTime<Utc>,
9    pub deleted_at: Option<DateTime<Utc>>,
10    pub course_id: Uuid,
11    pub enabled_to_students: bool,
12    pub chatbot_name: String,
13    pub prompt: String,
14    pub initial_message: String,
15    pub weekly_tokens_per_user: i32,
16    pub daily_tokens_per_user: i32,
17    pub temperature: f32,
18    pub top_p: f32,
19    pub frequency_penalty: f32,
20    pub presence_penalty: f32,
21    pub response_max_tokens: i32,
22    pub use_azure_search: bool,
23    pub maintain_azure_search_index: bool,
24    pub hide_citations: bool,
25    pub use_semantic_reranking: bool,
26    pub default_chatbot: bool,
27}
28
29impl Default for ChatbotConfiguration {
30    fn default() -> Self {
31        Self {
32            id: Uuid::nil(),
33            created_at: Default::default(),
34            updated_at: Default::default(),
35            deleted_at: None,
36            course_id: Default::default(),
37            enabled_to_students: false,
38            chatbot_name: Default::default(),
39            prompt: Default::default(),
40            initial_message: Default::default(),
41            weekly_tokens_per_user: 20000 * 5,
42            daily_tokens_per_user: 20000,
43            temperature: 0.7,
44            top_p: 1.0,
45            frequency_penalty: Default::default(),
46            presence_penalty: Default::default(),
47            response_max_tokens: 500,
48            use_azure_search: false,
49            maintain_azure_search_index: false,
50            hide_citations: false,
51            use_semantic_reranking: false,
52            default_chatbot: false,
53        }
54    }
55}
56
57#[derive(Clone, PartialEq, Deserialize, Serialize)]
58#[cfg_attr(feature = "ts_rs", derive(TS))]
59pub struct NewChatbotConf {
60    pub course_id: Uuid,
61    pub enabled_to_students: bool,
62    pub chatbot_name: String,
63    pub prompt: String,
64    pub initial_message: String,
65    pub weekly_tokens_per_user: i32,
66    pub daily_tokens_per_user: i32,
67    pub temperature: f32,
68    pub top_p: f32,
69    pub frequency_penalty: f32,
70    pub presence_penalty: f32,
71    pub response_max_tokens: i32,
72    pub use_azure_search: bool,
73    pub maintain_azure_search_index: bool,
74    pub hide_citations: bool,
75    pub use_semantic_reranking: bool,
76    pub default_chatbot: bool,
77}
78
79impl Default for NewChatbotConf {
80    fn default() -> Self {
81        let chatbot_conf: ChatbotConfiguration = ChatbotConfiguration::default();
82        Self {
83            course_id: chatbot_conf.course_id,
84            enabled_to_students: chatbot_conf.enabled_to_students,
85            chatbot_name: chatbot_conf.chatbot_name,
86            prompt: chatbot_conf.prompt,
87            initial_message: chatbot_conf.initial_message,
88            weekly_tokens_per_user: chatbot_conf.weekly_tokens_per_user,
89            daily_tokens_per_user: chatbot_conf.daily_tokens_per_user,
90            temperature: chatbot_conf.temperature,
91            top_p: chatbot_conf.top_p,
92            frequency_penalty: chatbot_conf.frequency_penalty,
93            presence_penalty: chatbot_conf.presence_penalty,
94            response_max_tokens: chatbot_conf.response_max_tokens,
95            use_azure_search: chatbot_conf.use_azure_search,
96            maintain_azure_search_index: chatbot_conf.maintain_azure_search_index,
97            hide_citations: chatbot_conf.hide_citations,
98            use_semantic_reranking: chatbot_conf.use_semantic_reranking,
99            default_chatbot: chatbot_conf.default_chatbot,
100        }
101    }
102}
103
104pub async fn get_by_id(conn: &mut PgConnection, id: Uuid) -> ModelResult<ChatbotConfiguration> {
105    let res = sqlx::query_as!(
106        ChatbotConfiguration,
107        r#"
108SELECT * FROM chatbot_configurations
109WHERE id = $1
110AND deleted_at IS NULL
111        "#,
112        id
113    )
114    .fetch_one(conn)
115    .await?;
116    Ok(res)
117}
118
119pub async fn insert(
120    conn: &mut PgConnection,
121    input: NewChatbotConf,
122) -> ModelResult<ChatbotConfiguration> {
123    let res = sqlx::query_as!(
124        ChatbotConfiguration,
125        r#"
126INSERT INTO chatbot_configurations (
127    course_id,
128    enabled_to_students,
129    chatbot_name,
130    prompt,
131    initial_message,
132    weekly_tokens_per_user,
133    daily_tokens_per_user,
134    temperature,
135    top_p,
136    frequency_penalty,
137    presence_penalty,
138    response_max_tokens
139  )
140VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
141RETURNING *
142        "#,
143        input.course_id,
144        input.enabled_to_students,
145        input.chatbot_name,
146        input.prompt,
147        input.initial_message,
148        input.weekly_tokens_per_user,
149        input.daily_tokens_per_user,
150        input.temperature,
151        input.top_p,
152        input.frequency_penalty,
153        input.presence_penalty,
154        input.response_max_tokens
155    )
156    .fetch_one(conn)
157    .await?;
158    Ok(res)
159}
160
161pub async fn edit(
162    conn: &mut PgConnection,
163    input: NewChatbotConf,
164    chatbot_configuration_id: Uuid,
165) -> ModelResult<ChatbotConfiguration> {
166    let res = sqlx::query_as!(
167        ChatbotConfiguration,
168        r#"
169UPDATE chatbot_configurations AS cc
170SET
171    enabled_to_students = $1,
172    chatbot_name = $2,
173    prompt = $3,
174    initial_message = $4,
175    weekly_tokens_per_user = $5,
176    daily_tokens_per_user = $6,
177    temperature = $7,
178    top_p = $8,
179    frequency_penalty = $9,
180    presence_penalty = $10,
181    response_max_tokens = $11,
182    use_azure_search = $12,
183    maintain_azure_search_index = $13,
184    hide_citations = $14,
185    use_semantic_reranking = $15,
186    default_chatbot = $16
187WHERE cc.id = $17
188RETURNING *"#,
189        input.enabled_to_students,
190        input.chatbot_name,
191        input.prompt,
192        input.initial_message,
193        input.weekly_tokens_per_user,
194        input.daily_tokens_per_user,
195        input.temperature,
196        input.top_p,
197        input.frequency_penalty,
198        input.presence_penalty,
199        input.response_max_tokens,
200        input.use_azure_search,
201        input.maintain_azure_search_index,
202        input.hide_citations,
203        input.use_semantic_reranking,
204        input.default_chatbot,
205        chatbot_configuration_id
206    )
207    .fetch_one(conn)
208    .await?;
209    Ok(res)
210}
211
212pub async fn delete(conn: &mut PgConnection, chatbot_configuration_id: Uuid) -> ModelResult<()> {
213    sqlx::query!(
214        r#"
215UPDATE chatbot_configurations
216SET deleted_at = now()
217WHERE id = $1
218AND deleted_at IS NULL
219        "#,
220        chatbot_configuration_id
221    )
222    .execute(conn)
223    .await?;
224    Ok(())
225}
226
227pub async fn get_for_course(
228    conn: &mut PgConnection,
229    course_id: Uuid,
230) -> ModelResult<Vec<ChatbotConfiguration>> {
231    let res = sqlx::query_as!(
232        ChatbotConfiguration,
233        r#"
234SELECT * FROM
235chatbot_configurations
236WHERE course_id = $1
237AND deleted_at IS NULL
238"#,
239        course_id
240    )
241    .fetch_all(conn)
242    .await?;
243    Ok(res)
244}
245
246pub async fn get_enabled_nondefault_for_course(
247    conn: &mut PgConnection,
248    course_id: Uuid,
249) -> ModelResult<Vec<ChatbotConfiguration>> {
250    let res = sqlx::query_as!(
251        ChatbotConfiguration,
252        r#"
253SELECT * FROM
254chatbot_configurations
255WHERE course_id = $1
256AND default_chatbot IS false
257AND enabled_to_students IS true
258AND deleted_at IS NULL
259"#,
260        course_id
261    )
262    .fetch_all(conn)
263    .await?;
264    Ok(res)
265}
266
267pub async fn get_for_azure_search_maintenance(
268    conn: &mut PgConnection,
269) -> ModelResult<Vec<ChatbotConfiguration>> {
270    let res = sqlx::query_as!(
271        ChatbotConfiguration,
272        r#"
273SELECT * FROM
274chatbot_configurations
275WHERE maintain_azure_search_index = true
276AND deleted_at IS NULL
277"#,
278    )
279    .fetch_all(conn)
280    .await?;
281    Ok(res)
282}
283
284pub async fn remove_default_chatbot_from_course(
285    conn: &mut PgConnection,
286    course_id: Uuid,
287) -> ModelResult<()> {
288    sqlx::query!(
289        r#"
290UPDATE chatbot_configurations
291SET default_chatbot = false
292WHERE course_id = $1
293AND default_chatbot = true
294AND deleted_at IS NULL
295"#,
296        course_id,
297    )
298    .execute(conn)
299    .await?;
300    Ok(())
301}
302
303pub async fn set_default_chatbot_for_course(
304    conn: &mut PgConnection,
305    chatbot_configuration_id: Uuid,
306) -> ModelResult<ChatbotConfiguration> {
307    let res = sqlx::query_as!(
308        ChatbotConfiguration,
309        r#"
310UPDATE chatbot_configurations
311SET default_chatbot = true
312WHERE id = $1
313RETURNING *
314"#,
315        chatbot_configuration_id,
316    )
317    .fetch_one(conn)
318    .await?;
319    Ok(res)
320}