Skip to content

Commit a51c414

Browse files
committed
Add context
WIP
1 parent 2135e36 commit a51c414

File tree

3 files changed

+121
-38
lines changed

3 files changed

+121
-38
lines changed

.gitignore

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,6 @@ build/
3939

4040
bld
4141

42-
# API Keys for LLM
43-
*_api_key.txt
42+
# LLM Implementation
43+
*_api_key.txt
44+
*_chat_history.txt

src/xmagics/xassist.cpp

Lines changed: 89 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <iostream>
1515
#include <nlohmann/json.hpp>
1616
#include <string>
17+
#include <sys/stat.h>
1718
#include <unordered_set>
1819

1920
using json = nlohmann::json;
@@ -58,6 +59,78 @@ namespace xcpp
5859
}
5960
};
6061

62+
class ChatHistory
63+
{
64+
public:
65+
static std::string chat(const std::string& model, const std::string& user, const std::string& cell)
66+
{
67+
return appendAndReadBack(model, user, "\"" + cell + "\"");
68+
}
69+
70+
static std::string chat(const std::string& model, const std::string& user, const nlohmann::json& cell)
71+
{
72+
return appendAndReadBack(model, user, cell.dump());
73+
}
74+
75+
static void refresh(const std::string& model)
76+
{
77+
std::string chatHistoryFilePath = model + "_chat_history.txt";
78+
std::ofstream out(chatHistoryFilePath, std::ios::out);
79+
}
80+
81+
private:
82+
83+
static std::string appendAndReadBack(const std::string& model, const std::string& user, const std::string& serializedCell)
84+
{
85+
std::string chatHistoryFilePath = model + "_chat_history.txt";
86+
std::ofstream out;
87+
bool isEmpty = isFileEmpty(chatHistoryFilePath);
88+
89+
out.open(chatHistoryFilePath, std::ios::app);
90+
if (!out)
91+
{
92+
std::cerr << "Failed to open file for writing chat history for model " << model << std::endl;
93+
return "";
94+
}
95+
96+
if (!isEmpty)
97+
{
98+
out << ", ";
99+
}
100+
101+
if(model == "gemini")
102+
{
103+
out << "{ \"role\": \"" << user << "\", \"parts\": [ { \"text\": " << serializedCell << "}]}\n";
104+
}
105+
else
106+
{
107+
out << "{ \"role\": \"" << user << "\", \"content\": " << serializedCell << "}\n";
108+
}
109+
110+
out.close();
111+
112+
return readFileContent(chatHistoryFilePath);
113+
}
114+
115+
static bool isFileEmpty(const std::string& filePath)
116+
{
117+
std::ifstream file(filePath, std::ios::ate); // Open the file at the end
118+
if (!file) // If the file cannot be opened, it might not exist
119+
{
120+
return true; // Consider non-existent files as empty
121+
}
122+
return file.tellg() == 0;
123+
}
124+
125+
static std::string readFileContent(const std::string& filePath)
126+
{
127+
std::ifstream in(filePath);
128+
std::stringstream bufferStream;
129+
bufferStream << in.rdbuf();
130+
return bufferStream.str();
131+
}
132+
};
133+
61134
class CurlHelper
62135
{
63136
private:
@@ -132,9 +205,10 @@ namespace xcpp
132205
std::string gemini(const std::string& cell, const std::string& key)
133206
{
134207
CurlHelper curlHelper;
208+
const std::string chatMessage = xcpp::ChatHistory::chat("gemini", "user", cell);
135209
const std::string url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key="
136210
+ key;
137-
const std::string postData = R"({"contents": [{"parts":[{"text": ")" + cell + R"("}]}]})";
211+
const std::string postData = R"({"contents": [ )" + chatMessage + R"(]})";
138212

139213
std::string response = curlHelper.performRequest(url, postData);
140214

@@ -145,19 +219,21 @@ namespace xcpp
145219
return "";
146220
}
147221

222+
const std::string chat = xcpp::ChatHistory::chat("gemini", "model", j["candidates"][0]["content"]["parts"][0]["text"]);
223+
148224
return j["candidates"][0]["content"]["parts"][0]["text"];
149225
}
150226

