@@ -66,7 +66,7 @@ bool ServerStartCmd::Exec(const std::string& host, int port,
6666 si.cb = sizeof (si);
6767 ZeroMemory (&pi, sizeof (pi));
6868 std::wstring params = L" --start-server" ;
69- params += L" --config_file_path \" " +
69+ params += L" --config_file_path \" " +
7070 file_manager_utils::GetConfigurationPath ().wstring () + L" \" " ;
7171 params += L" --data_folder_path \" " +
7272 file_manager_utils::GetCortexDataPath ().wstring () + L" \" " ;
@@ -80,17 +80,17 @@ bool ServerStartCmd::Exec(const std::string& host, int port,
8080 mutable_cmds.push_back (L' \0 ' );
8181 // Create child process
8282 if (!CreateProcess (
83- NULL , // No module name (use command line)
83+ NULL , // No module name (use command line)
8484 mutable_cmds
85- .data (), // Command line (replace with your actual executable)
86- NULL , // Process handle not inheritable
87- NULL , // Thread handle not inheritable
88- FALSE , // Set handle inheritance
89- CREATE_NO_WINDOW, // No new console
90- NULL , // Use parent's environment block
91- NULL , // Use parent's starting directory
92- &si, // Pointer to STARTUPINFO structure
93- &pi)) // Pointer to PROCESS_INFORMATION structure
85+ .data (), // Command line (replace with your actual executable)
86+ NULL , // Process handle not inheritable
87+ NULL , // Thread handle not inheritable
88+ FALSE , // Set handle inheritance
89+ CREATE_NO_WINDOW, // No new console
90+ NULL , // Use parent's environment block
91+ NULL , // Use parent's starting directory
92+ &si, // Pointer to STARTUPINFO structure
93+ &pi)) // Pointer to PROCESS_INFORMATION structure
9494 {
9595 std::cout << " Could not start server: " << GetLastError () << std::endl;
9696 return false ;
@@ -136,4 +136,171 @@ bool ServerStartCmd::Exec(const std::string& host, int port,
136136#endif
137137 return true ;
138138}
139+
140+ bool ServerStartCmd::Exec (
141+ const std::optional<std::string>& log_level,
142+ const std::unordered_map<std::string, std::string>& options,
143+ CortexConfig& data) {
144+ for (const auto & [key, value] : options) {
145+ if (!value.empty ()) {
146+ UpdateConfig (data, key, value);
147+ }
148+ }
149+
150+ auto config_path = file_manager_utils::GetConfigurationPath ();
151+ auto result =
152+ config_yaml_utils::CortexConfigMgr::GetInstance ().DumpYamlConfig (
153+ data, config_path.string ());
154+ if (result.has_error ()) {
155+ CTL_WRN (" Error update " << config_path.string () << result.error ());
156+ }
157+ return Exec (data.apiServerHost , std::stoi (data.apiServerPort ), log_level);
158+ }
159+
160+ void ServerStartCmd::UpdateConfig (CortexConfig& data, const std::string& key,
161+ const std::string& value) {
162+ static const std::unordered_map<
163+ std::string, std::function<void (CortexConfig&, const std::string&,
164+ const std::string&)>>
165+ updaters = {
166+ {" logspath" ,
167+ [](CortexConfig& data, const std::string&, const std::string& v) {
168+ data.logFolderPath = v;
169+ }},
170+ {" logsllama" ,
171+ [](CortexConfig& data, const std::string&, const std::string& v) {
172+ data.logLlamaCppPath = v;
173+ }},
174+ {" logsonnx" ,
175+ [](CortexConfig& data, const std::string&, const std::string& v) {
176+ data.logOnnxPath = v;
177+ }},
178+ {" loglines" ,
179+ [this ](CortexConfig& data, const std::string& k,
180+ const std::string& v) {
181+ UpdateNumericField (k, v, [&data](float f) {
182+ data.maxLogLines = static_cast <int >(f);
183+ });
184+ }},
185+ {" host" ,
186+ [](CortexConfig& data, const std::string&, const std::string& v) {
187+ data.apiServerHost = v;
188+ }},
189+ {" port" ,
190+ [](CortexConfig& data, const std::string& k, const std::string& v) {
191+ data.apiServerPort = v;
192+ }},
193+ {" hf-token" ,
194+ [](CortexConfig& data, const std::string&, const std::string& v) {
195+ data.huggingFaceToken = v;
196+ }},
197+ {" gh-agent" ,
198+ [](CortexConfig& data, const std::string&, const std::string& v) {
199+ data.gitHubUserAgent = v;
200+ }},
201+ {" gh-token" ,
202+ [](CortexConfig& data, const std::string&, const std::string& v) {
203+ data.gitHubToken = v;
204+ }},
205+ {" cors" ,
206+ [this ](CortexConfig& data, const std::string& k,
207+ const std::string& v) {
208+ UpdateBooleanField (k, v, [&data](bool b) { data.enableCors = b; });
209+ }},
210+ {" origins" ,
211+ [this ](CortexConfig& data, const std::string& k,
212+ const std::string& v) {
213+ UpdateVectorField (k, v,
214+ [&data](const std::vector<std::string>& orgs) {
215+ data.allowedOrigins = orgs;
216+ });
217+ }},
218+ {" proxy-url" ,
219+ [](CortexConfig& data, const std::string&, const std::string& v) {
220+ data.proxyUrl = v;
221+ }},
222+ {" verify-proxy" ,
223+ [this ](CortexConfig& data, const std::string& k,
224+ const std::string& v) {
225+ UpdateBooleanField (k, v,
226+ [&data](bool b) { data.verifyProxySsl = b; });
227+ }},
228+ {" verify-proxy-host" ,
229+ [this ](CortexConfig& data, const std::string& k,
230+ const std::string& v) {
231+ UpdateBooleanField (
232+ k, v, [&data](bool b) { data.verifyProxyHostSsl = b; });
233+ }},
234+ {" proxy-username" ,
235+ [](CortexConfig& data, const std::string&, const std::string& v) {
236+ data.proxyUsername = v;
237+ }},
238+ {" proxy-password" ,
239+ [](CortexConfig& data, const std::string&, const std::string& v) {
240+ data.proxyPassword = v;
241+ }},
242+ {" no-proxy" ,
243+ [](CortexConfig& data, const std::string&, const std::string& v) {
244+ data.noProxy = v;
245+ }},
246+ {" verify-ssl-peer" ,
247+ [this ](CortexConfig& data, const std::string& k,
248+ const std::string& v) {
249+ UpdateBooleanField (k, v,
250+ [&data](bool b) { data.verifyPeerSsl = b; });
251+ }},
252+ {" verify-ssl-host" ,
253+ [this ](CortexConfig& data, const std::string& k,
254+ const std::string& v) {
255+ UpdateBooleanField (k, v,
256+ [&data](bool b) { data.verifyHostSsl = b; });
257+ }},
258+ {" ssl-cert-path" ,
259+ [](CortexConfig& data, const std::string&, const std::string& v) {
260+ data.sslCertPath = v;
261+ }},
262+ {" ssl-key-path" ,
263+ [](CortexConfig& data, const std::string&, const std::string& v) {
264+ data.sslKeyPath = v;
265+ }},
266+ };
267+
268+ if (auto it = updaters.find (key); it != updaters.end ()) {
269+ it->second (data, key, value);
270+ CTL_INF (" Updated " << key << " to: " << value);
271+ } else {
272+ CTL_WRN (" Warning: Unknown configuration key '" << key << " ' ignored." );
273+ }
274+ }
275+
276+ void ServerStartCmd::UpdateVectorField (
277+ const std::string& key, const std::string& value,
278+ std::function<void (const std::vector<std::string>&)> setter) {
279+ std::vector<std::string> tokens;
280+ std::istringstream iss (value);
281+ std::string token;
282+ while (std::getline (iss, token, ' ,' )) {
283+ tokens.push_back (token);
284+ }
285+ setter (tokens);
286+ }
287+
288+ void ServerStartCmd::UpdateNumericField (const std::string& key,
289+ const std::string& value,
290+ std::function<void (float )> setter) {
291+ try {
292+ float numeric_val = std::stof (value);
293+ setter (numeric_val);
294+ } catch (const std::exception& e) {
295+ CLI_LOG (" Failed to parse numeric value for " << key << " : " << e.what ());
296+ }
297+ }
298+
299+ void ServerStartCmd::UpdateBooleanField (const std::string& key,
300+ const std::string& value,
301+ std::function<void (bool )> setter) {
302+ bool bool_value = (value == " true" || value == " 1" );
303+ setter (bool_value);
304+ }
305+
139306}; // namespace commands
0 commit comments