#include "metrics_protocol.h" #include #include #include static int clamp_percent(int value) { if (value < 0) { return 0; } if (value > 100) { return 100; } return value; } static bool parse_int_token(char **cursor, int *out) { char *token = strsep(cursor, ","); if (token == NULL || token[0] == '\0') { return false; } char *end = NULL; long value = strtol(token, &end, 10); if (end == token || *end != '\0') { return false; } *out = (int)value; return true; } static void set_disk_text(ui_metrics_t *metrics, const char *disk_text) { if (disk_text == NULL || disk_text[0] == '\0') { metrics->disk_text[0] = '\0'; return; } snprintf(metrics->disk_text, sizeof(metrics->disk_text), "%s", disk_text); } static void set_cpu_core_text(ui_metrics_t *metrics, const char *core_text) { if (core_text == NULL || core_text[0] == '\0') { metrics->cpu_core_text[0] = '\0'; return; } snprintf(metrics->cpu_core_text, sizeof(metrics->cpu_core_text), "%s", core_text); } static void set_optional_defaults(ui_metrics_t *metrics) { metrics->cpu_core_text[0] = '\0'; metrics->codex_5h_percent = -1; metrics->codex_week_percent = -1; metrics->codex_5h_reset_mins = -1; metrics->codex_week_reset_mins = -1; metrics->codex_reset_credits = -1; metrics->codex_today_tokens_m10 = -1; metrics->codex_daily_count = 0; for (int i = 0; i < UI_CODEX_DAILY_BAR_COUNT; i++) { metrics->codex_daily_percent[i] = -1; } metrics->zhipu_status = 0; metrics->zhipu_quota_percent = -1; metrics->zhipu_latency_ms = -1; metrics->zhipu_5h_percent = -1; metrics->zhipu_week_percent = -1; metrics->zhipu_5h_reset_mins = -1; metrics->zhipu_week_reset_mins = -1; metrics->zhipu_today_tokens_m10 = -1; metrics->zhipu_daily_count = 0; for (int i = 0; i < UI_ZHIPU_DAILY_BAR_COUNT; i++) { metrics->zhipu_daily_percent[i] = -1; } } static void parse_codex_daily_bars(ui_metrics_t *metrics, const char *daily_text) { metrics->codex_daily_count = 0; for (int i = 0; i < UI_CODEX_DAILY_BAR_COUNT; i++) { metrics->codex_daily_percent[i] = -1; } if (daily_text == NULL || daily_text[0] == '\0') { return; } char buffer[96]; snprintf(buffer, sizeof(buffer), "%s", daily_text); char *cursor = buffer; char *token = NULL; while ((token = strsep(&cursor, ":")) != NULL && metrics->codex_daily_count < UI_CODEX_DAILY_BAR_COUNT) { if (token[0] == '\0') { continue; } char *end = NULL; long value = strtol(token, &end, 10); if (end == token || *end != '\0') { continue; } metrics->codex_daily_percent[metrics->codex_daily_count] = clamp_percent((int)value); metrics->codex_daily_count++; } } static void parse_zhipu_daily_bars(ui_metrics_t *metrics, const char *daily_text) { metrics->zhipu_daily_count = 0; for (int i = 0; i < UI_ZHIPU_DAILY_BAR_COUNT; i++) { metrics->zhipu_daily_percent[i] = -1; } if (daily_text == NULL || daily_text[0] == '\0') { return; } char buffer[96]; snprintf(buffer, sizeof(buffer), "%s", daily_text); char *cursor = buffer; char *token = NULL; while ((token = strsep(&cursor, ":")) != NULL && metrics->zhipu_daily_count < UI_ZHIPU_DAILY_BAR_COUNT) { if (token[0] == '\0') { continue; } char *end = NULL; long value = strtol(token, &end, 10); if (end == token || *end != '\0') { continue; } metrics->zhipu_daily_percent[metrics->zhipu_daily_count] = clamp_percent((int)value); metrics->zhipu_daily_count++; } } static bool parse_sys2_line(const char *line, ui_metrics_t *metrics) { char buffer[320]; snprintf(buffer, sizeof(buffer), "%s", line); char *cursor = buffer; char *tag = strsep(&cursor, ","); if (tag == NULL || strcmp(tag, "SYS2") != 0) { return false; } int cpu = 0; int cpu_mhz = 0; int mem = 0; int mem_used = 0; int mem_total = 0; int disk_count = 0; int disk_percent = 0; int disk_read = 0; int disk_write = 0; int rx = 0; int tx = 0; if (!parse_int_token(&cursor, &cpu) || !parse_int_token(&cursor, &cpu_mhz) || !parse_int_token(&cursor, &mem) || !parse_int_token(&cursor, &mem_used) || !parse_int_token(&cursor, &mem_total) || !parse_int_token(&cursor, &disk_count) || !parse_int_token(&cursor, &disk_percent) || !parse_int_token(&cursor, &disk_read) || !parse_int_token(&cursor, &disk_write) || !parse_int_token(&cursor, &rx) || !parse_int_token(&cursor, &tx)) { return false; } metrics->cpu_percent = clamp_percent(cpu); metrics->cpu_mhz = cpu_mhz; metrics->memory_percent = clamp_percent(mem); metrics->memory_used_mb = mem_used; metrics->memory_total_mb = mem_total; metrics->disk_count = disk_count; metrics->disk_percent = clamp_percent(disk_percent); metrics->disk_read_kbps = disk_read; metrics->disk_write_kbps = disk_write; metrics->rx_kbps = rx; metrics->tx_kbps = tx; set_disk_text(metrics, cursor); return true; } static bool parse_sys3_line(const char *line, ui_metrics_t *metrics) { char buffer[384]; snprintf(buffer, sizeof(buffer), "%s", line); char *cursor = buffer; char *tag = strsep(&cursor, ","); if (tag == NULL || strcmp(tag, "SYS3") != 0) { return false; } int cpu = 0; int cpu_mhz = 0; int mem = 0; int mem_used = 0; int mem_total = 0; int disk_count = 0; int disk_percent = 0; int disk_read = 0; int disk_write = 0; int rx = 0; int tx = 0; int codex_5h = -1; int codex_week = -1; int codex_5h_reset = -1; int codex_week_reset = -1; int codex_credits = -1; int zhipu_status = 0; int zhipu_quota = -1; int zhipu_latency = -1; if (!parse_int_token(&cursor, &cpu) || !parse_int_token(&cursor, &cpu_mhz) || !parse_int_token(&cursor, &mem) || !parse_int_token(&cursor, &mem_used) || !parse_int_token(&cursor, &mem_total) || !parse_int_token(&cursor, &disk_count) || !parse_int_token(&cursor, &disk_percent) || !parse_int_token(&cursor, &disk_read) || !parse_int_token(&cursor, &disk_write) || !parse_int_token(&cursor, &rx) || !parse_int_token(&cursor, &tx) || !parse_int_token(&cursor, &codex_5h) || !parse_int_token(&cursor, &codex_week) || !parse_int_token(&cursor, &codex_5h_reset) || !parse_int_token(&cursor, &codex_week_reset) || !parse_int_token(&cursor, &codex_credits) || !parse_int_token(&cursor, &zhipu_status) || !parse_int_token(&cursor, &zhipu_quota) || !parse_int_token(&cursor, &zhipu_latency)) { return false; } metrics->cpu_percent = clamp_percent(cpu); metrics->cpu_mhz = cpu_mhz; metrics->memory_percent = clamp_percent(mem); metrics->memory_used_mb = mem_used; metrics->memory_total_mb = mem_total; metrics->disk_count = disk_count; metrics->disk_percent = clamp_percent(disk_percent); metrics->disk_read_kbps = disk_read; metrics->disk_write_kbps = disk_write; metrics->rx_kbps = rx; metrics->tx_kbps = tx; metrics->codex_5h_percent = (codex_5h >= 0) ? clamp_percent(codex_5h) : -1; metrics->codex_week_percent = (codex_week >= 0) ? clamp_percent(codex_week) : -1; metrics->codex_5h_reset_mins = codex_5h_reset; metrics->codex_week_reset_mins = codex_week_reset; metrics->codex_reset_credits = codex_credits; metrics->zhipu_status = zhipu_status; metrics->zhipu_quota_percent = (zhipu_quota >= 0) ? clamp_percent(zhipu_quota) : -1; metrics->zhipu_latency_ms = zhipu_latency; metrics->zhipu_5h_percent = metrics->zhipu_quota_percent; metrics->zhipu_week_percent = -1; metrics->zhipu_5h_reset_mins = -1; metrics->zhipu_week_reset_mins = -1; set_disk_text(metrics, cursor); return true; } static bool parse_sys4_line(const char *line, ui_metrics_t *metrics) { char buffer[384]; snprintf(buffer, sizeof(buffer), "%s", line); char *cursor = buffer; char *tag = strsep(&cursor, ","); if (tag == NULL || strcmp(tag, "SYS4") != 0) { return false; } int cpu = 0; int cpu_mhz = 0; int mem = 0; int mem_used = 0; int mem_total = 0; int disk_count = 0; int disk_percent = 0; int disk_read = 0; int disk_write = 0; int rx = 0; int tx = 0; int codex_5h = -1; int codex_week = -1; int codex_5h_reset = -1; int codex_week_reset = -1; int codex_credits = -1; int zhipu_status = 0; int zhipu_5h = -1; int zhipu_week = -1; int zhipu_5h_reset = -1; int zhipu_week_reset = -1; if (!parse_int_token(&cursor, &cpu) || !parse_int_token(&cursor, &cpu_mhz) || !parse_int_token(&cursor, &mem) || !parse_int_token(&cursor, &mem_used) || !parse_int_token(&cursor, &mem_total) || !parse_int_token(&cursor, &disk_count) || !parse_int_token(&cursor, &disk_percent) || !parse_int_token(&cursor, &disk_read) || !parse_int_token(&cursor, &disk_write) || !parse_int_token(&cursor, &rx) || !parse_int_token(&cursor, &tx) || !parse_int_token(&cursor, &codex_5h) || !parse_int_token(&cursor, &codex_week) || !parse_int_token(&cursor, &codex_5h_reset) || !parse_int_token(&cursor, &codex_week_reset) || !parse_int_token(&cursor, &codex_credits) || !parse_int_token(&cursor, &zhipu_status) || !parse_int_token(&cursor, &zhipu_5h) || !parse_int_token(&cursor, &zhipu_week) || !parse_int_token(&cursor, &zhipu_5h_reset) || !parse_int_token(&cursor, &zhipu_week_reset)) { return false; } metrics->cpu_percent = clamp_percent(cpu); metrics->cpu_mhz = cpu_mhz; metrics->memory_percent = clamp_percent(mem); metrics->memory_used_mb = mem_used; metrics->memory_total_mb = mem_total; metrics->disk_count = disk_count; metrics->disk_percent = clamp_percent(disk_percent); metrics->disk_read_kbps = disk_read; metrics->disk_write_kbps = disk_write; metrics->rx_kbps = rx; metrics->tx_kbps = tx; metrics->codex_5h_percent = (codex_5h >= 0) ? clamp_percent(codex_5h) : -1; metrics->codex_week_percent = (codex_week >= 0) ? clamp_percent(codex_week) : -1; metrics->codex_5h_reset_mins = codex_5h_reset; metrics->codex_week_reset_mins = codex_week_reset; metrics->codex_reset_credits = codex_credits; metrics->zhipu_status = zhipu_status; metrics->zhipu_5h_percent = (zhipu_5h >= 0) ? clamp_percent(zhipu_5h) : -1; metrics->zhipu_week_percent = (zhipu_week >= 0) ? clamp_percent(zhipu_week) : -1; metrics->zhipu_5h_reset_mins = zhipu_5h_reset; metrics->zhipu_week_reset_mins = zhipu_week_reset; metrics->zhipu_quota_percent = metrics->zhipu_5h_percent; metrics->zhipu_latency_ms = -1; set_disk_text(metrics, cursor); return true; } static bool parse_sys5_line(const char *line, ui_metrics_t *metrics) { char buffer[384]; snprintf(buffer, sizeof(buffer), "%s", line); char *cursor = buffer; char *tag = strsep(&cursor, ","); if (tag == NULL || strcmp(tag, "SYS5") != 0) { return false; } int cpu = 0; int cpu_mhz = 0; int mem = 0; int mem_used = 0; int mem_total = 0; int disk_count = 0; int disk_percent = 0; int disk_read = 0; int disk_write = 0; int rx = 0; int tx = 0; int codex_5h = -1; int codex_week = -1; int codex_5h_reset = -1; int codex_week_reset = -1; int codex_credits = -1; int codex_today_tokens_m10 = -1; int zhipu_status = 0; int zhipu_5h = -1; int zhipu_week = -1; int zhipu_5h_reset = -1; int zhipu_week_reset = -1; if (!parse_int_token(&cursor, &cpu) || !parse_int_token(&cursor, &cpu_mhz) || !parse_int_token(&cursor, &mem) || !parse_int_token(&cursor, &mem_used) || !parse_int_token(&cursor, &mem_total) || !parse_int_token(&cursor, &disk_count) || !parse_int_token(&cursor, &disk_percent) || !parse_int_token(&cursor, &disk_read) || !parse_int_token(&cursor, &disk_write) || !parse_int_token(&cursor, &rx) || !parse_int_token(&cursor, &tx) || !parse_int_token(&cursor, &codex_5h) || !parse_int_token(&cursor, &codex_week) || !parse_int_token(&cursor, &codex_5h_reset) || !parse_int_token(&cursor, &codex_week_reset) || !parse_int_token(&cursor, &codex_credits) || !parse_int_token(&cursor, &codex_today_tokens_m10) || !parse_int_token(&cursor, &zhipu_status) || !parse_int_token(&cursor, &zhipu_5h) || !parse_int_token(&cursor, &zhipu_week) || !parse_int_token(&cursor, &zhipu_5h_reset) || !parse_int_token(&cursor, &zhipu_week_reset)) { return false; } metrics->cpu_percent = clamp_percent(cpu); metrics->cpu_mhz = cpu_mhz; metrics->memory_percent = clamp_percent(mem); metrics->memory_used_mb = mem_used; metrics->memory_total_mb = mem_total; metrics->disk_count = disk_count; metrics->disk_percent = clamp_percent(disk_percent); metrics->disk_read_kbps = disk_read; metrics->disk_write_kbps = disk_write; metrics->rx_kbps = rx; metrics->tx_kbps = tx; metrics->codex_5h_percent = (codex_5h >= 0) ? clamp_percent(codex_5h) : -1; metrics->codex_week_percent = (codex_week >= 0) ? clamp_percent(codex_week) : -1; metrics->codex_5h_reset_mins = codex_5h_reset; metrics->codex_week_reset_mins = codex_week_reset; metrics->codex_reset_credits = codex_credits; metrics->codex_today_tokens_m10 = codex_today_tokens_m10; metrics->zhipu_status = zhipu_status; metrics->zhipu_5h_percent = (zhipu_5h >= 0) ? clamp_percent(zhipu_5h) : -1; metrics->zhipu_week_percent = (zhipu_week >= 0) ? clamp_percent(zhipu_week) : -1; metrics->zhipu_5h_reset_mins = zhipu_5h_reset; metrics->zhipu_week_reset_mins = zhipu_week_reset; metrics->zhipu_quota_percent = metrics->zhipu_5h_percent; metrics->zhipu_latency_ms = -1; set_disk_text(metrics, cursor); return true; } static bool parse_sys6_line(const char *line, ui_metrics_t *metrics) { char buffer[512]; snprintf(buffer, sizeof(buffer), "%s", line); char *cursor = buffer; char *tag = strsep(&cursor, ","); if (tag == NULL || strcmp(tag, "SYS6") != 0) { return false; } int cpu = 0; int cpu_mhz = 0; int mem = 0; int mem_used = 0; int mem_total = 0; int disk_count = 0; int disk_percent = 0; int disk_read = 0; int disk_write = 0; int rx = 0; int tx = 0; int codex_5h = -1; int codex_week = -1; int codex_5h_reset = -1; int codex_week_reset = -1; int codex_credits = -1; int codex_today_tokens_m10 = -1; int zhipu_status = 0; int zhipu_5h = -1; int zhipu_week = -1; int zhipu_5h_reset = -1; int zhipu_week_reset = -1; if (!parse_int_token(&cursor, &cpu) || !parse_int_token(&cursor, &cpu_mhz) || !parse_int_token(&cursor, &mem) || !parse_int_token(&cursor, &mem_used) || !parse_int_token(&cursor, &mem_total) || !parse_int_token(&cursor, &disk_count) || !parse_int_token(&cursor, &disk_percent) || !parse_int_token(&cursor, &disk_read) || !parse_int_token(&cursor, &disk_write) || !parse_int_token(&cursor, &rx) || !parse_int_token(&cursor, &tx) || !parse_int_token(&cursor, &codex_5h) || !parse_int_token(&cursor, &codex_week) || !parse_int_token(&cursor, &codex_5h_reset) || !parse_int_token(&cursor, &codex_week_reset) || !parse_int_token(&cursor, &codex_credits) || !parse_int_token(&cursor, &codex_today_tokens_m10)) { return false; } char *daily_text = strsep(&cursor, ","); if (daily_text == NULL || !parse_int_token(&cursor, &zhipu_status) || !parse_int_token(&cursor, &zhipu_5h) || !parse_int_token(&cursor, &zhipu_week) || !parse_int_token(&cursor, &zhipu_5h_reset) || !parse_int_token(&cursor, &zhipu_week_reset)) { return false; } metrics->cpu_percent = clamp_percent(cpu); metrics->cpu_mhz = cpu_mhz; metrics->memory_percent = clamp_percent(mem); metrics->memory_used_mb = mem_used; metrics->memory_total_mb = mem_total; metrics->disk_count = disk_count; metrics->disk_percent = clamp_percent(disk_percent); metrics->disk_read_kbps = disk_read; metrics->disk_write_kbps = disk_write; metrics->rx_kbps = rx; metrics->tx_kbps = tx; metrics->codex_5h_percent = (codex_5h >= 0) ? clamp_percent(codex_5h) : -1; metrics->codex_week_percent = (codex_week >= 0) ? clamp_percent(codex_week) : -1; metrics->codex_5h_reset_mins = codex_5h_reset; metrics->codex_week_reset_mins = codex_week_reset; metrics->codex_reset_credits = codex_credits; metrics->codex_today_tokens_m10 = codex_today_tokens_m10; parse_codex_daily_bars(metrics, daily_text); metrics->zhipu_status = zhipu_status; metrics->zhipu_5h_percent = (zhipu_5h >= 0) ? clamp_percent(zhipu_5h) : -1; metrics->zhipu_week_percent = (zhipu_week >= 0) ? clamp_percent(zhipu_week) : -1; metrics->zhipu_5h_reset_mins = zhipu_5h_reset; metrics->zhipu_week_reset_mins = zhipu_week_reset; metrics->zhipu_quota_percent = metrics->zhipu_5h_percent; metrics->zhipu_latency_ms = -1; set_disk_text(metrics, cursor); return true; } static bool parse_sys7_line(const char *line, ui_metrics_t *metrics) { char buffer[640]; snprintf(buffer, sizeof(buffer), "%s", line); char *cursor = buffer; char *tag = strsep(&cursor, ","); if (tag == NULL || strcmp(tag, "SYS7") != 0) { return false; } int cpu = 0; int cpu_mhz = 0; int mem = 0; int mem_used = 0; int mem_total = 0; int disk_count = 0; int disk_percent = 0; int disk_read = 0; int disk_write = 0; int rx = 0; int tx = 0; int codex_5h = -1; int codex_week = -1; int codex_5h_reset = -1; int codex_week_reset = -1; int codex_credits = -1; int codex_today_tokens_m10 = -1; int zhipu_status = 0; int zhipu_5h = -1; int zhipu_week = -1; int zhipu_5h_reset = -1; int zhipu_week_reset = -1; if (!parse_int_token(&cursor, &cpu) || !parse_int_token(&cursor, &cpu_mhz) || !parse_int_token(&cursor, &mem) || !parse_int_token(&cursor, &mem_used) || !parse_int_token(&cursor, &mem_total) || !parse_int_token(&cursor, &disk_count) || !parse_int_token(&cursor, &disk_percent) || !parse_int_token(&cursor, &disk_read) || !parse_int_token(&cursor, &disk_write) || !parse_int_token(&cursor, &rx) || !parse_int_token(&cursor, &tx) || !parse_int_token(&cursor, &codex_5h) || !parse_int_token(&cursor, &codex_week) || !parse_int_token(&cursor, &codex_5h_reset) || !parse_int_token(&cursor, &codex_week_reset) || !parse_int_token(&cursor, &codex_credits) || !parse_int_token(&cursor, &codex_today_tokens_m10)) { return false; } char *daily_text = strsep(&cursor, ","); if (daily_text == NULL || !parse_int_token(&cursor, &zhipu_status) || !parse_int_token(&cursor, &zhipu_5h) || !parse_int_token(&cursor, &zhipu_week) || !parse_int_token(&cursor, &zhipu_5h_reset) || !parse_int_token(&cursor, &zhipu_week_reset)) { return false; } char *core_text = strsep(&cursor, ","); if (core_text == NULL) { return false; } metrics->cpu_percent = clamp_percent(cpu); metrics->cpu_mhz = cpu_mhz; metrics->memory_percent = clamp_percent(mem); metrics->memory_used_mb = mem_used; metrics->memory_total_mb = mem_total; metrics->disk_count = disk_count; metrics->disk_percent = clamp_percent(disk_percent); metrics->disk_read_kbps = disk_read; metrics->disk_write_kbps = disk_write; metrics->rx_kbps = rx; metrics->tx_kbps = tx; metrics->codex_5h_percent = (codex_5h >= 0) ? clamp_percent(codex_5h) : -1; metrics->codex_week_percent = (codex_week >= 0) ? clamp_percent(codex_week) : -1; metrics->codex_5h_reset_mins = codex_5h_reset; metrics->codex_week_reset_mins = codex_week_reset; metrics->codex_reset_credits = codex_credits; metrics->codex_today_tokens_m10 = codex_today_tokens_m10; parse_codex_daily_bars(metrics, daily_text); metrics->zhipu_status = zhipu_status; metrics->zhipu_5h_percent = (zhipu_5h >= 0) ? clamp_percent(zhipu_5h) : -1; metrics->zhipu_week_percent = (zhipu_week >= 0) ? clamp_percent(zhipu_week) : -1; metrics->zhipu_5h_reset_mins = zhipu_5h_reset; metrics->zhipu_week_reset_mins = zhipu_week_reset; metrics->zhipu_quota_percent = metrics->zhipu_5h_percent; metrics->zhipu_latency_ms = -1; set_cpu_core_text(metrics, core_text); set_disk_text(metrics, cursor); return true; } static bool parse_sys8_line(const char *line, ui_metrics_t *metrics) { char buffer[768]; snprintf(buffer, sizeof(buffer), "%s", line); char *cursor = buffer; char *tag = strsep(&cursor, ","); if (tag == NULL || strcmp(tag, "SYS8") != 0) { return false; } int cpu = 0; int cpu_mhz = 0; int mem = 0; int mem_used = 0; int mem_total = 0; int disk_count = 0; int disk_percent = 0; int disk_read = 0; int disk_write = 0; int rx = 0; int tx = 0; int codex_5h = -1; int codex_week = -1; int codex_5h_reset = -1; int codex_week_reset = -1; int codex_credits = -1; int codex_today_tokens_m10 = -1; int zhipu_status = 0; int zhipu_5h = -1; int zhipu_week = -1; int zhipu_5h_reset = -1; int zhipu_week_reset = -1; int zhipu_today_tokens_m10 = -1; if (!parse_int_token(&cursor, &cpu) || !parse_int_token(&cursor, &cpu_mhz) || !parse_int_token(&cursor, &mem) || !parse_int_token(&cursor, &mem_used) || !parse_int_token(&cursor, &mem_total) || !parse_int_token(&cursor, &disk_count) || !parse_int_token(&cursor, &disk_percent) || !parse_int_token(&cursor, &disk_read) || !parse_int_token(&cursor, &disk_write) || !parse_int_token(&cursor, &rx) || !parse_int_token(&cursor, &tx) || !parse_int_token(&cursor, &codex_5h) || !parse_int_token(&cursor, &codex_week) || !parse_int_token(&cursor, &codex_5h_reset) || !parse_int_token(&cursor, &codex_week_reset) || !parse_int_token(&cursor, &codex_credits) || !parse_int_token(&cursor, &codex_today_tokens_m10)) { return false; } char *codex_daily_text = strsep(&cursor, ","); if (codex_daily_text == NULL || !parse_int_token(&cursor, &zhipu_status) || !parse_int_token(&cursor, &zhipu_5h) || !parse_int_token(&cursor, &zhipu_week) || !parse_int_token(&cursor, &zhipu_5h_reset) || !parse_int_token(&cursor, &zhipu_week_reset) || !parse_int_token(&cursor, &zhipu_today_tokens_m10)) { return false; } char *zhipu_daily_text = strsep(&cursor, ","); if (zhipu_daily_text == NULL) { return false; } char *core_text = strsep(&cursor, ","); if (core_text == NULL) { return false; } metrics->cpu_percent = clamp_percent(cpu); metrics->cpu_mhz = cpu_mhz; metrics->memory_percent = clamp_percent(mem); metrics->memory_used_mb = mem_used; metrics->memory_total_mb = mem_total; metrics->disk_count = disk_count; metrics->disk_percent = clamp_percent(disk_percent); metrics->disk_read_kbps = disk_read; metrics->disk_write_kbps = disk_write; metrics->rx_kbps = rx; metrics->tx_kbps = tx; metrics->codex_5h_percent = (codex_5h >= 0) ? clamp_percent(codex_5h) : -1; metrics->codex_week_percent = (codex_week >= 0) ? clamp_percent(codex_week) : -1; metrics->codex_5h_reset_mins = codex_5h_reset; metrics->codex_week_reset_mins = codex_week_reset; metrics->codex_reset_credits = codex_credits; metrics->codex_today_tokens_m10 = codex_today_tokens_m10; parse_codex_daily_bars(metrics, codex_daily_text); metrics->zhipu_status = zhipu_status; metrics->zhipu_5h_percent = (zhipu_5h >= 0) ? clamp_percent(zhipu_5h) : -1; metrics->zhipu_week_percent = (zhipu_week >= 0) ? clamp_percent(zhipu_week) : -1; metrics->zhipu_5h_reset_mins = zhipu_5h_reset; metrics->zhipu_week_reset_mins = zhipu_week_reset; metrics->zhipu_today_tokens_m10 = zhipu_today_tokens_m10; parse_zhipu_daily_bars(metrics, zhipu_daily_text); metrics->zhipu_quota_percent = metrics->zhipu_5h_percent; metrics->zhipu_latency_ms = -1; set_cpu_core_text(metrics, core_text); set_disk_text(metrics, cursor); return true; } static bool parse_legacy_sys_line(const char *line, ui_metrics_t *metrics) { int cpu = 0; int mem = 0; int disk = 0; int rx = 0; int tx = 0; int matched = sscanf(line, "SYS,%d,%d,%d,%d,%d", &cpu, &mem, &disk, &rx, &tx); if (matched != 5) { return false; } metrics->cpu_percent = clamp_percent(cpu); metrics->cpu_mhz = 0; metrics->memory_percent = clamp_percent(mem); metrics->memory_used_mb = 0; metrics->memory_total_mb = 0; metrics->disk_percent = clamp_percent(disk); metrics->disk_read_kbps = 0; metrics->disk_write_kbps = 0; metrics->rx_kbps = rx; metrics->tx_kbps = tx; metrics->disk_count = 1; snprintf(metrics->disk_text, sizeof(metrics->disk_text), "C:%d:-1:-1", metrics->disk_percent); return true; } bool metrics_parse_line(const char *line, ui_metrics_t *metrics) { if (line == NULL || metrics == NULL) { return false; } memset(metrics, 0, sizeof(*metrics)); set_optional_defaults(metrics); if (strncmp(line, "SYS8,", 5) == 0) { return parse_sys8_line(line, metrics); } if (strncmp(line, "SYS7,", 5) == 0) { return parse_sys7_line(line, metrics); } if (strncmp(line, "SYS6,", 5) == 0) { return parse_sys6_line(line, metrics); } if (strncmp(line, "SYS5,", 5) == 0) { return parse_sys5_line(line, metrics); } if (strncmp(line, "SYS4,", 5) == 0) { return parse_sys4_line(line, metrics); } if (strncmp(line, "SYS3,", 5) == 0) { return parse_sys3_line(line, metrics); } if (strncmp(line, "SYS2,", 5) == 0) { return parse_sys2_line(line, metrics); } return parse_legacy_sys_line(line, metrics); }