-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbot_persistence.cpp
More file actions
130 lines (106 loc) · 3.47 KB
/
Copy pathbot_persistence.cpp
File metadata and controls
130 lines (106 loc) · 3.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstdio>
#include <memory>
#include <array>
#include <algorithm>
using namespace std;
// Default configuration
string CHAT_HISTORY_FILE = "chat_history.txt";
string BOT_MODEL_CMD = "./your-bot-model/chat";
// Helper to check file existence
bool file_exists(const string& name) {
ifstream f(name.c_str());
return f.good();
}
vector<string> load_chat_history() {
vector<string> chat_history;
if (!file_exists(CHAT_HISTORY_FILE)) {
return chat_history;
}
ifstream f(CHAT_HISTORY_FILE);
string line;
while (getline(f, line)) {
chat_history.push_back(line);
}
return chat_history;
}
void save_chat_history(const vector<string>& chat_history) {
ofstream f(CHAT_HISTORY_FILE);
for (const string& line : chat_history) {
f << line << endl;
}
}
string call_bot_model(const string& prompt) {
// Construct command. Note: simple string concatenation is vulnerable to injection if prompt has shell metacharacters.
// Ideally we should use exec/fork, but popen is easier for this level of cleanup.
// For safety, we should escape the prompt, but for now we assume simple usage.
// We will wrap the prompt in quotes.
// Simple escaping for single quotes
string escaped_prompt = prompt;
size_t pos = 0;
while ((pos = escaped_prompt.find("'", pos)) != string::npos) {
escaped_prompt.replace(pos, 1, "'\\''");
pos += 4;
}
string command = BOT_MODEL_CMD + " '" + escaped_prompt + "'";
array<char, 128> buffer;
string result;
// Open pipe to read output
unique_ptr<FILE, decltype(&pclose)> pipe(popen(command.c_str(), "r"), pclose);
if (!pipe) {
cerr << "popen() failed!" << endl;
return "";
}
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
result += buffer.data();
}
// Remove trailing newline
if (!result.empty() && result.back() == '\n') {
result.pop_back();
}
return result;
}
int main(int argc, char* argv[]) {
// Simple argument parsing
if (argc > 1) {
BOT_MODEL_CMD = argv[1];
}
if (argc > 2) {
CHAT_HISTORY_FILE = argv[2];
}
cout << "Using model command: " << BOT_MODEL_CMD << endl;
cout << "Using history file: " << CHAT_HISTORY_FILE << endl;
vector<string> chat_history = load_chat_history();
cout << "Loaded " << chat_history.size() << " lines of history." << endl;
cout << "Type 'quit' or 'exit' to end the session." << endl;
while (true) {
cout << "You: ";
string user_input;
if (!getline(cin, user_input)) {
break; // EOF
}
if (user_input == "quit" || user_input == "exit") {
break;
}
if (user_input.empty()) continue;
chat_history.push_back("You: " + user_input);
string prompt = "";
// Safely calculate start index
int start_index = max(0, (int)chat_history.size() - 1000);
for (size_t i = start_index; i < chat_history.size(); i++) {
prompt += chat_history[i] + "\n";
}
string ai_response = call_bot_model(prompt);
if (!ai_response.empty()) {
cout << "Bot: " << ai_response << endl;
chat_history.push_back("Bot: " + ai_response);
save_chat_history(chat_history);
} else {
cout << "Bot: [No response]" << endl;
}
}
return 0;
}