Skip to content

Commit 82cb69b

Browse files
authored
Merge pull request #11 from JadeCara/jade/chatbot
chatbot
2 parents 21d5c46 + 436aa66 commit 82cb69b

File tree

6 files changed

+147
-0
lines changed

6 files changed

+147
-0
lines changed

module2/chatbot/.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# To run locally, add an OPENAI_API_KEY variable here with a valid API key

module2/chatbot/Cargo.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "chatbot"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
reqwest = {version = "0.11.3", features = ["json"]}
8+
tokio = {version = "1.9.0", features = ["full"]}
9+
serde = {version = "1.0.118", features = ["derive"]}
10+
serde_json = "1.0.60"
11+
dotenv = "0.15.0"

module2/chatbot/Makefile

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
SHELL := /bin/bash
2+
.PHONY: help
3+
4+
help:
5+
@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'
6+
7+
clean: ## Clean the project using cargo
8+
cargo clean
9+
10+
build: ## Build the project using cargo
11+
cargo build
12+
13+
run: ## Run the project using cargo
14+
cargo run
15+
16+
test: ## Run the tests using cargo
17+
cargo test
18+
19+
lint: ## Run the linter using cargo
20+
@rustup component add clippy 2> /dev/null
21+
cargo clippy
22+
23+
format: ## Format the code using cargo
24+
@rustup component add rustfmt 2> /dev/null
25+
cargo fmt
26+
27+
release:
28+
cargo build --release
29+
30+
all: format lint test run
31+
32+
bump: ## Bump the version of the project
33+
@echo "Current version is $(shell cargo pkgid | cut -d# -f2)"
34+
@read -p "Enter the new version: " version; \
35+
updated_version=$$(cargo pkgid | cut -d# -f2 | sed "s/$(shell cargo pkgid | cut -d# -f2)/$$version/"); \
36+
sed -i -E "s/^version = .*/version = \"$$updated_version\"/" Cargo.toml
37+
@echo "Version bumped to $$(cargo pkgid | cut -d# -f2)"
38+
rm Cargo.toml-e

module2/chatbot/src/chatbot.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
use reqwest::{header, Client};
2+
use serde_json::json;
3+
use serde_json::Value;
4+
use std::io;
5+
use std::io::Write;
6+
7+
pub async fn run_chat_loop(
8+
client: &Client,
9+
api_key: &str,
10+
url: &str,
11+
) -> Result<(), reqwest::Error> {
12+
let mut conversation: String = String::from("The following is a conversation with an AI Assistant:");
13+
loop {
14+
print!("Human: ");
15+
io::stdout().flush().unwrap();
16+
17+
let user_input: String = read_user_input();
18+
19+
if user_input.to_lowercase() == "exit" || user_input.to_lowercase() == "quit" {
20+
break;
21+
}
22+
23+
conversation.push_str("Human: ");
24+
conversation.push_str(&user_input);
25+
conversation.push_str("AI: ");
26+
27+
let json: Value = json!({
28+
"model": "gpt-3.5-turbo-instruct",
29+
"prompt": conversation,
30+
"max_tokens": 150,
31+
"temperature": 0.5,
32+
"top_p": 1.0,
33+
"frequency_penalty": 0.0,
34+
"presence_penalty": 0.0,
35+
"stop": ["Human:", "AI:"]
36+
});
37+
38+
let body: Value = call_api(client, api_key, url, json).await?;
39+
print!("{}", body);
40+
let ai_response: &str = get_ai_response(&body);
41+
42+
print!("AI: {}", ai_response);
43+
44+
conversation.push_str(ai_response);
45+
conversation.push_str("\n");
46+
}
47+
Ok(())
48+
}
49+
50+
pub async fn call_api(
51+
client: &Client,
52+
api_key: &str,
53+
url: &str,
54+
json: Value,
55+
) -> Result<Value, reqwest::Error> {
56+
let response: reqwest::Response = client
57+
.post(url)
58+
.header(header::CONTENT_TYPE, "application/json")
59+
.header(header::AUTHORIZATION, format!("Bearer {}", api_key))
60+
.json(&json)
61+
.send()
62+
.await?;
63+
64+
let body: Value = response.json().await?;
65+
Ok(body)
66+
}
67+
68+
pub fn get_ai_response(body: &Value) -> &str {
69+
body["choices"][0]["text"].as_str().unwrap().trim()
70+
}
71+
72+
pub fn read_user_input() -> String {
73+
let mut user_input: String = String::new();
74+
io::stdin().read_line(&mut user_input).unwrap();
75+
user_input.trim().to_string()
76+
}

module2/chatbot/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod chatbot;

module2/chatbot/src/main.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use chatbot::chatbot::run_chat_loop;
2+
use reqwest::Client;
3+
4+
use dotenv::dotenv;
5+
use std::env;
6+
7+
#[tokio::main]
8+
async fn main() -> Result<(), reqwest::Error> {
9+
// Load the .env file
10+
dotenv().ok();
11+
let client = Client::new();
12+
13+
// use env variable OPENAI_API_KEY
14+
let api_key: String = env::var("OPENAI_API_KEY").expect("OPENAI_API_KEY must be set");
15+
let url: &str = "https://api.openai.com/v1/completions";
16+
17+
run_chat_loop(&client, &api_key, url).await?;
18+
19+
Ok(())
20+
}

0 commit comments

Comments
 (0)