@bniladridas/cursor 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.clang-tidy +28 -0
- package/.dockerignore +56 -0
- package/.env.example +29 -0
- package/.github/CODEOWNERS +2 -0
- package/.github/ISSUE_TEMPLATE/blank.md +27 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +33 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +24 -0
- package/.github/SECURITY.md +24 -0
- package/.github/codeql/codeql-config.yml +8 -0
- package/.github/dependabot.yml +14 -0
- package/.github/labeler.yml +50 -0
- package/.github/packaging/brand-cursor.png +0 -0
- package/.github/packaging/database/init.sql +48 -0
- package/.github/packaging/docker/Dockerfile +111 -0
- package/.github/packaging/docker/docker-compose.yml +56 -0
- package/.github/packaging/scripts/preflight.sh +413 -0
- package/.github/packaging/scripts/prepare-release.sh +141 -0
- package/.github/packaging/scripts/release.sh +22 -0
- package/.github/packaging/scripts/setup-git-hooks.sh +73 -0
- package/.github/pull_request_template.md +31 -0
- package/.github/signed.json +9 -0
- package/.github/workflows/README.md +23 -0
- package/.github/workflows/ci.yml +181 -0
- package/.github/workflows/cla.yml +33 -0
- package/.github/workflows/formula-sha.yml +63 -0
- package/.github/workflows/issue-response.yml +44 -0
- package/.github/workflows/labeler.yml +42 -0
- package/.github/workflows/pr-body.yml +49 -0
- package/.github/workflows/release.yml +176 -0
- package/.github/workflows/security.yml +94 -0
- package/.github/workflows/stale.yml +38 -0
- package/AGENTS.md +49 -0
- package/CHANGELOG.md +3 -0
- package/CMakeLists.txt +646 -0
- package/Formula/cursor.rb +46 -0
- package/LICENSE +201 -0
- package/Makefile +28 -0
- package/README.md +46 -0
- package/cli.js +16 -0
- package/include/agent.h +86 -0
- package/include/agent_mode.h +17 -0
- package/include/memory_manager.h +102 -0
- package/include/services/ai_service.h +31 -0
- package/include/services/auth_service.h +87 -0
- package/include/services/checkpoint_service.h +69 -0
- package/include/services/codebase_service.h +38 -0
- package/include/services/command_service.h +23 -0
- package/include/services/context_service.h +74 -0
- package/include/services/database_service.h +56 -0
- package/include/services/error_service.h +106 -0
- package/include/services/file_service.h +51 -0
- package/include/services/git_service.h +29 -0
- package/include/services/github_service.h +85 -0
- package/include/services/mcp_service.h +85 -0
- package/include/services/multi_file_service.h +93 -0
- package/include/services/sandbox_service.h +96 -0
- package/include/services/theme_service.h +67 -0
- package/include/services/web_service.h +52 -0
- package/include/utils/config.h +68 -0
- package/include/utils/memory_utils.h +79 -0
- package/include/utils/platform.h +56 -0
- package/include/utils/ui.h +43 -0
- package/include/utils/validation.h +63 -0
- package/include/utils/version.h.in +17 -0
- package/install.js +49 -0
- package/package.json +16 -0
- package/release/checksums.txt +3 -0
- package/release/cursor-linux/cursor_v0.1.7_linux_amd64.tar.gz +0 -0
- package/release/cursor-macos/cursor_v0.1.7_darwin_arm64.tar.gz +0 -0
- package/release/cursor-windows/cursor__windows_amd64.zip +0 -0
- package/src/agent.cpp +2026 -0
- package/src/main.cpp +97 -0
- package/src/memory_manager.cpp +814 -0
- package/src/services/ai_service.cpp +366 -0
- package/src/services/auth_service.cpp +779 -0
- package/src/services/checkpoint_service.cpp +465 -0
- package/src/services/codebase_service.cpp +233 -0
- package/src/services/command_service.cpp +82 -0
- package/src/services/context_service.cpp +348 -0
- package/src/services/database_service.cpp +148 -0
- package/src/services/error_service.cpp +438 -0
- package/src/services/file_service.cpp +349 -0
- package/src/services/git_service.cpp +148 -0
- package/src/services/github_service.cpp +435 -0
- package/src/services/mcp_service.cpp +481 -0
- package/src/services/multi_file_service.cpp +591 -0
- package/src/services/sandbox_service.cpp +678 -0
- package/src/services/theme_service.cpp +429 -0
- package/src/services/web_service.cpp +532 -0
- package/src/utils/config.cpp +77 -0
- package/src/utils/memory_utils.cpp +93 -0
- package/src/utils/ui.cpp +307 -0
- package/src/utils/validation.cpp +306 -0
- package/src/utils/version.cpp +175 -0
- package/tests/e2e/docker-compose.yml +195 -0
- package/tests/e2e/run_e2e_tests.sh +70 -0
- package/tests/e2e/run_tests_in_docker.sh +115 -0
- package/tests/main_test.cpp +16 -0
- package/tests/mocks/mock_ollama.py +98 -0
- package/tests/mocks/start_nginx.sh +64 -0
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
#include "services/ai_service.h"
|
|
2
|
+
#include "agent_mode.h"
|
|
3
|
+
#include "services/web_service.h"
|
|
4
|
+
#include "utils/config.h"
|
|
5
|
+
#include <curl/curl.h>
|
|
6
|
+
#include <nlohmann/json.hpp>
|
|
7
|
+
#include <sstream>
|
|
8
|
+
|
|
9
|
+
// Use the HeaderMap from web_service.h
|
|
10
|
+
|
|
11
|
+
// Reuse the CaseInsensitiveCompare and HeaderMap from web_service.h
|
|
12
|
+
|
|
13
|
+
namespace Services {
|
|
14
|
+
|
|
15
|
+
AIService::AIService(Core::AgentMode mode, const std::string &api_key)
|
|
16
|
+
: mode_(mode), api_key_(api_key) {}
|
|
17
|
+
|
|
18
|
+
bool AIService::is_online_mode() const {
|
|
19
|
+
return mode_ == Core::AgentMode::MODE_TOGETHER ||
|
|
20
|
+
mode_ == Core::AgentMode::MODE_CEREBRAS ||
|
|
21
|
+
mode_ == Core::AgentMode::MODE_FIREWORKS ||
|
|
22
|
+
mode_ == Core::AgentMode::MODE_GROQ ||
|
|
23
|
+
mode_ == Core::AgentMode::MODE_DEEPSEEK ||
|
|
24
|
+
mode_ == Core::AgentMode::MODE_OPENAI;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
bool AIService::is_available() {
|
|
28
|
+
// For online providers API key is required.
|
|
29
|
+
if (is_online_mode()) {
|
|
30
|
+
return !api_key_.empty();
|
|
31
|
+
}
|
|
32
|
+
// Offline modes don't need an API key (they talk to local server)
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
std::string AIService::get_api_url() {
|
|
37
|
+
if (std::getenv("TEST_MODE")) {
|
|
38
|
+
// Use mock URLs for testing
|
|
39
|
+
switch (mode_) {
|
|
40
|
+
case Core::AgentMode::MODE_TOGETHER:
|
|
41
|
+
return "http://mock-together/v1/chat/completions";
|
|
42
|
+
case Core::AgentMode::MODE_CEREBRAS:
|
|
43
|
+
return "http://mock-cerebras/v1/chat/completions";
|
|
44
|
+
case Core::AgentMode::MODE_FIREWORKS:
|
|
45
|
+
return "http://mock-fireworks/inference/v1/chat/completions";
|
|
46
|
+
case Core::AgentMode::MODE_GROQ:
|
|
47
|
+
return "http://mock-groq/openai/v1/chat/completions";
|
|
48
|
+
case Core::AgentMode::MODE_DEEPSEEK:
|
|
49
|
+
return "http://mock-deepseek/v1/chat/completions";
|
|
50
|
+
case Core::AgentMode::MODE_OPENAI:
|
|
51
|
+
return "http://mock-openai/v1/chat/completions";
|
|
52
|
+
case Core::AgentMode::MODE_LLAMA_3B:
|
|
53
|
+
case Core::AgentMode::MODE_LLAMA_LATEST:
|
|
54
|
+
case Core::AgentMode::MODE_LLAMA_31:
|
|
55
|
+
default:
|
|
56
|
+
return "http://mock-ollama:11434/api/chat";
|
|
57
|
+
}
|
|
58
|
+
} else {
|
|
59
|
+
switch (mode_) {
|
|
60
|
+
case Core::AgentMode::MODE_TOGETHER:
|
|
61
|
+
return "https://api.together.xyz/v1/chat/completions";
|
|
62
|
+
case Core::AgentMode::MODE_CEREBRAS:
|
|
63
|
+
return "https://api.cerebras.ai/v1/chat/completions";
|
|
64
|
+
case Core::AgentMode::MODE_FIREWORKS:
|
|
65
|
+
return "https://api.fireworks.ai/inference/v1/chat/completions";
|
|
66
|
+
case Core::AgentMode::MODE_GROQ:
|
|
67
|
+
return "https://api.groq.com/openai/v1/chat/completions";
|
|
68
|
+
case Core::AgentMode::MODE_DEEPSEEK:
|
|
69
|
+
return "https://api.deepseek.com/v1/chat/completions";
|
|
70
|
+
case Core::AgentMode::MODE_OPENAI:
|
|
71
|
+
return "https://api.openai.com/v1/chat/completions";
|
|
72
|
+
case Core::AgentMode::MODE_LLAMA_3B:
|
|
73
|
+
case Core::AgentMode::MODE_LLAMA_LATEST:
|
|
74
|
+
case Core::AgentMode::MODE_LLAMA_31:
|
|
75
|
+
default:
|
|
76
|
+
return "http://localhost:11434/api/chat";
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
nlohmann::json AIService::create_standard_payload(const std::string &model,
|
|
82
|
+
const std::string &user_input,
|
|
83
|
+
const std::string &context) {
|
|
84
|
+
std::string system_prompt = "You are a helpful AI assistant. " + context;
|
|
85
|
+
return {{"model", model},
|
|
86
|
+
{"messages",
|
|
87
|
+
{{{"role", "system"}, {"content", system_prompt}},
|
|
88
|
+
{{"role", "user"}, {"content", user_input}}}},
|
|
89
|
+
{"max_tokens", 1000},
|
|
90
|
+
{"temperature", 0.7}};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
nlohmann::json AIService::create_payload(const std::string &user_input,
|
|
94
|
+
const std::string &context) {
|
|
95
|
+
std::string system_prompt =
|
|
96
|
+
"You are an advanced AI agent with comprehensive codebase analysis and "
|
|
97
|
+
"development capabilities.\n\n"
|
|
98
|
+
"BASIC COMMANDS:\n"
|
|
99
|
+
"• search:query - Search the web for information\n"
|
|
100
|
+
"• cmd:command - Execute shell commands safely\n"
|
|
101
|
+
"• read:filename - Read file contents\n"
|
|
102
|
+
"• read:filename:start:count - Read specific line ranges from files\n"
|
|
103
|
+
"• write:filename content - Write content to files\n\n"
|
|
104
|
+
"ADVANCED FILE OPERATIONS:\n"
|
|
105
|
+
"• replace:filename:old_text:new_text[:expected_count] - Replace text in "
|
|
106
|
+
"files with precision\n"
|
|
107
|
+
"• grep:pattern[:directory[:file_filter]] - Search for patterns in files "
|
|
108
|
+
"and directories\n\n"
|
|
109
|
+
"CODEBASE ANALYSIS:\n"
|
|
110
|
+
"• analyze:path - Analyze codebase structure, file types, and project "
|
|
111
|
+
"configuration\n"
|
|
112
|
+
"• components:path - Find main components and their relationships\n"
|
|
113
|
+
"• todos:path - Find all task comments in codebase\n"
|
|
114
|
+
"• tree:path - Display directory tree structure\n\n"
|
|
115
|
+
"GIT INTEGRATION:\n"
|
|
116
|
+
"• git:log - Show recent git commit history\n"
|
|
117
|
+
"• git:status - Show git working directory status\n"
|
|
118
|
+
"• git:analyze - Comprehensive git repository analysis\n\n"
|
|
119
|
+
"MEMORY MANAGEMENT:\n"
|
|
120
|
+
"• remember:fact - Save important facts to persistent global memory\n"
|
|
121
|
+
"• memory - View stored global memories\n"
|
|
122
|
+
"• clear - Clear current session memory\n"
|
|
123
|
+
"• forget - Clear all global memories\n\n"
|
|
124
|
+
"CAPABILITIES:\n"
|
|
125
|
+
"- Understand codebase structure and relationships\n"
|
|
126
|
+
"- Analyze git history and track changes\n"
|
|
127
|
+
"- Find and prioritize task comments\n"
|
|
128
|
+
"- Advanced text search and replacement with context validation\n"
|
|
129
|
+
"- Structured memory system for facts and preferences\n"
|
|
130
|
+
"- File operations with safety checks and path validation\n"
|
|
131
|
+
"- Enhanced error handling and user feedback\n\n"
|
|
132
|
+
"When users ask about codebase analysis, use analyze: or components: "
|
|
133
|
+
"commands.\n"
|
|
134
|
+
"For git-related questions, use git: commands.\n"
|
|
135
|
+
"For finding tasks or technical debt, use todos: command.\n"
|
|
136
|
+
"For complex file editing, use replace: instead of write: when modifying "
|
|
137
|
+
"existing content.\n"
|
|
138
|
+
"Use grep: to search for code patterns or text across multiple files.\n"
|
|
139
|
+
"Remember important user preferences and facts using remember:.\n"
|
|
140
|
+
"Be helpful, precise, and professional.\n\n"
|
|
141
|
+
"Conversation history:\n" +
|
|
142
|
+
context;
|
|
143
|
+
|
|
144
|
+
switch (mode_) {
|
|
145
|
+
case Core::AgentMode::MODE_TOGETHER: // Together AI
|
|
146
|
+
return create_standard_payload(
|
|
147
|
+
"meta-llama/Llama-3.3-70B-Instruct-Turbo-Free", user_input,
|
|
148
|
+
system_prompt);
|
|
149
|
+
case Core::AgentMode::MODE_CEREBRAS: // Cerebras
|
|
150
|
+
return {{"model", "llama-4-maverick-17b-128e-instruct"},
|
|
151
|
+
{"messages",
|
|
152
|
+
{{{"role", "system"}, {"content", system_prompt}},
|
|
153
|
+
{{"role", "user"}, {"content", user_input}}}},
|
|
154
|
+
{"stream", true},
|
|
155
|
+
{"max_completion_tokens", 4096},
|
|
156
|
+
{"temperature", 0.7},
|
|
157
|
+
{"top_p", 0.9}};
|
|
158
|
+
case Core::AgentMode::MODE_FIREWORKS: // Fireworks
|
|
159
|
+
return create_standard_payload(
|
|
160
|
+
"accounts/fireworks/models/llama-v3-70b-instruct", user_input,
|
|
161
|
+
system_prompt);
|
|
162
|
+
case Core::AgentMode::MODE_GROQ: // Groq
|
|
163
|
+
return create_standard_payload("llama-3.1-70b-versatile", user_input,
|
|
164
|
+
system_prompt);
|
|
165
|
+
case Core::AgentMode::MODE_DEEPSEEK: // DeepSeek
|
|
166
|
+
return create_standard_payload("deepseek-chat", user_input, system_prompt);
|
|
167
|
+
case Core::AgentMode::MODE_OPENAI: // OpenAI
|
|
168
|
+
return create_standard_payload("gpt-4", user_input, system_prompt);
|
|
169
|
+
case Core::AgentMode::MODE_LLAMA_3B: // Llama 3B (local)
|
|
170
|
+
return {{"model", "llama3.2:3b"},
|
|
171
|
+
{"stream", false},
|
|
172
|
+
{"messages",
|
|
173
|
+
{{{"role", "system"}, {"content", system_prompt}},
|
|
174
|
+
{{"role", "user"}, {"content", user_input}}}}};
|
|
175
|
+
|
|
176
|
+
case Core::AgentMode::MODE_LLAMA_LATEST: // Llama latest (local)
|
|
177
|
+
return {{"model", "llama3.2:latest"},
|
|
178
|
+
{"stream", false},
|
|
179
|
+
{"messages",
|
|
180
|
+
{{{"role", "system"}, {"content", system_prompt}},
|
|
181
|
+
{{"role", "user"}, {"content", user_input}}}}};
|
|
182
|
+
|
|
183
|
+
case Core::AgentMode::MODE_LLAMA_31: // Llama 3.1 (local)
|
|
184
|
+
return {{"model", "llama3.1:latest"},
|
|
185
|
+
{"stream", false},
|
|
186
|
+
{"messages",
|
|
187
|
+
{{{"role", "system"}, {"content", system_prompt}},
|
|
188
|
+
{{"role", "user"}, {"content", user_input}}}}};
|
|
189
|
+
|
|
190
|
+
default: // Fallback to Llama 3B
|
|
191
|
+
return {{"model", "llama3.2:3b"},
|
|
192
|
+
{"stream", false},
|
|
193
|
+
{"messages",
|
|
194
|
+
{{{"role", "system"}, {"content", system_prompt}},
|
|
195
|
+
{{"role", "user"}, {"content", user_input}}}}};
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
std::string AIService::parse_cerebras_stream(const std::string &response) {
|
|
200
|
+
// Response is server-sent events style; accumulate content deltas.
|
|
201
|
+
std::string result;
|
|
202
|
+
std::istringstream stream(response);
|
|
203
|
+
std::string line;
|
|
204
|
+
|
|
205
|
+
while (std::getline(stream, line)) {
|
|
206
|
+
// trim leading spaces
|
|
207
|
+
if (line.starts_with("data: ")) {
|
|
208
|
+
std::string json_str = line.substr(6);
|
|
209
|
+
if (json_str == "[DONE]")
|
|
210
|
+
break;
|
|
211
|
+
|
|
212
|
+
try {
|
|
213
|
+
auto json = nlohmann::json::parse(json_str);
|
|
214
|
+
if (json.contains("choices") && !json["choices"].empty()) {
|
|
215
|
+
auto &choice = json["choices"][0];
|
|
216
|
+
if (choice.contains("delta") && choice["delta"].contains("content")) {
|
|
217
|
+
// content might be string
|
|
218
|
+
result += choice["delta"]["content"].get<std::string>();
|
|
219
|
+
} else if (choice.contains("text")) {
|
|
220
|
+
result += choice["text"].get<std::string>();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
} catch (const std::exception &) {
|
|
224
|
+
// ignore malformed chunk and continue
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return result;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
std::string safe_get_string(const nlohmann::json &j,
|
|
233
|
+
const std::initializer_list<std::string> &path,
|
|
234
|
+
const std::string &fallback = "") {
|
|
235
|
+
const nlohmann::json *cur = &j;
|
|
236
|
+
for (const auto &p : path) {
|
|
237
|
+
if (!cur->is_object() || !cur->contains(p))
|
|
238
|
+
return fallback;
|
|
239
|
+
cur = &((*cur)[p]);
|
|
240
|
+
}
|
|
241
|
+
if (cur->is_string())
|
|
242
|
+
return cur->get<std::string>();
|
|
243
|
+
return fallback;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
std::string AIService::chat(const std::string &user_input,
|
|
247
|
+
const std::string &context) {
|
|
248
|
+
if (!is_available()) {
|
|
249
|
+
return "Error: AI service is not available. Please check your API key and "
|
|
250
|
+
"internet connection.";
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
auto payload = create_payload(user_input, context);
|
|
254
|
+
auto url = get_api_url();
|
|
255
|
+
|
|
256
|
+
try {
|
|
257
|
+
// Set up headers
|
|
258
|
+
HeaderMap headers = {{"Content-Type", "application/json"},
|
|
259
|
+
{"Accept", "text/event-stream"}};
|
|
260
|
+
|
|
261
|
+
// Set API key in appropriate header based on service
|
|
262
|
+
switch (mode_) {
|
|
263
|
+
case Core::AgentMode::MODE_TOGETHER: // Together AI
|
|
264
|
+
case Core::AgentMode::MODE_FIREWORKS: // Fireworks
|
|
265
|
+
case Core::AgentMode::MODE_GROQ: // Groq
|
|
266
|
+
case Core::AgentMode::MODE_DEEPSEEK: // DeepSeek
|
|
267
|
+
case Core::AgentMode::MODE_OPENAI: // OpenAI
|
|
268
|
+
headers["Authorization"] = "Bearer " + api_key_;
|
|
269
|
+
break;
|
|
270
|
+
case Core::AgentMode::MODE_CEREBRAS: // Cerebras
|
|
271
|
+
headers["X-API-Key"] = api_key_;
|
|
272
|
+
break;
|
|
273
|
+
case Core::AgentMode::MODE_LLAMA_3B: // Local Ollama
|
|
274
|
+
case Core::AgentMode::MODE_LLAMA_LATEST:
|
|
275
|
+
case Core::AgentMode::MODE_LLAMA_31:
|
|
276
|
+
// No API key needed for local
|
|
277
|
+
break;
|
|
278
|
+
case Core::AgentMode::MODE_UNSET:
|
|
279
|
+
// No action
|
|
280
|
+
break;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Use WebService to make the HTTP request
|
|
284
|
+
WebService web_service;
|
|
285
|
+
std::string json_body = payload.dump();
|
|
286
|
+
|
|
287
|
+
WebResponse response;
|
|
288
|
+
if (mode_ == Core::AgentMode::MODE_TOGETHER ||
|
|
289
|
+
mode_ == Core::AgentMode::MODE_CEREBRAS ||
|
|
290
|
+
mode_ == Core::AgentMode::MODE_FIREWORKS ||
|
|
291
|
+
mode_ == Core::AgentMode::MODE_GROQ ||
|
|
292
|
+
mode_ == Core::AgentMode::MODE_DEEPSEEK ||
|
|
293
|
+
mode_ == Core::AgentMode::MODE_OPENAI ||
|
|
294
|
+
mode_ == Core::AgentMode::MODE_LLAMA_3B ||
|
|
295
|
+
mode_ == Core::AgentMode::MODE_LLAMA_LATEST ||
|
|
296
|
+
mode_ == Core::AgentMode::MODE_LLAMA_31) {
|
|
297
|
+
// All providers use POST
|
|
298
|
+
response = web_service.post_json(url, json_body, headers);
|
|
299
|
+
} else {
|
|
300
|
+
// Fallback (should not happen)
|
|
301
|
+
response = web_service.post_json(url, json_body, headers);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
if (response.status_code != 200) {
|
|
305
|
+
std::string error_content = response.content;
|
|
306
|
+
if (error_content.length() > 500) {
|
|
307
|
+
error_content = error_content.substr(0, 500) + "...[truncated]";
|
|
308
|
+
}
|
|
309
|
+
return "Error: AI service returned status code " +
|
|
310
|
+
std::to_string(response.status_code) + " - " + error_content +
|
|
311
|
+
" | Error: " + response.error_message;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Handle streaming response for Cerebras
|
|
315
|
+
if (mode_ == Core::AgentMode::MODE_CEREBRAS) {
|
|
316
|
+
return parse_cerebras_stream(response.content);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// Parse the response based on the service
|
|
320
|
+
auto json_response = nlohmann::json::parse(response.content);
|
|
321
|
+
|
|
322
|
+
// Handle different response formats
|
|
323
|
+
switch (mode_) {
|
|
324
|
+
case Core::AgentMode::MODE_TOGETHER: // Together AI
|
|
325
|
+
case Core::AgentMode::MODE_FIREWORKS: // Fireworks
|
|
326
|
+
case Core::AgentMode::MODE_GROQ: // Groq
|
|
327
|
+
case Core::AgentMode::MODE_DEEPSEEK: // DeepSeek
|
|
328
|
+
case Core::AgentMode::MODE_OPENAI: // OpenAI
|
|
329
|
+
case Core::AgentMode::MODE_CEREBRAS: // Cerebras
|
|
330
|
+
if (json_response.contains("choices") &&
|
|
331
|
+
!json_response["choices"].empty()) {
|
|
332
|
+
auto &choice = json_response["choices"][0];
|
|
333
|
+
if (choice.contains("message") &&
|
|
334
|
+
choice["message"].contains("content")) {
|
|
335
|
+
return choice["message"]["content"].get<std::string>();
|
|
336
|
+
} else if (choice.contains("text")) {
|
|
337
|
+
return choice["text"].get<std::string>();
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
break;
|
|
341
|
+
case Core::AgentMode::MODE_LLAMA_3B: // Local Ollama
|
|
342
|
+
case Core::AgentMode::MODE_LLAMA_LATEST:
|
|
343
|
+
case Core::AgentMode::MODE_LLAMA_31:
|
|
344
|
+
if (json_response.contains("message") &&
|
|
345
|
+
json_response["message"].contains("content")) {
|
|
346
|
+
return json_response["message"]["content"].get<std::string>();
|
|
347
|
+
} else if (json_response.contains("response")) {
|
|
348
|
+
return json_response["response"].get<std::string>();
|
|
349
|
+
}
|
|
350
|
+
break;
|
|
351
|
+
case Core::AgentMode::MODE_UNSET:
|
|
352
|
+
// No action
|
|
353
|
+
break;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// If we get here, the response format wasn't as expected
|
|
357
|
+
return "Error: Unexpected response format from AI service: " +
|
|
358
|
+
response.content;
|
|
359
|
+
|
|
360
|
+
} catch (const std::exception &e) {
|
|
361
|
+
return "Error: " + std::string(e.what());
|
|
362
|
+
}
|
|
363
|
+
return "Error: Unknown error occurred in AI service";
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
} // namespace Services
|