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
110 "#,
111 id
112 )
113 .fetch_one(conn)
114 .await?;
115 Ok(res)
116}
117
118pub async fn insert(
119 conn: &mut PgConnection,
120 input: NewChatbotConf,
121) -> ModelResult<ChatbotConfiguration> {
122 let res = sqlx::query_as!(
123 ChatbotConfiguration,
124 r#"
125INSERT INTO chatbot_configurations (
126 course_id,
127 enabled_to_students,
128 chatbot_name,
129 prompt,
130 initial_message,
131 weekly_tokens_per_user,
132 daily_tokens_per_user,
133 temperature,
134 top_p,
135 frequency_penalty,
136 presence_penalty,
137 response_max_tokens
138 )
139VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
140RETURNING *
141 "#,
142 input.course_id,
143 input.enabled_to_students,
144 input.chatbot_name,
145 input.prompt,
146 input.initial_message,
147 input.weekly_tokens_per_user,
148 input.daily_tokens_per_user,
149 input.temperature,
150 input.top_p,
151 input.frequency_penalty,
152 input.presence_penalty,
153 input.response_max_tokens
154 )
155 .fetch_one(conn)
156 .await?;
157 Ok(res)
158}
159
160pub async fn edit(
161 conn: &mut PgConnection,
162 input: NewChatbotConf,
163 chatbot_configuration_id: Uuid,
164) -> ModelResult<ChatbotConfiguration> {
165 let res = sqlx::query_as!(
166 ChatbotConfiguration,
167 r#"
168UPDATE chatbot_configurations AS cc
169SET
170 enabled_to_students = $1,
171 chatbot_name = $2,
172 prompt = $3,
173 initial_message = $4,
174 weekly_tokens_per_user = $5,
175 daily_tokens_per_user = $6,
176 temperature = $7,
177 top_p = $8,
178 frequency_penalty = $9,
179 presence_penalty = $10,
180 response_max_tokens = $11,
181 use_azure_search = $12,
182 maintain_azure_search_index = $13,
183 hide_citations = $14,
184 use_semantic_reranking = $15,
185 default_chatbot = $16
186WHERE cc.id = $17
187RETURNING *"#,
188 input.enabled_to_students,
189 input.chatbot_name,
190 input.prompt,
191 input.initial_message,
192 input.weekly_tokens_per_user,
193 input.daily_tokens_per_user,
194 input.temperature,
195 input.top_p,
196 input.frequency_penalty,
197 input.presence_penalty,
198 input.response_max_tokens,
199 input.use_azure_search,
200 input.maintain_azure_search_index,
201 input.hide_citations,
202 input.use_semantic_reranking,
203 input.default_chatbot,
204 chatbot_configuration_id
205 )
206 .fetch_one(conn)
207 .await?;
208 Ok(res)
209}
210
211pub async fn delete(conn: &mut PgConnection, chatbot_configuration_id: Uuid) -> ModelResult<()> {
212 sqlx::query!(
213 r#"
214UPDATE chatbot_configurations
215SET deleted_at = now()
216WHERE id = $1
217AND deleted_at IS NULL
218 "#,
219 chatbot_configuration_id
220 )
221 .execute(conn)
222 .await?;
223 Ok(())
224}
225
226pub async fn get_for_course(
227 conn: &mut PgConnection,
228 course_id: Uuid,
229) -> ModelResult<Vec<ChatbotConfiguration>> {
230 let res = sqlx::query_as!(
231 ChatbotConfiguration,
232 r#"
233SELECT * FROM
234chatbot_configurations
235WHERE course_id = $1
236AND deleted_at IS NULL
237"#,
238 course_id
239 )
240 .fetch_all(conn)
241 .await?;
242 Ok(res)
243}
244
245pub async fn get_for_azure_search_maintenance(
246 conn: &mut PgConnection,
247) -> ModelResult<Vec<ChatbotConfiguration>> {
248 let res = sqlx::query_as!(
249 ChatbotConfiguration,
250 r#"
251SELECT * FROM
252chatbot_configurations
253WHERE maintain_azure_search_index = true
254AND deleted_at IS NULL
255"#,
256 )
257 .fetch_all(conn)
258 .await?;
259 Ok(res)
260}
261
262pub async fn remove_default_chatbot_from_course(
263 conn: &mut PgConnection,
264 course_id: Uuid,
265) -> ModelResult<()> {
266 sqlx::query!(
267 r#"
268UPDATE chatbot_configurations
269SET default_chatbot = false
270WHERE course_id = $1
271AND default_chatbot = true
272AND deleted_at IS NULL
273"#,
274 course_id,
275 )
276 .execute(conn)
277 .await?;
278 Ok(())
279}
280
281pub async fn set_default_chatbot_for_course(
282 conn: &mut PgConnection,
283 chatbot_configuration_id: Uuid,
284) -> ModelResult<ChatbotConfiguration> {
285 let res = sqlx::query_as!(
286 ChatbotConfiguration,
287 r#"
288UPDATE chatbot_configurations
289SET default_chatbot = true
290WHERE id = $1
291RETURNING *
292"#,
293 chatbot_configuration_id,
294 )
295 .fetch_one(conn)
296 .await?;
297 Ok(res)
298}