Skip to content

Commit 9906d57

Browse files
server: add WebUI config via CLI and env var
- Add --webui-config-file and LLAMA_WEBUI_CONFIG to configure - WebUI defaults from server side. Exposes webui_settings in - /props for both router and child modes Completes TODO placeholder in server-models.cpp
1 parent 254098a commit 9906d57

File tree

5 files changed

+87
-0
lines changed

5 files changed

+87
-0
lines changed

common/arg.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2493,6 +2493,13 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
24932493
params.api_prefix = value;
24942494
}
24952495
).set_examples({LLAMA_EXAMPLE_SERVER}).set_env("LLAMA_ARG_API_PREFIX"));
2496+
add_opt(common_arg(
2497+
{"--webui-config-file"}, "PATH",
2498+
"JSON file that provides default WebUI settings (overrides WebUI defaults; can be overridden by LLAMA_WEBUI_CONFIG)",
2499+
[](common_params & params, const std::string & value) {
2500+
params.webui_config_file = value;
2501+
}
2502+
).set_examples({LLAMA_EXAMPLE_SERVER}));
24962503
add_opt(common_arg(
24972504
{"--webui"},
24982505
{"--no-webui"},

common/common.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include <vector>
1313
#include <map>
1414

15+
#include <nlohmann/json.hpp>
16+
1517
#if defined(_WIN32) && !defined(_WIN32_WINNT)
1618
#define _WIN32_WINNT 0x0A00
1719
#endif
@@ -482,6 +484,8 @@ struct common_params {
482484

483485
// "advanced" endpoints are disabled by default for better security
484486
bool webui = true;
487+
std::string webui_config_file;
488+
nlohmann::ordered_json webui_config = nlohmann::ordered_json::object();
485489
bool endpoint_slots = true;
486490
bool endpoint_props = false; // only control POST requests, not GET
487491
bool endpoint_metrics = false;

tools/server/server-context.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3117,6 +3117,7 @@ void server_routes::init_routes() {
31173117
{ "endpoint_props", params.endpoint_props },
31183118
{ "endpoint_metrics", params.endpoint_metrics },
31193119
{ "webui", params.webui },
3120+
{ "webui_settings", params.webui_config },
31203121
{ "chat_template", common_chat_templates_source(ctx_server.chat_templates.get()) },
31213122
{ "bos_token", common_token_to_piece(ctx_server.ctx, llama_vocab_bos(ctx_server.vocab), /* special= */ true)},
31223123
{ "eos_token", common_token_to_piece(ctx_server.ctx, llama_vocab_eos(ctx_server.vocab), /* special= */ true)},

tools/server/server-models.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,7 @@ void server_models_routes::init_routes() {
822822
{"params", json{}},
823823
{"n_ctx", 0},
824824
}},
825+
{"webui_settings", params.webui_config},
825826
});
826827
return res;
827828
}

tools/server/server.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,24 @@
22
#include "server-http.h"
33
#include "server-models.h"
44

5+
#include "server-common.h"
56
#include "arg.h"
67
#include "common.h"
78
#include "llama.h"
89
#include "log.h"
910

1011
#include <atomic>
12+
#include <cstdlib>
13+
#include <fstream>
1114
#include <signal.h>
1215
#include <thread> // for std::thread::hardware_concurrency
1316

1417
#if defined(_WIN32)
1518
#include <windows.h>
1619
#endif
1720

21+
using json = nlohmann::ordered_json;
22+
1823
static std::function<void(int)> shutdown_handler;
1924
static std::atomic_flag is_terminating = ATOMIC_FLAG_INIT;
2025

@@ -29,6 +34,67 @@ static inline void signal_handler(int signal) {
2934
shutdown_handler(signal);
3035
}
3136

37+
static bool is_valid_webui_setting_value(const json & value) {
38+
return value.is_boolean() || value.is_number() || value.is_string();
39+
}
40+
41+
static bool merge_webui_settings(const json & overrides, json & target, const std::string & source) {
42+
if (overrides.is_null()) {
43+
return true;
44+
}
45+
46+
if (!overrides.is_object()) {
47+
LOG_ERR("%s must be a JSON object of key/value pairs\n", source.c_str());
48+
return false;
49+
}
50+
51+
for (const auto & [key, value] : overrides.items()) {
52+
if (!is_valid_webui_setting_value(value)) {
53+
LOG_WRN("%s: ignoring '%s' because the value type is not supported (expected string/number/boolean)\n", source.c_str(), key.c_str());
54+
continue;
55+
}
56+
target[key] = value;
57+
}
58+
59+
return true;
60+
}
61+
62+
static bool load_webui_config_from_file(const std::string & path, json & target) {
63+
if (path.empty()) {
64+
return true;
65+
}
66+
67+
std::ifstream file(path);
68+
if (!file.is_open()) {
69+
LOG_WRN("failed to open webui config file '%s', continuing with defaults\n", path.c_str());
70+
return true;
71+
}
72+
73+
try {
74+
json parsed = json::parse(file);
75+
return merge_webui_settings(parsed, target, string_format("webui config file '%s'", path.c_str()));
76+
} catch (const std::exception & e) {
77+
LOG_ERR("failed to parse webui config file '%s' as JSON: %s\n", path.c_str(), e.what());
78+
return false;
79+
}
80+
}
81+
82+
static void merge_webui_config_from_env(json & target) {
83+
const char * env_value = std::getenv("LLAMA_WEBUI_CONFIG");
84+
if (env_value == nullptr) {
85+
return;
86+
}
87+
88+
try {
89+
json parsed = json::parse(env_value);
90+
if (!merge_webui_settings(parsed, target, "LLAMA_WEBUI_CONFIG")) {
91+
LOG_ERR("ignoring LLAMA_WEBUI_CONFIG because it is not a JSON object\n");
92+
}
93+
} catch (const std::exception & e) {
94+
LOG_ERR("failed to parse LLAMA_WEBUI_CONFIG as JSON: %s\n", e.what());
95+
}
96+
}
97+
3298
// wrapper function that handles exceptions and logs errors
3399
// this is to make sure handler_t never throws exceptions; instead, it returns an error response
34100
static server_http_context::handler_t ex_wrapper(server_http_context::handler_t func) {
@@ -73,6 +139,14 @@ int main(int argc, char ** argv, char ** envp) {
73139
return 1;
74140
}
75141

142+
// Merge priority: WebUI built-in defaults -> config file -> LLAMA_WEBUI_CONFIG -> user localStorage
143+
json webui_settings = json::object();
144+
if (!load_webui_config_from_file(params.webui_config_file, webui_settings)) {
145+
return 1;
146+
}
147+
merge_webui_config_from_env(webui_settings);
148+
params.webui_config = std::move(webui_settings);
149+
76150
// TODO: should we have a separate n_parallel parameter for the server?
77151
// https://github.com/ggml-org/llama.cpp/pull/16736#discussion_r2483763177
78152
// TODO: this is a common configuration that is suitable for most local use cases

0 commit comments

Comments
 (0)