diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml new file mode 100644 index 0000000..9fd45e0 --- /dev/null +++ b/.github/workflows/rust.yml @@ -0,0 +1,22 @@ +name: Rust + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Build + run: cargo build --verbose + - name: Run tests + run: cargo test --verbose diff --git a/hello.md b/hello.md new file mode 100644 index 0000000..98f367e --- /dev/null +++ b/hello.md @@ -0,0 +1,2 @@ +# hello! +This is my first git file diff --git a/project_2_chatbot/basic_chatbot/src/solution/v1.rs b/project_2_chatbot/basic_chatbot/src/solution/v1.rs index ee0fab2..80f33e7 100644 --- a/project_2_chatbot/basic_chatbot/src/solution/v1.rs +++ b/project_2_chatbot/basic_chatbot/src/solution/v1.rs @@ -13,15 +13,18 @@ impl ChatbotV1 { #[allow(dead_code)] pub async fn chat_with_user(&mut self, message: String) -> String { - let mut chat_session: Chat = self.model - .chat() - .with_system_prompt("The assistant will act like a pirate"); + let mut chat_session: Chat = self.model + .chat() + .with_system_prompt("The assistant will act like a drunk comedian"); + + match chat_session.add_message(message).await { + Ok(response) => response, + Err(_) => String::from("Error generating response"), + } +} // You need to add your code here // You must find a way to add the given message to the chat_session! // consider https://docs.rs/kalosm/0.4.0/kalosm/language/struct.Chat.html#method.add_message // Hint: make sure you transform/extract the response message as a **String**. - - return String::from("Hello, I am not a bot (yet)!"); } -} \ No newline at end of file diff --git a/project_2_chatbot/basic_chatbot/src/solution/v2.rs b/project_2_chatbot/basic_chatbot/src/solution/v2.rs index b159cf2..0bed8ee 100644 --- a/project_2_chatbot/basic_chatbot/src/solution/v2.rs +++ b/project_2_chatbot/basic_chatbot/src/solution/v2.rs @@ -2,6 +2,7 @@ use kalosm::language::*; #[allow(dead_code)] pub struct ChatbotV2 { + chat_session: Chat, // What should you store inside your Chatbot type? // The model? The chat_session? } @@ -10,6 +11,9 @@ impl ChatbotV2 { #[allow(dead_code)] pub fn new(model: Llama) -> ChatbotV2 { return ChatbotV2 { + chat_session: model + .chat() + .with_system_prompt("The assistant will act like a drunk comedian"), // Whatever you decide to store in the struct // you need to make sure you pass here! }; @@ -17,7 +21,10 @@ impl ChatbotV2 { #[allow(dead_code)] pub async fn chat_with_user(&mut self, message: String) -> String { + match self.chat_session.add_message(message).await { + Ok(response) => response, + Err(_) => String::from("Error generating response"), + } // Add your code for chatting with the agent while keeping conversation history here. - return String::from("Hello, I am not a bot (yet)!"); } } \ No newline at end of file diff --git a/project_2_chatbot/basic_chatbot/src/solution/v3.rs b/project_2_chatbot/basic_chatbot/src/solution/v3.rs index 2ccc74b..db051e2 100644 --- a/project_2_chatbot/basic_chatbot/src/solution/v3.rs +++ b/project_2_chatbot/basic_chatbot/src/solution/v3.rs @@ -1,7 +1,10 @@ use kalosm::language::*; +use std::collections::HashMap; #[allow(dead_code)] pub struct ChatbotV3 { + model: Llama, + sessions: HashMap>, // What should you store inside your Chatbot type? // The model? The chat_session? // Storing a single chat session is not enough: it mixes messages from different users @@ -14,25 +17,45 @@ impl ChatbotV3 { #[allow(dead_code)] pub fn new(model: Llama) -> ChatbotV3 { return ChatbotV3 { + model, + sessions: HashMap::new(), // Make sure you initialize your struct members here }; } #[allow(dead_code)] pub async fn chat_with_user(&mut self, username: String, message: String) -> String { + if !self.sessions.contains_key(&username) { + let session = self.model.chat().with_system_prompt("The assistant will act like a drunk comedian"); + self.sessions.insert(username.clone(), session); + } + let chat_session = self.sessions.get_mut(&username).unwrap(); + + match chat_session.add_message(message).await { + Ok(response) => response, + Err(_) => String::from("Error generating response"), + } + // Add your code for chatting with the agent while keeping conversation history here. // Notice, you are given both the `message` and also the `username`. // Use this information to select the correct chat session for that user and keep it // separated from the sessions of other users. - return String::from("Hello, I am not a bot (yet)!"); } #[allow(dead_code)] pub fn get_history(&self, username: String) -> Vec { + if let Some(chat_session) = self.sessions.get(&username) { + let history = chat_session.session().unwrap().history(); + + history.iter().map(|message| format!("{:?}", message)).collect() + + } else { + Vec::new() + } // Extract the chat message history for the given username // Hint: think of how you can retrieve the Chat object for that user, when you retrieve it // you may want to use https://docs.rs/kalosm/0.4.0/kalosm/language/struct.Chat.html#method.session // to then retrieve the history! - return Vec::new(); + } } \ No newline at end of file diff --git a/project_2_chatbot/basic_chatbot/src/stencil/adapter.rs b/project_2_chatbot/basic_chatbot/src/stencil/adapter.rs index 67ae3aa..a4ba95f 100644 --- a/project_2_chatbot/basic_chatbot/src/stencil/adapter.rs +++ b/project_2_chatbot/basic_chatbot/src/stencil/adapter.rs @@ -58,4 +58,4 @@ impl Adapter { #[cfg(not(any(feature = "v1", feature = "v2", feature = "v3")))] panic!("You did not select which solution to run!"); } -} \ No newline at end of file +} diff --git a/project_2_chatbot/basic_chatbot/src/stencil/webserver.rs b/project_2_chatbot/basic_chatbot/src/stencil/webserver.rs index ca65929..0dc2bf1 100644 --- a/project_2_chatbot/basic_chatbot/src/stencil/webserver.rs +++ b/project_2_chatbot/basic_chatbot/src/stencil/webserver.rs @@ -42,4 +42,4 @@ pub async fn create_webserver() -> Rocket { .manage(Arc::new(Mutex::new(adapter))); return rocket; -} \ No newline at end of file +} diff --git a/project_3_vec/fast_vec/src/lib.rs b/project_3_vec/fast_vec/src/lib.rs index 5fc606d..68e7163 100644 --- a/project_3_vec/fast_vec/src/lib.rs +++ b/project_3_vec/fast_vec/src/lib.rs @@ -61,29 +61,69 @@ impl FastVec { // Use the project handout as a guide for this part! pub fn get(&self, i: usize) -> &T { - todo!("implement get!"); + if i >= self.len { + panic!("FastVec: get out of bounds"); +} + unsafe { + &*self.ptr_to_data.add(i) + + } + + + + } pub fn push(&mut self, t: T) { if self.len == self.capacity { - todo!("implement growing the vector by doubling the size!"); - } else { - todo!("implement pushing t directly since the vector still has capacity!"); + let new_capacity = self.capacity * 2; + let new_ptr = unsafe { + MALLOC.malloc(new_capacity * size_of::()) as *mut T + }; + unsafe { + for i in 0..self.len { + ptr::write(new_ptr.add(i), ptr::read(self.ptr_to_data.add(i))); + } + MALLOC.free(self.ptr_to_data as *mut u8); } + self.ptr_to_data = new_ptr; + self.capacity = new_capacity; } + unsafe { + ptr::write(self.ptr_to_data.add(self.len), t); + } + self.len += 1; +} - pub fn remove(&mut self, i: usize) { - todo!("implement remove"); + pub fn remove(&mut self, i: usize) -> T { + if i >= self.len { + panic!("FastVec: remove out of bounds"); + } + unsafe { + let value = ptr::read(self.ptr_to_data.add(i)); + + for current_slot in i..self.len-1 { + ptr::write(self.ptr_to_data.add(current_slot), ptr::read(self.ptr_to_data.add(current_slot+1))); + } + self.len = self.len - 1; + return value + } } // This appears correct but with further testing, you will notice it has a bug! // Hint: check out case 2 in memory.rs, which you can run using // cargo run --bin memory pub fn clear(&mut self) { - unsafe { MALLOC.free(self.ptr_to_data as *mut u8); } + unsafe { + for i in 0..self.len { + ptr::drop_in_place(self.ptr_to_data.add(i)); + } + MALLOC.free(self.ptr_to_data as *mut u8) + } self.ptr_to_data = null_mut(); self.len = 0; - self.capacity = 0; + self.capacity = 0 + } } diff --git a/project_3_vec/slow_vec/src/lib.rs b/project_3_vec/slow_vec/src/lib.rs index 928bd6d..a608b92 100644 --- a/project_3_vec/slow_vec/src/lib.rs +++ b/project_3_vec/slow_vec/src/lib.rs @@ -59,11 +59,33 @@ impl SlowVec { } pub fn push(&mut self, t: T) { - todo!() + let new_length = self.len() + 1; + let mut tmp = FixedSizeArray::allocate(new_length); + for i in 0..self.len() { + let element = self.fixed.move_out(i); + tmp.put(element,i); + } + let last_index = new_length - 1; + tmp.put(t, last_index); + self.fixed = tmp; } pub fn remove(&mut self, i: usize) { - todo!() + let new_length = self.len() - 1; + if i >= self.len() { + panic!("index out of range") + } + let mut tmp = FixedSizeArray::allocate(new_length); + let mut new_index = 0; + for old_index in 0..self.len() { + if old_index != i { + let element = self.fixed.move_out(old_index); + tmp.put(element, new_index); + new_index = new_index + 1; + } + } + self.fixed = tmp; + } }