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, Debug)]
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    pub chatbotconf_id: Option<Uuid>,
78}
79
80impl Default for NewChatbotConf {
81    fn default() -> Self {
82        let chatbot_conf: ChatbotConfiguration = ChatbotConfiguration::default();
83        Self {
84            course_id: chatbot_conf.course_id,
85            enabled_to_students: chatbot_conf.enabled_to_students,
86            chatbot_name: chatbot_conf.chatbot_name,
87            prompt: chatbot_conf.prompt,
88            initial_message: chatbot_conf.initial_message,
89            weekly_tokens_per_user: chatbot_conf.weekly_tokens_per_user,
90            daily_tokens_per_user: chatbot_conf.daily_tokens_per_user,
91            temperature: chatbot_conf.temperature,
92            top_p: chatbot_conf.top_p,
93            frequency_penalty: chatbot_conf.frequency_penalty,
94            presence_penalty: chatbot_conf.presence_penalty,
95            response_max_tokens: chatbot_conf.response_max_tokens,
96            use_azure_search: chatbot_conf.use_azure_search,
97            maintain_azure_search_index: chatbot_conf.maintain_azure_search_index,
98            hide_citations: chatbot_conf.hide_citations,
99            use_semantic_reranking: chatbot_conf.use_semantic_reranking,
100            default_chatbot: chatbot_conf.default_chatbot,
101            chatbotconf_id: None,
102        }
103    }
104}
105
106pub async fn get_by_id(conn: &mut PgConnection, id: Uuid) -> ModelResult<ChatbotConfiguration> {
107    let res = sqlx::query_as!(
108        ChatbotConfiguration,
109        r#"
110SELECT * FROM chatbot_configurations
111WHERE id = $1
112AND deleted_at IS NULL
113        "#,
114        id
115    )
116    .fetch_one(conn)
117    .await?;
118    Ok(res)
119}
120
121pub async fn insert(
122    conn: &mut PgConnection,
123    pkey_policy: PKeyPolicy<Uuid>,
124    input: NewChatbotConf,
125) -> ModelResult<ChatbotConfiguration> {
126    let res = sqlx::query_as!(
127        ChatbotConfiguration,
128        r#"
129INSERT INTO chatbot_configurations (
130    id,
131    course_id,
132    enabled_to_students,
133    chatbot_name,
134    prompt,
135    initial_message,
136    weekly_tokens_per_user,
137    daily_tokens_per_user,
138    temperature,
139    top_p,
140    hide_citations,
141    frequency_penalty,
142    presence_penalty,
143    response_max_tokens,
144    use_azure_search,
145    maintain_azure_search_index,
146    default_chatbot
147  )
148VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $15, $16)
149RETURNING *
150        "#,
151        pkey_policy.into_uuid(),
152        input.course_id,
153        input.enabled_to_students,
154        input.chatbot_name,
155        input.prompt,
156        input.initial_message,
157        input.weekly_tokens_per_user,
158        input.daily_tokens_per_user,
159        input.temperature,
160        input.top_p,
161        input.hide_citations,
162        input.frequency_penalty,
163        input.presence_penalty,
164        input.response_max_tokens,
165        input.use_azure_search,
166        input.default_chatbot
167    )
168    .fetch_one(conn)
169    .await?;
170    Ok(res)
171}
172
173pub async fn edit(
174    conn: &mut PgConnection,
175    input: NewChatbotConf,
176    chatbot_configuration_id: Uuid,
177) -> ModelResult<ChatbotConfiguration> {
178    let res = sqlx::query_as!(
179        ChatbotConfiguration,
180        r#"
181UPDATE chatbot_configurations AS cc
182SET
183    enabled_to_students = $1,
184    chatbot_name = $2,
185    prompt = $3,
186    initial_message = $4,
187    weekly_tokens_per_user = $5,
188    daily_tokens_per_user = $6,
189    temperature = $7,
190    top_p = $8,
191    frequency_penalty = $9,
192    presence_penalty = $10,
193    response_max_tokens = $11,
194    use_azure_search = $12,
195    maintain_azure_search_index = $13,
196    hide_citations = $14,
197    use_semantic_reranking = $15,
198    default_chatbot = $16
199WHERE cc.id = $17
200RETURNING *"#,
201        input.enabled_to_students,
202        input.chatbot_name,
203        input.prompt,
204        input.initial_message,
205        input.weekly_tokens_per_user,
206        input.daily_tokens_per_user,
207        input.temperature,
208        input.top_p,
209        input.frequency_penalty,
210        input.presence_penalty,
211        input.response_max_tokens,
212        input.use_azure_search,
213        input.maintain_azure_search_index,
214        input.hide_citations,
215        input.use_semantic_reranking,
216        input.default_chatbot,
217        chatbot_configuration_id
218    )
219    .fetch_one(conn)
220    .await?;
221    Ok(res)
222}
223
224pub async fn delete(conn: &mut PgConnection, chatbot_configuration_id: Uuid) -> ModelResult<()> {
225    sqlx::query!(
226        r#"
227UPDATE chatbot_configurations
228SET deleted_at = now()
229WHERE id = $1
230AND deleted_at IS NULL
231        "#,
232        chatbot_configuration_id
233    )
234    .execute(conn)
235    .await?;
236    Ok(())
237}
238
239pub async fn get_for_course(
240    conn: &mut PgConnection,
241    course_id: Uuid,
242) -> ModelResult<Vec<ChatbotConfiguration>> {
243    let res = sqlx::query_as!(
244        ChatbotConfiguration,
245        r#"
246SELECT * FROM
247chatbot_configurations
248WHERE course_id = $1
249AND deleted_at IS NULL
250"#,
251        course_id
252    )
253    .fetch_all(conn)
254    .await?;
255    Ok(res)
256}
257
258pub async fn get_enabled_nondefault_for_course(
259    conn: &mut PgConnection,
260    course_id: Uuid,
261) -> ModelResult<Vec<ChatbotConfiguration>> {
262    let res = sqlx::query_as!(
263        ChatbotConfiguration,
264        r#"
265SELECT * FROM
266chatbot_configurations
267WHERE course_id = $1
268AND default_chatbot IS false
269AND enabled_to_students IS true
270AND deleted_at IS NULL
271"#,
272        course_id
273    )
274    .fetch_all(conn)
275    .await?;
276    Ok(res)
277}
278
279pub async fn get_for_azure_search_maintenance(
280    conn: &mut PgConnection,
281) -> ModelResult<Vec<ChatbotConfiguration>> {
282    let res = sqlx::query_as!(
283        ChatbotConfiguration,
284        r#"
285SELECT * FROM
286chatbot_configurations
287WHERE maintain_azure_search_index = true
288AND deleted_at IS NULL
289"#,
290    )
291    .fetch_all(conn)
292    .await?;
293    Ok(res)
294}
295
296pub async fn remove_default_chatbot_from_course(
297    conn: &mut PgConnection,
298    course_id: Uuid,
299) -> ModelResult<()> {
300    sqlx::query!(
301        r#"
302UPDATE chatbot_configurations
303SET default_chatbot = false
304WHERE course_id = $1
305AND default_chatbot = true
306AND deleted_at IS NULL
307"#,
308        course_id,
309    )
310    .execute(conn)
311    .await?;
312    Ok(())
313}
314
315pub async fn set_default_chatbot_for_course(
316    conn: &mut PgConnection,
317    chatbot_configuration_id: Uuid,
318) -> ModelResult<ChatbotConfiguration> {
319    let res = sqlx::query_as!(
320        ChatbotConfiguration,
321        r#"
322UPDATE chatbot_configurations
323SET default_chatbot = true
324WHERE id = $1
325RETURNING *
326"#,
327        chatbot_configuration_id,
328    )
329    .fetch_one(conn)
330    .await?;
331    Ok(res)
332}