14
14
#include < iostream>
15
15
#include < nlohmann/json.hpp>
16
16
#include < string>
17
+ #include < sys/stat.h>
17
18
#include < unordered_set>
18
19
19
20
using json = nlohmann::json;
@@ -58,6 +59,78 @@ namespace xcpp
58
59
}
59
60
};
60
61
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
+
61
134
class CurlHelper
62
135
{
63
136
private:
@@ -132,9 +205,10 @@ namespace xcpp
132
205
std::string gemini (const std::string& cell, const std::string& key)
133
206
{
134
207
CurlHelper curlHelper;
208
+ const std::string chatMessage = xcpp::ChatHistory::chat (" gemini" , " user" , cell);
135
209
const std::string url = " https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key="
136
210
+ key;
137
- const std::string postData = R"( {"contents": [{"parts":[{"text": " )" + cell + R"( "}]} ]})" ;
211
+ const std::string postData = R"( {"contents": [ )" + chatMessage + R"( ]})" ;
138
212
139
213
std::string response = curlHelper.performRequest (url, postData);
140
214
@@ -145,19 +219,21 @@ namespace xcpp
145
219
return " " ;
146
220
}
147
221
222
+ const std::string chat = xcpp::ChatHistory::chat (" gemini" , " model" , j[" candidates" ][0 ][" content" ][" parts" ][0 ][" text" ]);
223
+
148
224
return j[" candidates" ][0 ][" content" ][" parts" ][0 ][" text" ];
149
225
}
150
226
151
227
std::string openai (const std::string& cell, const std::string& key)
152
228
{
153
229
CurlHelper curlHelper;
154
230
const std::string url = " https://api.openai.com/v1/chat/completions" ;
231
+ const std::string chatMessage = xcpp::ChatHistory::chat (" openai" , " user" , cell);
155
232
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
+ })" ;
161
237
std::string authHeader = " Authorization: Bearer " + key;
162
238
163
239
std::string response = curlHelper.performRequest (url, postData, authHeader);
@@ -170,6 +246,8 @@ namespace xcpp
170
246
return " " ;
171
247
}
172
248
249
+ const std::string chat = xcpp::ChatHistory::chat (" openai" , " assistant" , j[" choices" ][0 ][" message" ][" content" ]);
250
+
173
251
return j[" choices" ][0 ][" message" ][" content" ];
174
252
}
175
253
@@ -192,11 +270,15 @@ namespace xcpp
192
270
return ;
193
271
}
194
272
195
- APIKeyManager api;
196
273
if (tokens[2 ] == " --save-key" )
197
274
{
198
275
xcpp::APIKeyManager::saveApiKey (model, cell);
199
276
return ;
277
+ }
278
+ else if (tokens[2 ] == " --refresh" )
279
+ {
280
+ xcpp::ChatHistory::refresh (model);
281
+ return ;
200
282
}
201
283
202
284
std::string key = xcpp::APIKeyManager::loadApiKey (model);
0 commit comments