common : change --color to accept on/off/auto, default to auto (#17827)

This commit is contained in:
Sigbjørn Skjæret 2025-12-07 03:43:50 +01:00 committed by GitHub
parent d9e03db1e7
commit 22577583a3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 54 additions and 32 deletions

View File

@ -708,6 +708,8 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
params.use_jinja = true; params.use_jinja = true;
} }
params.use_color = tty_can_use_colors();
// load dynamic backends // load dynamic backends
ggml_backend_load_all(); ggml_backend_load_all();
@ -790,10 +792,20 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
} }
).set_examples({LLAMA_EXAMPLE_MAIN})); ).set_examples({LLAMA_EXAMPLE_MAIN}));
add_opt(common_arg( add_opt(common_arg(
{"-co", "--color"}, {"-co", "--color"}, "[on|off|auto]",
string_format("colorise output to distinguish prompt and user input from generations (default: %s)", params.use_color ? "true" : "false"), "Colorize output to distinguish prompt and user input from generations ('on', 'off', or 'auto', default: 'auto')\n"
[](common_params & params) { "'auto' enables colors when output is to a terminal",
params.use_color = true; [](common_params & params, const std::string & value) {
if (is_truthy(value)) {
params.use_color = true;
} else if (is_falsey(value)) {
params.use_color = false;
} else if (is_autoy(value)) {
params.use_color = tty_can_use_colors();
} else {
throw std::invalid_argument(
string_format("error: unknown value for --color: '%s'\n", value.c_str()));
}
} }
).set_examples({LLAMA_EXAMPLE_MAIN, LLAMA_EXAMPLE_SPECULATIVE, LLAMA_EXAMPLE_LOOKUP})); ).set_examples({LLAMA_EXAMPLE_MAIN, LLAMA_EXAMPLE_SPECULATIVE, LLAMA_EXAMPLE_LOOKUP}));
add_opt(common_arg( add_opt(common_arg(
@ -1022,7 +1034,7 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
params.flash_attn_type = LLAMA_FLASH_ATTN_TYPE_AUTO; params.flash_attn_type = LLAMA_FLASH_ATTN_TYPE_AUTO;
} else { } else {
throw std::runtime_error( throw std::runtime_error(
string_format("error: unkown value for --flash-attn: '%s'\n", value.c_str())); string_format("error: unknown value for --flash-attn: '%s'\n", value.c_str()));
} }
}).set_env("LLAMA_ARG_FLASH_ATTN")); }).set_env("LLAMA_ARG_FLASH_ATTN"));
add_opt(common_arg( add_opt(common_arg(
@ -2696,7 +2708,7 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
common_log_set_colors(common_log_main(), LOG_COLORS_AUTO); common_log_set_colors(common_log_main(), LOG_COLORS_AUTO);
} else { } else {
throw std::invalid_argument( throw std::invalid_argument(
string_format("error: unkown value for --log-colors: '%s'\n", value.c_str())); string_format("error: unknown value for --log-colors: '%s'\n", value.c_str()));
} }
} }
).set_env("LLAMA_LOG_COLORS")); ).set_env("LLAMA_LOG_COLORS"));

View File

@ -982,6 +982,32 @@ std::vector<common_file_info> fs_list(const std::string & path, bool include_dir
return files; return files;
} }
//
// TTY utils
//
bool tty_can_use_colors() {
// Check NO_COLOR environment variable (https://no-color.org/)
if (const char * no_color = std::getenv("NO_COLOR")) {
if (no_color[0] != '\0') {
return false;
}
}
// Check TERM environment variable
if (const char * term = std::getenv("TERM")) {
if (std::strcmp(term, "dumb") == 0) {
return false;
}
}
// Check if stdout and stderr are connected to a terminal
// We check both because log messages can go to either
bool stdout_is_tty = isatty(fileno(stdout));
bool stderr_is_tty = isatty(fileno(stderr));
return stdout_is_tty || stderr_is_tty;
}
// //
// Model utils // Model utils

View File

@ -655,6 +655,13 @@ struct common_file_info {
}; };
std::vector<common_file_info> fs_list(const std::string & path, bool include_directories); std::vector<common_file_info> fs_list(const std::string & path, bool include_directories);
//
// TTY utils
//
// Auto-detect if colors can be enabled based on terminal and environment
bool tty_can_use_colors();
// //
// Model utils // Model utils
// //

View File

@ -1,3 +1,4 @@
#include "common.h"
#include "log.h" #include "log.h"
#include <chrono> #include <chrono>
@ -26,30 +27,6 @@ void common_log_set_verbosity_thold(int verbosity) {
common_log_verbosity_thold = verbosity; common_log_verbosity_thold = verbosity;
} }
// Auto-detect if colors should be enabled based on terminal and environment
static bool common_log_should_use_colors_auto() {
// Check NO_COLOR environment variable (https://no-color.org/)
if (const char * no_color = std::getenv("NO_COLOR")) {
if (no_color[0] != '\0') {
return false;
}
}
// Check TERM environment variable
if (const char * term = std::getenv("TERM")) {
if (std::strcmp(term, "dumb") == 0) {
return false;
}
}
// Check if stdout and stderr are connected to a terminal
// We check both because log messages can go to either
bool stdout_is_tty = isatty(fileno(stdout));
bool stderr_is_tty = isatty(fileno(stderr));
return stdout_is_tty || stderr_is_tty;
}
static int64_t t_us() { static int64_t t_us() {
return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count(); return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
} }
@ -391,7 +368,7 @@ struct common_log * common_log_main() {
static std::once_flag init_flag; static std::once_flag init_flag;
std::call_once(init_flag, [&]() { std::call_once(init_flag, [&]() {
// Set default to auto-detect colors // Set default to auto-detect colors
log.set_colors(common_log_should_use_colors_auto()); log.set_colors(tty_can_use_colors());
}); });
return &log; return &log;
@ -422,7 +399,7 @@ void common_log_set_file(struct common_log * log, const char * file) {
void common_log_set_colors(struct common_log * log, log_colors colors) { void common_log_set_colors(struct common_log * log, log_colors colors) {
if (colors == LOG_COLORS_AUTO) { if (colors == LOG_COLORS_AUTO) {
log->set_colors(common_log_should_use_colors_auto()); log->set_colors(tty_can_use_colors());
return; return;
} }