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}