Skip to content

Commit

Permalink
feat: implement user interaction
Browse files Browse the repository at this point in the history
  • Loading branch information
jschang19 committed Dec 16, 2023
1 parent 33162a9 commit decc487
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 43 deletions.
2 changes: 1 addition & 1 deletion ChatGPT/include/ChatGPT.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace OpenAI {
OpenAI::ChatCompletion askChatGPT(const std::string& role);
std::string askWhisper(const std::string& audio_path);
std::vector< Message > prompts;
void Add_prompt(const std::string& new_role ,const std::string& new_content);
void Add_prompt(const Message& prompt);

private:
std::string m_token;
Expand Down
54 changes: 44 additions & 10 deletions ChatGPT/include/Game.h
Original file line number Diff line number Diff line change
@@ -1,34 +1,68 @@
#include <vector>
#include <string>
#include "ChatGPT.h"
#include <nlohmann/json.hpp>

namespace System {
struct UserChoice {
int story_id;
std::string content;
struct Option{
std::string id;
std::string text;
Option(std::string id, std::string text) : id(id), text(text) {}; // constructor
};

class Story {
public:
int id;
std::string place;
std::string content;
std::vector< UserChoice > choices;
std::string user_choice;
bool is_answered = false;
std::vector< System::Option > choices;
Story(int id, std::string place, std::string content)
: id(id), place(place), content(content) {}
~Story(); // destructor
void addChoice(int story_id, std::string content);
private:
};


class Game {
public:
int count;
int current_count = 0;
std::vector<int> story_ids;
void addPrompt(OpenAI::ChatGPT& chatGpt, const int story_id){
OpenAI::Message prompt = this->generateStoryPrompt(story_id);
chatGpt.Add_prompt(prompt);
};
OpenAI::ChatCompletion sendToChatGPT(OpenAI::ChatGPT& chatGpt){
auto response = chatGpt.askChatGPT("user");
return response;
};
std::vector<int> picked_story_ids;
Game(); // constructor
void parseGPTResponse(OpenAI::ChatCompletion& chatCompletion, int story_id){
System::Story* story_ptr = this->getStoryPtrById(story_id);
nlohmann::json j2;
try {
j2 = nlohmann::json::parse(chatCompletion.choices[0].message.content);
std::vector< System::Option > choices;
for (auto& choice : j2["options"]) {
choices.push_back(System::Option(choice["id"], choice["text"]));
}
this->setOptions(story_id, choices);
}catch(std::exception& e){
std::cerr<<"Game.h parsing Error: "+chatCompletion.choices[0].message.content;
}
};
Game();
~Game(); // destructor
std::vector< Story > stories;
std::vector< System::Story > stories;
std::vector< int > getRandStoryIds(int num);
Story* getStoryPtrById(int id);
std::vector< Story > readTextFile(const std::string& filename);
System::Story* getStoryPtrById(int id);
OpenAI::Message generateStoryPrompt(int id);
void setOptions(int id, const std::vector< System::Option > &choices);
void printOptions(int id);
bool setUserChoice(int story_id, const std::string& user_choice_id);
private:
std::vector< System::Story > readTextFile(const std::string& filename);
};
}
59 changes: 39 additions & 20 deletions ChatGPT/src/ChatGPT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,32 @@ OpenAI::ChatCompletion OpenAI::ChatGPT::askChatGPT(const std::string& role) {
if (prompt_message==""){ //exception handling
throw std::invalid_argument("Error:there is no prompt message, please use Add_prompts() to add prompt in Chatgpt");
}
nlohmann::json j;
j["model"] = "gpt-4-1106-preview";
j["messages"] = nlohmann::json::parse("[" + prompt_message + "]");
j["response_format"] = {{"type", "json_object"}};
j["temperature"] = 1;
j["max_tokens"] = 1000;
j["n"] = 1;

std::cout<< j.dump() << std::endl;

auto json="{\n"
" \"model\": \"gpt-3.5-turbo\",\n"
" \"messages\": ["+ prompt_message +"]\n"
"}";
auto response = cpr::Post(cpr::Url{m_link},
cpr::Body{j.dump()},
cpr::Bearer({m_token}),
cpr::Header{{"Content-Type", "application/json"}}).text;

auto response = cpr::Post(cpr::Url{m_link},cpr::Body{json},cpr::Bearer({m_token}),cpr::Header{{"Content-Type","application/json"}}).text;
OpenAI::ChatCompletion chatCompletion;
nlohmann::json j;
try {
nlohmann::json j_response = nlohmann::json::parse(response);
if (!j_response.contains("error")) {
from_json(j_response, chatCompletion);
} else {
throw OpenAI::Error{j_response.dump()};
}
} catch (std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
try {
j = nlohmann::json::parse(response);
}catch(std::exception& e){
Expand All @@ -41,14 +58,15 @@ OpenAI::ChatCompletion OpenAI::ChatGPT::askChatGPT(const std::string& role) {
}else{
throw OpenAI::Error{j.dump()};
}

//adding the respond to this->prompts
std::string bot_response_string="";
for(const auto& choice:chatCompletion.choices){
bot_response_string+=choice.message.content;
// load chatCompletion.content as json
nlohmann::json j2;
try {
j2 = nlohmann::json::parse(chatCompletion.choices[0].message.content);
}catch(std::exception& e){
std::cerr<<"parsing j2 Error: "+chatCompletion.choices[0].message.content;
}
this->Add_prompt("system",bot_response_string);

// add chatCompletion.choices[0].message.content into prompts
// this->Add_prompt(OpenAI::Message("assistant", j2["options"]));
return chatCompletion;
}

Expand All @@ -75,27 +93,28 @@ std::string OpenAI::ChatGPT::askWhisper(const std::string &audio_path) {
if(j.contains("error")) {
throw OpenAI::Error{j.dump()};
}

return j["text"];
}

void OpenAI::ChatGPT::Add_prompt(const std::string& new_role ,const std::string& new_content){
Message new_prompt(new_role, new_content);
void OpenAI::ChatGPT::Add_prompt(const Message& new_prompt){
this->prompts.push_back(new_prompt);
}

std::string OpenAI::ChatGPT::PromptsToStringContent(){
std :: string return_string="";
std :: string return_string="{\"role\": \"system\", \"content\": \"You are a text game system that generates interesting options to make young college players choose and laugh. you must produce content in Traditional Chinese.\"},";
for(int i=0; i<this->prompts.size(); i++){
return_string += " {\"role\": \"" + this->prompts[i].role + "\" , \"content\": \"" + this->prompts[i].content + "\" }";

return_string += " {\"role\": \"" + this->prompts[i].role + "\" , \"content\": \"" + this->prompts[i].content;
if (i == this->prompts.size()-1){
return_string += ",幫我想 4 個好笑且具有創意的遊戲情境讓我選擇,並確保選項都跟之前我的選擇行動有關,都以「 你 」當作開頭,都以句號結尾,請用一個 key 叫 options 的 JSON 物件格式回覆我,而這個 options 的 value 是一個 Array,每個陣列元素要包含 id 跟 text 兩個 key,id 代號為 a, b, c, d";
}
return_string += "\"}";
//處理換行符號
if (i != this->prompts.size()-1 ){
return_string+=",\n";
}else{
return_string+="\n";
}
}


return return_string;
}
24 changes: 12 additions & 12 deletions main.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include <iostream>
#include <string>
#include <vector>
#include "ChatGPT/include/ChatGPT.h"
#include "ChatGPT/include/Error.h"
#include "ChatGPT/include/Game.h"
// this is the main function
Expand All @@ -16,29 +15,30 @@ int main(int args,char** argv){
return 0;
}
System::Game game;
game.count=STORY_NUM;
OpenAI::ChatGPT chatGpt{argv[1]};
// get random story ids
std::vector<int> story_ids = game.getRandStoryIds(STORY_NUM);
game.story_ids = story_ids;
// get story pointers
std::vector<System::Story*> story_ptrs;


try {
for (int i=0; i<STORY_NUM; i++){
// get user input
int story_id = story_ids[i];
OpenAI::Message prompt = game.generateStoryPrompt(i);
game.addPrompt(chatGpt, story_id);
auto chatCompletion = game.sendToChatGPT(chatGpt);
game.parseGPTResponse(chatCompletion, story_id);
game.printOptions(story_id);

std::string userInput;
std::cout<<"Enter your message: ";
std::cout<<"輸入你的選擇:";
std::getline(std::cin,userInput);
chatGpt.Add_prompt("user","answer all the question in Chinese only");
auto response = chatGpt.askChatGPT("user"); //讓使用者問問題並記錄使用者的回答道response

std::string bot_response_string=""; //紀錄此輪chatgpt的回答

//Iterate all answers and adding it to answer
for(const auto& choice:response.choices){
std::cout<<choice.message.content;
}

game.setUserChoice(story_id, userInput);
game.current_count += 1;
}
}catch(OpenAI::Error& e){
//JSON error returned by the server
Expand Down

0 comments on commit decc487

Please sign in to comment.