Compare commits

..
2 Commits
Author SHA1 Message Date
infosave2007 c1ff675d80 chore: release 0.2.42
Docker / publish (push) Canceled after 0s
Release / crates-io (push) Canceled after 0s
Release / release (macos-14, aarch64-apple-darwin) (push) Canceled after 0s
Release / release (ubuntu-latest, x86_64-unknown-linux-gnu) (push) Canceled after 0s
Release / release (windows-latest, x86_64-pc-windows-msvc) (push) Canceled after 0s
2026-08-08 12:18:04 +03:00
infosave2007 9ef1af3ae1 feat(ui): the continuous complexity score shows next to the tier
Benchmark (routing mode) and the dashboard's recent-requests list now print
the router's raw 0..1 score under/next to the tier badge — people can see
what different prompts actually weigh and tune the boundary sliders from
real data. Tooltip explains the link to the Routing sliders (7 languages).

Caught before commit: naming the field row.score collided with the answer-
correctness fraction from evaluate() and dragged the benchmark's quality KPI
down to the average complexity — renamed to cscore, KPI verified back at
100%. Dashboard tier badges also render translated names now, and the
Russian locale calls the dashboard «Рабочий стол».
2026-08-08 12:11:07 +03:00
12 changed files with 32 additions and 7 deletions
+11
View File
@@ -3,6 +3,17 @@
All notable changes to this project are documented here. All notable changes to this project are documented here.
The format is based on [Keep a Changelog](https://keepachangelog.com/). The format is based on [Keep a Changelog](https://keepachangelog.com/).
## [0.2.42] - 2026-08-08
### Added
- **The continuous complexity score is visible**: the benchmark's routing table and the
dashboard's recent-requests list show the router's raw 0..1 score next to the tier badge —
see what different prompts actually weigh and tune the boundary sliders from real traffic.
### Changed
- Dashboard tier badges render translated tier names; the Russian locale calls the dashboard
«Рабочий стол».
## [0.2.41] - 2026-08-08 ## [0.2.41] - 2026-08-08
### Added ### Added
Generated
+1 -1
View File
@@ -285,7 +285,7 @@ checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
[[package]] [[package]]
name = "cortiq-gateway" name = "cortiq-gateway"
version = "0.2.41" version = "0.2.42"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"arc-swap", "arc-swap",
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "cortiq-gateway" name = "cortiq-gateway"
version = "0.2.41" version = "0.2.42"
edition = "2021" edition = "2021"
rust-version = "1.75" rust-version = "1.75"
license = "Apache-2.0" license = "Apache-2.0"
+1
View File
@@ -634,4 +634,5 @@ export default {
"tier.low": "leicht", "tier.low": "leicht",
"tier.medium": "mittel", "tier.medium": "mittel",
"tier.high": "schwer", "tier.high": "schwer",
"bm.scoreHint": "Der kontinuierliche Komplexitätsscore des Routers (0..1) — die Grenzregler auf der Routing-Seite teilen ihn in Stufen.",
}; };
+1
View File
@@ -627,4 +627,5 @@ export default {
"tier.low": "low", "tier.low": "low",
"tier.medium": "medium", "tier.medium": "medium",
"tier.high": "high", "tier.high": "high",
"bm.scoreHint": "The router's continuous complexity score (0..1) — the boundary sliders on the Routing page cut it into tiers.",
}; };
+1
View File
@@ -634,4 +634,5 @@ export default {
"tier.low": "fácil", "tier.low": "fácil",
"tier.medium": "medio", "tier.medium": "medio",
"tier.high": "difícil", "tier.high": "difícil",
"bm.scoreHint": "La puntuación continua de complejidad del router (0..1) — los deslizadores de límites de la página Enrutado la dividen en niveles.",
}; };
+1
View File
@@ -634,4 +634,5 @@ export default {
"tier.low": "facile", "tier.low": "facile",
"tier.medium": "moyen", "tier.medium": "moyen",
"tier.high": "difficile", "tier.high": "difficile",
"bm.scoreHint": "Le score de complexité continu du routeur (0..1) — les curseurs de limites de la page Routage le découpent en niveaux.",
}; };
+3 -2
View File
@@ -25,7 +25,7 @@ export default {
"common.all": "все", "common.all": "все",
// nav // nav
"nav.dashboard": "Дашборд", "nav.dashboard": "Рабочий стол",
"nav.models": "Модели", "nav.models": "Модели",
"nav.import": "Импорт модели", "nav.import": "Импорт модели",
"nav.routing": "Роутинг", "nav.routing": "Роутинг",
@@ -56,7 +56,7 @@ export default {
"login.failed": "Неверный токен администратора.", "login.failed": "Неверный токен администратора.",
// dashboard // dashboard
"dash.title": "Дашборд", "dash.title": "Рабочий стол",
"dash.subtitle": "Трафик в реальном времени, расходы и аналитика роутинга по пулу моделей.", "dash.subtitle": "Трафик в реальном времени, расходы и аналитика роутинга по пулу моделей.",
"dash.clear": "Очистить логи", "dash.clear": "Очистить логи",
"dash.clearConfirm": "Очистить всю статистику и логи? Отменить нельзя.", "dash.clearConfirm": "Очистить всю статистику и логи? Отменить нельзя.",
@@ -626,4 +626,5 @@ export default {
"tier.low": "лёгкий", "tier.low": "лёгкий",
"tier.medium": "средний", "tier.medium": "средний",
"tier.high": "сложный", "tier.high": "сложный",
"bm.scoreHint": "Непрерывный коэффициент сложности роутера (0..1) — ползунки границ на вкладке Роутинг нарезают его на уровни.",
}; };
+1
View File
@@ -634,4 +634,5 @@ export default {
"tier.low": "kolay", "tier.low": "kolay",
"tier.medium": "orta", "tier.medium": "orta",
"tier.high": "zor", "tier.high": "zor",
"bm.scoreHint": "Yönlendiricinin sürekli karmaşıklık puanı (0..1) — Yönlendirme sayfasındaki sınır kaydırıcıları onu katmanlara böler.",
}; };
+1
View File
@@ -634,4 +634,5 @@ export default {
"tier.low": "简单", "tier.low": "简单",
"tier.medium": "中等", "tier.medium": "中等",
"tier.high": "困难", "tier.high": "困难",
"bm.scoreHint": "路由器的连续复杂度得分(0..1)— 路由页面上的边界滑块将其划分为层级。",
}; };
+6 -1
View File
@@ -238,6 +238,7 @@ export async function renderBenchmark() {
info.cost_usd = (info.cost_usd || 0) + (again.cost_usd || 0); info.cost_usd = (info.cost_usd || 0) + (again.cost_usd || 0);
if (again.tier === "high") { if (again.tier === "high") {
info.tier = again.tier; info.tier = again.tier;
info.score = again.score;
info.selected_model = again.selected_model; info.selected_model = again.selected_model;
info.task_label = again.task_label; info.task_label = again.task_label;
info.route_source = again.route_source; info.route_source = again.route_source;
@@ -269,6 +270,8 @@ export async function renderBenchmark() {
|| String(info.route_source || "").includes("degraded"); || String(info.route_source || "").includes("degraded");
row.task = info.task_label || "—"; row.task = info.task_label || "—";
row.tier = info.tier || "—"; row.tier = info.tier || "—";
row.cscore = info.score || 0; // непрерывный коэффициент сложности
// (row.score занят долей правильности ответа из evaluate())
row.chosen = info.selected_model || "—"; row.chosen = info.selected_model || "—";
row.source = info.route_source || "—"; row.source = info.route_source || "—";
row.expected = test.label; // null = classification not judged row.expected = test.label; // null = classification not judged
@@ -402,7 +405,9 @@ export async function renderBenchmark() {
: h("span", { class: r.taskOk ? "" : "err" }, : h("span", { class: r.taskOk ? "" : "err" },
(r.taskOk ? "✓ " : "✗ ") + r.task, (r.taskOk ? "✓ " : "✗ ") + r.task,
r.taskOk ? "" : h("div", { class: "muted small" }, t("bm.expectedLbl") + " " + (r.expected || []).join("/")))), r.taskOk ? "" : h("div", { class: "muted small" }, t("bm.expectedLbl") + " " + (r.expected || []).join("/")))),
h("td", {}, r.tier ? h("span", { class: "badge tier-" + r.tier }, trTier(r.tier)) : "—"), h("td", {},
r.tier ? h("span", { class: "badge tier-" + r.tier }, trTier(r.tier)) : "—",
r.cscore > 0 ? h("div", { class: "muted small mono", title: t("bm.scoreHint") }, r.cscore.toFixed(2)) : null),
h("td", {}, h("td", {},
h("span", { class: "mono small" }, r.chosen || "—"), h("span", { class: "mono small" }, r.chosen || "—"),
r.cost > 0 ? h("div", { class: "muted small" }, moneyEl(r.cost)) : null, r.cost > 0 ? h("div", { class: "muted small" }, moneyEl(r.cost)) : null,
+4 -2
View File
@@ -1,6 +1,6 @@
// Dashboard — KPIs, time-series charts, breakdown, recent requests, health. // Dashboard — KPIs, time-series charts, breakdown, recent requests, health.
import { h, mount, money, moneyEl, num, ms, pct, timeAgo, toast, confirmDialog } from "../ui.js"; import { h, mount, money, moneyEl, num, ms, pct, timeAgo, toast, confirmDialog } from "../ui.js";
import { t } from "../i18n.js"; import { t, trTier } from "../i18n.js";
import { api } from "../api.js"; import { api } from "../api.js";
import { lineChart, barList } from "../charts.js"; import { lineChart, barList } from "../charts.js";
import { SITE_URL } from "../app.js"; import { SITE_URL } from "../app.js";
@@ -271,7 +271,9 @@ function recentTable(rows) {
{}, {},
h("td", { class: "mono" }, timeAgo(r.ts)), h("td", { class: "mono" }, timeAgo(r.ts)),
h("td", {}, r.model_id || "—", r.failover ? h("span", { class: "badge warn", style: "margin-left:6px" }, "fo") : null), h("td", {}, r.model_id || "—", r.failover ? h("span", { class: "badge warn", style: "margin-left:6px" }, "fo") : null),
h("td", {}, r.tier ? h("span", { class: "badge tier-" + r.tier }, r.tier) : "—"), h("td", {},
r.tier ? h("span", { class: "badge tier-" + r.tier }, trTier(r.tier)) : "—",
r.score > 0 ? h("span", { class: "muted small mono", style: "margin-left:6px" }, r.score.toFixed(2)) : null),
h("td", {}, r.task_label || "—"), h("td", {}, r.task_label || "—"),
h("td", { class: "mono" }, `${r.prompt_tokens}/${r.completion_tokens}`), h("td", { class: "mono" }, `${r.prompt_tokens}/${r.completion_tokens}`),
h("td", { class: "mono" }, money(r.cost_usd)), h("td", { class: "mono" }, money(r.cost_usd)),