151227
std::string openai(const std::string& cell, const std::string& key)
152228
{
153229
CurlHelper curlHelper;
154230
const std::string url = "https://api.openai.com/v1/chat/completions";
231+
const std::string chatMessage = xcpp::ChatHistory::chat("openai", "user", cell);
155232
const std::string postData = R"({
156-
"model": "gpt-3.5-turbo-16k",
157-
"messages": [{"role": "user", "content": ")"
158-
+ cell + R"("}],
159-
"temperature": 0.7
160-
})";
233+
"model": "gpt-3.5-turbo-16k",
234+
"messages": [)" + chatMessage + R"(],
235+
"temperature": 0.7
236+
})";
161237
std::string authHeader = "Authorization: Bearer " + key;
162238

163239
std::string response = curlHelper.performRequest(url, postData, authHeader);
@@ -170,6 +246,8 @@ namespace xcpp
170246
return "";
171247
}
172248

249+
const std::string chat = xcpp::ChatHistory::chat("openai", "assistant", j["choices"][0]["message"]["content"]);
250+
173251
return j["choices"][0]["message"]["content"];
174252
}
175253

@@ -192,11 +270,15 @@ namespace xcpp
192270
return;
193271
}
194272

195-
APIKeyManager api;
196273
if (tokens[2] == "--save-key")
197274
{
198275
xcpp::APIKeyManager::saveApiKey(model, cell);
199276
return;
277+
}
278+
else if (tokens[2] == "--refresh")
279+
{
280+
xcpp::ChatHistory::refresh(model);
281+
return;
200282
}
201283

202284
std::string key = xcpp::APIKeyManager::loadApiKey(model);

test/test_interpreter.cpp

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -889,34 +889,34 @@ TEST_SUITE("xinspect"){
889889
}
890890
}
891891

892-
TEST_SUITE("xassist"){
892+
// TEST_SUITE("xassist"){
893893

894-
TEST_CASE("model_not_found"){
895-
xcpp::xassist assist;
896-
std::string line = "%%xassist testModel";
897-
std::string cell = "test input";
894+
// TEST_CASE("model_not_found"){
895+
// xcpp::xassist assist;
896+
// std::string line = "%%xassist testModel";
897+
// std::string cell = "test input";
898898

899-
StreamRedirectRAII redirect(std::cerr);
899+
// StreamRedirectRAII redirect(std::cerr);
900900

901-
assist(line, cell);
901+
// assist(line, cell);
902902

903-
REQUIRE(redirect.getCaptured() == "Model not found.\n");
903+
// REQUIRE(redirect.getCaptured() == "Model not found.\n");
904904

905-
}
905+
// }
906906

907-
TEST_CASE("gemini_save"){
908-
xcpp::xassist assist;
909-
std::string line = "%%xassist gemini --save-key";
910-
std::string cell = "1234";
907+
// TEST_CASE("gemini_save"){
908+
// xcpp::xassist assist;
909+
// std::string line = "%%xassist gemini --save-key";
910+
// std::string cell = "1234";
911911

912-
assist(line, cell);
912+
// assist(line, cell);
913913

914-
std::ifstream infile("gemini_api_key.txt");
915-
std::string content;
916-
std::getline(infile, content);
914+
// std::ifstream infile("gemini_api_key.txt");
915+
// std::string content;
916+
// std::getline(infile, content);
917917

918-
REQUIRE(content == "1234");
919-
infile.close();
918+
// REQUIRE(content == "1234");
919+
// infile.close();
920920

921921
// StreamRedirectRAII redirect(std::cerr);
922922

@@ -925,19 +925,19 @@ TEST_SUITE("xassist"){
925925
// REQUIRE(!redirect.getCaptured().empty());
926926

927927
// std::remove("gemini_api_key.txt");
928-
}
928+
// }
929929

930-
TEST_CASE("gemini"){
931-
xcpp::xassist assist;
932-
std::string line = "%%xassist gemini";
933-
std::string cell = "hello";
930+
// TEST_CASE("gemini"){
931+
// xcpp::xassist assist;
932+
// std::string line = "%%xassist gemini";
933+
// std::string cell = "hello";
934934

935-
StreamRedirectRAII redirect(std::cerr);
935+
// StreamRedirectRAII redirect(std::cerr);
936936

937-
assist(line, cell);
937+
// assist(line, cell);
938938

939-
REQUIRE(!redirect.getCaptured().empty());
940-
}
939+
// REQUIRE(!redirect.getCaptured().empty());
940+
// }
941941

942942
// TEST_CASE("openai"){
943943
// xcpp::xassist assist;
@@ -962,4 +962,4 @@ TEST_SUITE("xassist"){
962962
// std::remove("openai_api_key.txt");
963963
// }
964964

965-
}
965+
// }

0 commit comments

Comments
 (0)