From cbc385f6c7c2b3c431e70e04892765b6240b7ebe Mon Sep 17 00:00:00 2001 From: infosave2007 Date: Tue, 30 Jun 2026 10:51:37 +0300 Subject: [PATCH] feat: universal LLM gateway with embedded multilingual admin console - OpenAI-compatible gateway with intelligent routing via cortiq-router (allaigate) - Embedded build-free admin SPA at /admin: 7 languages (en/ru/de/fr/es/zh/tr), light/dark themes, hot config reload (no restart) - Admin API, per-request statistics + Prometheus /metrics, secret store, playground - English documentation (primary) with Russian translations (*.ru.md) --- .gitattributes | 7 + .github/workflows/ci.yml | 24 + .gitignore | 10 + CHANGELOG.md | 35 + CONTRIBUTING.md | 46 + CONTRIBUTING.ru.md | 45 + Cargo.lock | 2162 +++++++++++++++++++++++++++++++ Cargo.toml | 49 + LICENSE | 179 +++ README.md | 222 ++++ README.ru.md | 177 +++ config/gateway.example.toml | 152 +++ docs/ARCHITECTURE.md | 205 +++ docs/ARCHITECTURE.ru.md | 202 +++ docs/PROTOCOLS.md | 324 +++++ docs/PROTOCOLS.ru.md | 321 +++++ docs/ROUTING.md | 164 +++ docs/ROUTING.ru.md | 162 +++ docs/screenshots/dashboard.png | Bin 0 -> 235339 bytes docs/screenshots/models.png | Bin 0 -> 149399 bytes docs/screenshots/playground.png | Bin 0 -> 139977 bytes docs/screenshots/routing.png | Bin 0 -> 142903 bytes src/admin/assets.rs | 58 + src/admin/mod.rs | 756 +++++++++++ src/config.rs | 474 +++++++ src/error.rs | 74 ++ src/main.rs | 107 ++ src/model.rs | 102 ++ src/pipeline.rs | 251 ++++ src/protocols/mod.rs | 17 + src/protocols/openai_chat.rs | 168 +++ src/providers/anthropic.rs | 57 + src/providers/mod.rs | 46 + src/providers/openai.rs | 157 +++ src/registry.rs | 43 + src/router_client.rs | 78 ++ src/routing.rs | 48 + src/secrets.rs | 96 ++ src/state.rs | 107 ++ src/stats.rs | 395 ++++++ web/css/styles.css | 309 +++++ web/favicon.svg | 12 + web/index.html | 24 + web/js/api.js | 93 ++ web/js/app.js | 228 ++++ web/js/charts.js | 56 + web/js/i18n.js | 56 + web/js/i18n/de.js | 256 ++++ web/js/i18n/en.js | 257 ++++ web/js/i18n/es.js | 256 ++++ web/js/i18n/fr.js | 256 ++++ web/js/i18n/ru.js | 256 ++++ web/js/i18n/tr.js | 256 ++++ web/js/i18n/zh.js | 256 ++++ web/js/ui.js | 103 ++ web/js/views/dashboard.js | 218 ++++ web/js/views/keys.js | 128 ++ web/js/views/login.js | 40 + web/js/views/models.js | 206 +++ web/js/views/playground.js | 137 ++ web/js/views/protocols.js | 67 + web/js/views/routing.js | 158 +++ web/js/views/settings.js | 191 +++ 63 files changed, 11339 insertions(+) create mode 100644 .gitattributes create mode 100644 .github/workflows/ci.yml create mode 100644 .gitignore create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 CONTRIBUTING.ru.md create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 README.ru.md create mode 100644 config/gateway.example.toml create mode 100644 docs/ARCHITECTURE.md create mode 100644 docs/ARCHITECTURE.ru.md create mode 100644 docs/PROTOCOLS.md create mode 100644 docs/PROTOCOLS.ru.md create mode 100644 docs/ROUTING.md create mode 100644 docs/ROUTING.ru.md create mode 100644 docs/screenshots/dashboard.png create mode 100644 docs/screenshots/models.png create mode 100644 docs/screenshots/playground.png create mode 100644 docs/screenshots/routing.png create mode 100644 src/admin/assets.rs create mode 100644 src/admin/mod.rs create mode 100644 src/config.rs create mode 100644 src/error.rs create mode 100644 src/main.rs create mode 100644 src/model.rs create mode 100644 src/pipeline.rs create mode 100644 src/protocols/mod.rs create mode 100644 src/protocols/openai_chat.rs create mode 100644 src/providers/anthropic.rs create mode 100644 src/providers/mod.rs create mode 100644 src/providers/openai.rs create mode 100644 src/registry.rs create mode 100644 src/router_client.rs create mode 100644 src/routing.rs create mode 100644 src/secrets.rs create mode 100644 src/state.rs create mode 100644 src/stats.rs create mode 100644 web/css/styles.css create mode 100644 web/favicon.svg create mode 100644 web/index.html create mode 100644 web/js/api.js create mode 100644 web/js/app.js create mode 100644 web/js/charts.js create mode 100644 web/js/i18n.js create mode 100644 web/js/i18n/de.js create mode 100644 web/js/i18n/en.js create mode 100644 web/js/i18n/es.js create mode 100644 web/js/i18n/fr.js create mode 100644 web/js/i18n/ru.js create mode 100644 web/js/i18n/tr.js create mode 100644 web/js/i18n/zh.js create mode 100644 web/js/ui.js create mode 100644 web/js/views/dashboard.js create mode 100644 web/js/views/keys.js create mode 100644 web/js/views/login.js create mode 100644 web/js/views/models.js create mode 100644 web/js/views/playground.js create mode 100644 web/js/views/protocols.js create mode 100644 web/js/views/routing.js create mode 100644 web/js/views/settings.js diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..f1c3d60 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,7 @@ +# Normalize line endings +* text=auto eol=lf + +# The embedded admin SPA is first-party but ships as a UI asset; exclude it from +# GitHub's language statistics so the repo is correctly identified as Rust. +web/** linguist-vendored +docs/screenshots/** linguist-vendored diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..8ac1ea5 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,24 @@ +name: CI + +on: + push: + branches: [ main, master ] + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt, clippy + - uses: Swatinem/rust-cache@v2 + - name: Format + run: cargo fmt --all -- --check + - name: Clippy + run: cargo clippy --all-targets -- -D warnings + - name: Build + run: cargo build --release + - name: Test + run: cargo test diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d28ac0f --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +/target +**/*.rs.bk +# Cargo.lock is committed: this is an application (binary), so we want reproducible builds. +config/gateway.toml +config/secrets.toml +config/stats.jsonl +config/*.toml.tmp +.env +*.log +.DS_Store diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..ad6d53f --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,35 @@ +# Changelog + +All notable changes to this project are documented here. +The format is based on [Keep a Changelog](https://keepachangelog.com/). + +## [Unreleased] + +### Added +- **Embedded admin web console** at `/admin` — a build-free single-page app compiled + into the binary via `rust-embed`. Manage models, routing, protocols, virtual keys + and secrets from the browser; changes are hot-reloaded (no restart). +- **Multilingual UI** in 7 languages (en, ru, de, fr, es, zh, tr) with browser + auto-detection, plus light/dark themes. +- **Admin API** under `/admin/api/*` (Bearer admin token): config, models (CRUD + + probe), routing, protocols, settings, keys, secrets, stats, requests, and a + playground `test` endpoint. +- **Hot config reload** — config-derived state lives behind `arc-swap`; writes + validate → atomically rewrite the TOML → swap, with no restart. +- **Request statistics** — in-memory aggregates, per-minute time buckets, and a ring + buffer of recent requests, appended to a JSONL file and replayed on startup. +- **Prometheus `GET /metrics`** endpoint. +- **Secret store** (`config/secrets.toml`, mode `0600`) — provider keys can be set + from the UI without writing them into `gateway.toml`; values are never returned by + the API. +- English documentation as the primary language, with Russian translations + (`README.ru.md`, `docs/*.ru.md`). + +### Changed +- The Anthropic provider now returns a clear error instead of panicking when called + (the adapter is still planned for v0.2). + +## [0.0.1] +- Initial skeleton: OpenAI Chat Completions inbound adapter, OpenAI-compatible + outbound provider, routing table with fallback and graceful degradation, and + cost/token accounting. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..5dbd99b --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,46 @@ +*Read this in [Русский](CONTRIBUTING.ru.md).* + +# Contributing to Cortiq Gateway + +Thank you for your interest in the project! This is an open gateway and we welcome contributions. + +## Getting started + +1. Read [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) — design overview and roadmap. +2. Review [docs/PROTOCOLS.md](docs/PROTOCOLS.md) and [docs/ROUTING.md](docs/ROUTING.md). +3. The current phase is **Phase 0** (skeleton). Good entry-point tasks are labeled + `good first issue`. + +## How to add... + +- **A new inbound protocol** — implement the `InboundProtocol` trait in `src/protocols/`, + translate to/from the canonical model (`ChatRequest`/`ChatResponse`), and add the + corresponding flag in `[protocols]`. Do not touch the providers. +- **A new provider** — implement the `Provider` trait in `src/providers/`. Most local + servers are OpenAI-compatible, so reusing `openai.rs` is often sufficient. +- **A new routing policy** — extend `src/routing.rs` and the `[routing.policy]` section. + +Core principle: N protocols × M providers communicate **only** through the canonical model — +no direct protocol↔provider translations. + +## Style and checks + +```bash +cargo fmt --all +cargo clippy --all-targets -- -D warnings +cargo test +``` + +- Match the style of the surrounding code. +- Secrets go only through `*_env` variables — never commit them to the repository. +- New functionality must be accompanied by tests and updates to `docs/`. + +## Pull requests + +- Keep PRs small and focused. One PR = one logical unit of change. +- In the description: what, why, and how it was tested. +- Link the related issue if one exists. + +## License + +Contributions are accepted under [Apache-2.0](LICENSE). diff --git a/CONTRIBUTING.ru.md b/CONTRIBUTING.ru.md new file mode 100644 index 0000000..5f9d88f --- /dev/null +++ b/CONTRIBUTING.ru.md @@ -0,0 +1,45 @@ +*Read this in [English](CONTRIBUTING.md).* + +# Contributing to Cortiq Gateway + +Спасибо за интерес к проекту! Это открытый шлюз, и мы рады контрибьюциям. + +## С чего начать + +1. Прочитайте [docs/ARCHITECTURE.md](docs/ARCHITECTURE.ru.md) — устройство и дорожная карта. +2. Посмотрите [docs/PROTOCOLS.md](docs/PROTOCOLS.ru.md) и [docs/ROUTING.md](docs/ROUTING.ru.md). +3. Текущая фаза — **Phase 0** (скелет). Хорошие первые задачи помечены `good first issue`. + +## Как добавить... + +- **Новый входящий протокол** — реализуйте трейт `InboundProtocol` в `src/protocols/`, + переведите его в/из канонической модели (`ChatRequest`/`ChatResponse`), добавьте флаг + в `[protocols]`. Не трогайте провайдеры. +- **Нового провайдера** — реализуйте трейт `Provider` в `src/providers/`. Большинство + локальных серверов OpenAI-совместимы → часто достаточно переиспользовать `openai.rs`. +- **Новую политику роутинга** — расширьте `src/routing.rs` и секцию `[routing.policy]`. + +Принцип: N протоколов × M провайдеров общаются **только** через каноническую модель — +никаких прямых переводов «протокол↔провайдер». + +## Стиль и проверки + +```bash +cargo fmt --all +cargo clippy --all-targets -- -D warnings +cargo test +``` + +- Пишите код в стиле окружающего кода. +- Секреты — только через `*_env`, никогда в репозиторий. +- Новый функционал сопровождайте тестами и обновлением docs/. + +## Pull requests + +- Небольшие, сфокусированные PR. Один PR — одна логическая единица. +- В описании: что, зачем, как протестировано. +- Линкуйте issue, если есть. + +## Лицензия + +Контрибьюции принимаются под [Apache-2.0](LICENSE). diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..7be3006 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,2162 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" + +[[package]] +name = "anstyle-parse" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.61.2", +] + +[[package]] +name = "anyhow" +version = "1.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" + +[[package]] +name = "arc-swap" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c049c0be4daef0b145cb3555416b3b8ef5b7888a38aea1a3a155801fe7b0810b" +dependencies = [ + "rustversion", +] + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "axum" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" +dependencies = [ + "async-trait", + "axum-core", + "axum-macros", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-core" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57d123550fa8d071b7255cb0cc04dc302baa6c8c4a79f55701552684d8399bce" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bitflags" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "bytes" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593" + +[[package]] +name = "cc" +version = "1.2.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "clap" +version = "4.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" + +[[package]] +name = "colorchoice" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" + +[[package]] +name = "cortiq-gateway" +version = "0.0.1" +dependencies = [ + "anyhow", + "arc-swap", + "async-trait", + "axum", + "bytes", + "clap", + "futures", + "mime_guess", + "reqwest", + "rust-embed", + "serde", + "serde_json", + "thiserror 1.0.69", + "tokio", + "tokio-stream", + "toml", + "tower", + "tower-http", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "displaydoc" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-executor" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + +[[package]] +name = "futures-macro" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi", + "wasip2", + "wasm-bindgen", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "http" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "icu_collections" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" +dependencies = [ + "displaydoc", + "potential_utf", + "utf8_iter", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" + +[[package]] +name = "icu_properties" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" + +[[package]] +name = "icu_provider" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "ipnet" +version = "2.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "js-sys" +version = "0.3.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "litemap" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" + +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "memchr" +version = "2.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "mio" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "potential_utf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" +dependencies = [ + "zerovec", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quinn" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror 2.0.18", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fcb935c5bec503c2f0e306bdd3e58bb9029dcb14fa8d9ac76e3a5256ac0763e" +dependencies = [ + "bytes", + "getrandom 0.3.4", + "lru-slab", + "rand", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.18", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.60.2", +] + +[[package]] +name = "quote" +version = "1.0.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rand" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +dependencies = [ + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + +[[package]] +name = "reqwest" +version = "0.12.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +dependencies = [ + "base64", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tokio-util", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "webpki-roots", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rust-embed" +version = "8.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04113cb9355a377d83f06ef1f0a45b8ab8cd7d8b1288160717d66df5c7988d27" +dependencies = [ + "rust-embed-impl", + "rust-embed-utils", + "walkdir", +] + +[[package]] +name = "rust-embed-impl" +version = "8.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0902e4c7c8e997159ab384e6d0fc91c221375f6894346ae107f47dd0f3ccaa" +dependencies = [ + "proc-macro2", + "quote", + "rust-embed-utils", + "syn", + "walkdir", +] + +[[package]] +name = "rust-embed-utils" +version = "8.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bcdef0be6fe7f6fa333b1073c949729274b05f123a0ad7efcb8efd878e5c3b1" +dependencies = [ + "sha2", + "walkdir", +] + +[[package]] +name = "rustc-hash" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" + +[[package]] +name = "rustls" +version = "0.23.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" +dependencies = [ + "itoa", + "serde", + "serde_core", +] + +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" + +[[package]] +name = "socket2" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl 2.0.18", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "tinystr" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" +dependencies = [ + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-macros" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "toml_write", + "winnow", +] + +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" +dependencies = [ + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", + "tracing", + "url", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + +[[package]] +name = "unicase" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.4+wasi-0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-streams" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf85cb06032201fa7c6f829d7db5a7e5aa45bcc0655327713065f6f0576731bf" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[package]] +name = "winnow" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "writeable" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" + +[[package]] +name = "yoke" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zerofrom" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" + +[[package]] +name = "zerotrie" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..3a11152 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,49 @@ +[package] +name = "cortiq-gateway" +version = "0.0.1" +edition = "2021" +license = "Apache-2.0" +description = "Universal LLM gateway with intelligent routing via cortiq-router" +repository = "https://github.com/infosave2007/cortiq-gateway" +readme = "README.md" +keywords = ["llm", "gateway", "proxy", "openai", "routing"] +categories = ["web-programming::http-server"] + +[dependencies] +# async runtime + HTTP server +tokio = { version = "1", features = ["full"] } +axum = { version = "0.7", features = ["macros"] } +tower = "0.5" +tower-http = { version = "0.6", features = ["limit", "trace", "cors"] } + +# HTTP client to providers and to cortiq-router (rustls, no OpenSSL) +reqwest = { version = "0.12", default-features = false, features = ["json", "stream", "rustls-tls"] } + +# serialization +serde = { version = "1", features = ["derive"] } +serde_json = "1" +toml = "0.8" + +# hot-reloadable shared state + embedded admin SPA +arc-swap = "1" +rust-embed = "8" +mime_guess = "2" + +# streaming / async utils +futures = "0.3" +async-trait = "0.1" +bytes = "1" +tokio-stream = "0.1" + +# CLI / config +clap = { version = "4", features = ["derive"] } + +# errors / logging / metrics +thiserror = "1" +anyhow = "1" +tracing = "0.1" +tracing-subscriber = { version = "0.3", features = ["env-filter"] } + +[profile.release] +lto = true +codegen-units = 1 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..818aaf3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,179 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or Derivative + Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2026 Cortiq + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..6c7ac82 --- /dev/null +++ b/README.md @@ -0,0 +1,222 @@ +# Cortiq Gateway + +**English** · [Русский](README.ru.md) + +[![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE) +![Rust](https://img.shields.io/badge/Rust-2021-orange.svg) +![Status](https://img.shields.io/badge/status-active-success.svg) + +**A universal LLM gateway with intelligent routing.** +One OpenAI-compatible endpoint → automatic model selection from your pool +(cheap local + expensive hosted) based on the task type and complexity decided by +[allaigate / cortiq-router](https://api.allaigate.com). + +> In your agent/SDK you only change `base_url` — and you get "smart" routing across +> models. No model-selection logic on the client side. + +``` +┌─────────────┐ OpenAI / Anthropic / MCP ┌──────────────────┐ +│ Agent / │ ─────────────────────────────▶│ Cortiq Gateway │ +│ developer │ (standard protocol) │ (this project) │ +└─────────────┘ ◀─────────────────────────────└──────────────────┘ + response + metadata │ │ + │ /v1/route│ call LLM + ▼ ▼ + ┌──────────────┐ ┌─────────────────────┐ + │ cortiq-router│ │ Model pool │ + │ (task type, │ │ • local llama.cpp │ + │ complexity) │ │ • ollama / vLLM │ + └──────────────┘ │ • OpenAI / Claude │ + └─────────────────────┘ +``` + +--- + +## ✨ Highlights + +- **Drop-in OpenAI API.** Point any OpenAI client at the gateway and send `model: "cortiq-auto"`. +- **Intelligent routing.** `complexity.tier` → ordered model pool (`low → local`, `high → cloud`), with fallback and graceful degradation when the router is down. +- **Built-in multilingual admin console.** Manage models, routing, protocols, keys and secrets from a web UI — **no hand-editing TOML, no restart** (changes are hot-reloaded). Available in **7 languages** (en, ru, de, fr, es, zh, tr) with light/dark themes. +- **Live analytics.** Per-request stats (tokens, cost, latency, success rate, failovers), time-series charts, breakdowns by model/tier/task, and a Prometheus `GET /metrics` endpoint. +- **Playground.** Send a prompt through the live pipeline and inspect the routing decision. +- **Single self-contained binary.** The SPA is embedded into the Rust binary — nothing extra to deploy. +- **Secrets stay in the gateway.** Agents hold only a virtual gateway key; provider keys live in the gateway and never leak to clients. + +--- + +## 🖥️ Admin console + +![Dashboard](docs/screenshots/dashboard.png) + +The gateway ships with an embedded web console at **`/admin`**: + +| | | +|---|---| +| ![Models](docs/screenshots/models.png) | ![Routing](docs/screenshots/routing.png) | +| **Models** — add/edit/probe models, manage provider keys | **Routing** — visual tier editor (ordered, drag-to-reorder) | +| ![Playground](docs/screenshots/playground.png) | ![Dashboard](docs/screenshots/dashboard.png) | +| **Playground** — test the live pipeline, see the decision | **Dashboard** — traffic, cost, latency analytics | + +```bash +cargo run --release -- --config config/gateway.toml --admin-token +# open http://localhost:9000/admin?token= +``` + +If `--admin-token` / `[admin].token_env` are not set, a token is generated at startup +and printed to the log. All `/admin/api/*` endpoints require a Bearer admin token; +secret values are never returned by the API (only their presence: `store` / `env` / `missing`). + +--- + +## 🚀 Quick start + +```bash +# 1. start a router (the hosted allaigate router, or a local cortiq-router) +# it listens e.g. on http://localhost:8080 (or https://api.allaigate.com) + +# 2. describe your model pool +cp config/gateway.example.toml config/gateway.toml +$EDITOR config/gateway.toml + +# 3. run the gateway +cargo run --release -- --config config/gateway.toml +# Gateway listens on 0.0.0.0:9000 and serves the admin console at /admin +``` + +Now any OpenAI client works through the gateway: + +```python +from openai import OpenAI +client = OpenAI(base_url="http://localhost:9000/v1", api_key="sk-gw-...") + +resp = client.chat.completions.create( + model="cortiq-auto", # ← magic model = "choose for me" + messages=[{"role": "user", "content": "Solve x^2 - 5x + 6 = 0"}], +) +print(resp.choices[0].message.content) +# response headers show what the gateway picked: +# X-Cortiq-Task-Label: math +# X-Cortiq-Complexity-Tier: low +# X-Cortiq-Selected-Model: local-qwen +``` + +`model: "cortiq-auto"` enables routing. Any **real** model name from the config +(`"gpt-4o-mini"`, `"local-qwen"`) is a direct passthrough, without routing. + +> **Using the hosted allaigate router?** Set `url = "https://138.226.222.209"`, +> `verify_tls = false`, `taxonomy_id = "data-assistant"`, and a `cortiq_…` key in +> `CORTIQ_ROUTER_KEY`. On hard prompts the router escalates to an oracle (~10 s), so +> set `timeout_ms = 12000+` — otherwise the gateway gracefully degrades to the default model. + +--- + +## Request flow + +1. Client → `POST /v1/chat/completions` (or Anthropic/MCP) with `model: "cortiq-auto"`. +2. The gateway extracts the **text to route on** (strategy is configurable, see [docs/ROUTING.md](docs/ROUTING.md)). +3. Gateway → `cortiq-router /v1/route` → gets `task_label` + `complexity.tier`. +4. Gateway selects a model from the pool via the routing table (with a fallback order). +5. Gateway → the selected model's provider (translating the protocol if needed), returns the response. +6. Gateway attaches routing metadata in headers/`usage` and records cost & statistics. + +Details — [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md). + +--- + +## Supported protocols (inbound) + +Each adapter is toggled in the config — take only what you need. + +| Protocol | Endpoint | Status | +|---|---|---| +| OpenAI Chat Completions | `POST /v1/chat/completions` | ✅ implemented | +| OpenAI Completions (legacy) | `POST /v1/completions` | planned | +| OpenAI Embeddings | `POST /v1/embeddings` | planned | +| OpenAI Models | `GET /v1/models` | planned | +| Anthropic Messages | `POST /v1/messages` | planned | +| MCP (Model Context Protocol) | JSON-RPC / SSE | planned | +| Native passthrough | `POST /route` | planned | + +## Supported providers (outbound) + +| Provider | Covers | +|---|---| +| `openai` (OpenAI-compatible) | OpenAI, OpenRouter, Together, Groq, **vLLM, llama.cpp server, LM Studio, Ollama (`/v1`)** | +| `anthropic` | Claude Messages API (planned) | +| `ollama` | native Ollama API | +| `http` | arbitrary HTTP endpoint (custom adapter) | + +Most local servers already expose an OpenAI-compatible API — so the `openai` +adapter makes the gateway **universal** with almost no effort. + +--- + +## Configuration + +```toml +listen = "0.0.0.0:9000" + +[router] +url = "http://localhost:8080" +api_key_env = "CORTIQ_ROUTER_KEY" + +[[models]] +id = "local-qwen" +provider = "openai" +base_url = "http://localhost:8000/v1" +model = "qwen2.5-7b-instruct" +cost_tier = "cheap" + +[[models]] +id = "claude-opus" +provider = "anthropic" +base_url = "https://api.anthropic.com" +model = "claude-opus-4" +api_key_env = "ANTHROPIC_API_KEY" +cost_tier = "expensive" + +[routing] +low = ["local-qwen"] +high = ["claude-opus", "local-qwen"] +default = "local-qwen" +``` + +Full example — [config/gateway.example.toml](config/gateway.example.toml). +Routing & cost-aware selection — [docs/ROUTING.md](docs/ROUTING.md). +Everything in the config is also editable from the admin console at runtime. + +--- + +## Cross-standards (like grown-up APIs) + +- **Auth:** `Authorization: Bearer sk-gw-...` (virtual gateway keys). +- **Errors:** OpenAI-compatible `{"error": {...}}` envelope — parsed natively by SDKs. +- **Routing metadata:** `X-Cortiq-*` headers on every response. +- **Cost accounting:** token usage + USD cost and the selected model. +- **Observability:** `GET /metrics` (Prometheus), `GET /healthz`, `GET /readyz`. + +Details — [docs/PROTOCOLS.md](docs/PROTOCOLS.md). + +--- + +## Build & test + +```bash +cargo build --release # single self-contained binary (SPA embedded) +cargo test # config round-trip, routing validation +``` + +--- + +## Status + +🚧 Implemented so far: OpenAI Chat Completions, routing with fallback & graceful +degradation, cost/token accounting, the **embedded multilingual admin console with +hot config reload**, statistics and Prometheus `GET /metrics`. Planned: streaming +(SSE), Anthropic provider/inbound, embeddings, MCP. See the roadmap in +[docs/ARCHITECTURE.md](docs/ARCHITECTURE.md). Contributions welcome — see +[CONTRIBUTING.md](CONTRIBUTING.md). + +## License + +Apache-2.0 — see [LICENSE](LICENSE). diff --git a/README.ru.md b/README.ru.md new file mode 100644 index 0000000..6080a8c --- /dev/null +++ b/README.ru.md @@ -0,0 +1,177 @@ +# Cortiq Gateway + +[English](README.md) · **Русский** + +[![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE) +![Rust](https://img.shields.io/badge/Rust-2021-orange.svg) +![Status](https://img.shields.io/badge/status-active-success.svg) + +**Универсальный LLM-шлюз с интеллектуальной маршрутизацией.** +Один OpenAI-совместимый endpoint → автоматический выбор модели из вашего пула +(локальные дешёвые + хостовые дорогие) на основе типа задачи и сложности, которые +определяет [allaigate / cortiq-router](https://api.allaigate.com). + +> Меняете в своём агенте/SDK только `base_url` — и получаете «умный» роутинг между +> моделями. Никакой логики выбора модели на стороне клиента. + +``` +┌─────────────┐ OpenAI / Anthropic / MCP ┌──────────────────┐ +│ Агент / │ ─────────────────────────────▶│ Cortiq Gateway │ +│ разработчик │ (стандартный протокол) │ (этот проект) │ +└─────────────┘ ◀─────────────────────────────└──────────────────┘ + ответ + метаданные │ │ + │ /v1/route│ вызов LLM + ▼ ▼ + ┌──────────────┐ ┌─────────────────────┐ + │ cortiq-router│ │ Пул моделей │ + │ (тип задачи, │ │ • local llama.cpp │ + │ сложность) │ │ • ollama / vLLM │ + └──────────────┘ │ • OpenAI / Claude │ + └─────────────────────┘ +``` + +--- + +## ✨ Ключевое + +- **Drop-in OpenAI API.** Направьте любой OpenAI-клиент на шлюз и шлите `model: "cortiq-auto"`. +- **Интеллектуальный роутинг.** `complexity.tier` → упорядоченный пул моделей (`low → локально`, `high → облако`), с fallback и мягкой деградацией, если роутер недоступен. +- **Встроенная многоязычная панель управления.** Модели, роутинг, протоколы, ключи и секреты — из веб-интерфейса, **без ручного TOML и без рестарта** (горячая перезагрузка). **7 языков** (en, ru, de, fr, es, zh, tr), тёмная/светлая тема. +- **Живая аналитика.** Статистика по запросам (токены, стоимость, латентность, доля успеха, failover), графики, разбивка по моделям/полосам/задачам и Prometheus `GET /metrics`. +- **Playground.** Прогон промпта через живой пайплайн с разбором решения роутинга. +- **Один самодостаточный бинарь.** SPA встроена в Rust-бинарь — ничего лишнего разворачивать не нужно. +- **Секреты не покидают шлюз.** Агенты держат только виртуальный ключ шлюза; ключи провайдеров живут в шлюзе и наружу не уходят. + +--- + +## 🖥️ Панель управления + +![Дашборд](docs/screenshots/dashboard.png) + +В шлюз встроена веб-панель на **`/admin`**: + +| | | +|---|---| +| ![Модели](docs/screenshots/models.png) | ![Роутинг](docs/screenshots/routing.png) | +| **Models** — добавление/правка/probe моделей, ключи провайдеров | **Routing** — визуальный редактор полос (упорядоченный) | +| ![Playground](docs/screenshots/playground.png) | ![Дашборд](docs/screenshots/dashboard.png) | +| **Playground** — тест живого пайплайна с решением роутинга | **Dashboard** — трафик, стоимость, латентность | + +```bash +cargo run --release -- --config config/gateway.toml --admin-token <ВАШ_ТОКЕН> +# откройте http://localhost:9000/admin?token=<ВАШ_ТОКЕН> +``` + +Если `--admin-token` / `[admin].token_env` не заданы — токен генерируется при старте и +печатается в лог. Все эндпоинты `/admin/api/*` требуют Bearer admin-токен; значения +секретов API наружу не отдаёт (только статус наличия: `store` / `env` / `missing`). + +--- + +## 🚀 Быстрый старт + +```bash +# 1. поднимите роутер (хостовый allaigate или локальный cortiq-router) +# он слушает, например, http://localhost:8080 (или https://api.allaigate.com) + +# 2. опишите свой пул моделей +cp config/gateway.example.toml config/gateway.toml +$EDITOR config/gateway.toml + +# 3. запустите шлюз +cargo run --release -- --config config/gateway.toml +# Шлюз слушает 0.0.0.0:9000 и отдаёт панель на /admin +``` + +Теперь любой OpenAI-клиент работает через шлюз: + +```python +from openai import OpenAI +client = OpenAI(base_url="http://localhost:9000/v1", api_key="sk-gw-...") + +resp = client.chat.completions.create( + model="cortiq-auto", # ← магическая модель = «выбери сам» + messages=[{"role": "user", "content": "Solve x^2 - 5x + 6 = 0"}], +) +print(resp.choices[0].message.content) +# заголовки ответа покажут выбор шлюза: +# X-Cortiq-Task-Label: math +# X-Cortiq-Complexity-Tier: low +# X-Cortiq-Selected-Model: local-qwen +``` + +`model: "cortiq-auto"` включает роутинг. Любое **реальное** имя модели из конфига +(`"gpt-4o-mini"`, `"local-qwen"`) — это passthrough напрямую, без роутинга. + +> **Используете хостовый allaigate-роутер?** Укажите `url = "https://138.226.222.209"`, +> `verify_tls = false`, `taxonomy_id = "data-assistant"` и ключ `cortiq_…` в +> `CORTIQ_ROUTER_KEY`. На сложных запросах роутер эскалирует к oracle (~10 с), поэтому +> ставьте `timeout_ms = 12000+` — иначе шлюз мягко деградирует на default-модель. + +--- + +## Поток запроса + +1. Клиент → `POST /v1/chat/completions` (или Anthropic/MCP) с `model: "cortiq-auto"`. +2. Шлюз извлекает **текст для маршрутизации** (стратегия настраивается, см. [docs/ROUTING.ru.md](docs/ROUTING.ru.md)). +3. Шлюз → `cortiq-router /v1/route` → получает `task_label` + `complexity.tier`. +4. Шлюз выбирает модель из пула по таблице роутинга (с порядком fallback). +5. Шлюз → провайдер выбранной модели (транслируя протокол при необходимости), возвращает ответ. +6. Шлюз отдаёт метаданные роутинга в заголовках/`usage`, считает стоимость и статистику. + +Подробно — [docs/ARCHITECTURE.ru.md](docs/ARCHITECTURE.ru.md). + +--- + +## Поддерживаемые протоколы (входящие) + +| Протокол | Endpoint | Статус | +|---|---|---| +| OpenAI Chat Completions | `POST /v1/chat/completions` | ✅ реализовано | +| OpenAI Completions (legacy) | `POST /v1/completions` | план | +| OpenAI Embeddings | `POST /v1/embeddings` | план | +| OpenAI Models | `GET /v1/models` | план | +| Anthropic Messages | `POST /v1/messages` | план | +| MCP (Model Context Protocol) | JSON-RPC / SSE | план | +| Native passthrough | `POST /route` | план | + +## Поддерживаемые провайдеры (исходящие) + +| Провайдер | Покрывает | +|---|---| +| `openai` (OpenAI-совместимый) | OpenAI, OpenRouter, Together, Groq, **vLLM, llama.cpp server, LM Studio, Ollama (`/v1`)** | +| `anthropic` | Claude Messages API (план) | +| `ollama` | нативный Ollama API | +| `http` | произвольный HTTP-эндпоинт (свой адаптер) | + +--- + +## Конфигурация + +Полный пример — [config/gateway.example.toml](config/gateway.example.toml). +Модель роутинга и cost-aware выбор — [docs/ROUTING.ru.md](docs/ROUTING.ru.md). +Всё из конфига также правится из панели управления в рантайме. + +--- + +## Сборка и тесты + +```bash +cargo build --release # один самодостаточный бинарь (SPA встроена) +cargo test # round-trip конфига, валидация роутинга +``` + +--- + +## Статус + +🚧 Уже работает: OpenAI Chat Completions, роутинг с fallback и мягкой деградацией, +учёт стоимости/токенов, **встроенная многоязычная панель управления с горячей +перезагрузкой конфига**, статистика и Prometheus `GET /metrics`. В планах: стриминг +(SSE), провайдер/вход Anthropic, embeddings, MCP. Дорожная карта — +[docs/ARCHITECTURE.ru.md](docs/ARCHITECTURE.ru.md). Контрибьюции приветствуются — +см. [CONTRIBUTING.ru.md](CONTRIBUTING.ru.md). + +## Лицензия + +Apache-2.0 — см. [LICENSE](LICENSE). diff --git a/config/gateway.example.toml b/config/gateway.example.toml new file mode 100644 index 0000000..776a7b0 --- /dev/null +++ b/config/gateway.example.toml @@ -0,0 +1,152 @@ +# ============================================================================ +# Cortiq Gateway — example configuration +# Copy to gateway.toml and edit for your own model pool. +# Do NOT store secrets here — provide them via *_env (environment variables) +# or set them from the admin console (stored in config/secrets.toml). +# ============================================================================ + +listen = "0.0.0.0:9000" + +# --- connection to cortiq-router (decides task type / complexity) ----------- +# Hosted allaigate router: url = "https://138.226.222.209", verify_tls = false +# (cert is bound to an IP), taxonomy_id = "data-assistant", a cortiq_… key in +# CORTIQ_ROUTER_KEY. +# NOTE: on hard prompts the router escalates to an oracle LLM (~10 s) — for the +# hosted router set timeout_ms = 12000+, otherwise the gateway degrades to default. +[router] +url = "http://localhost:8080" +api_key_env = "CORTIQ_ROUTER_KEY" # name of the env var holding the router key +timeout_ms = 800 # timeout for the /v1/route call (12000+ for oracle) +taxonomy_id = "general.task-type" # for allaigate: "data-assistant" +verify_tls = true # false if the router uses an IP / self-signed cert + +# --- how to pick the text to classify from the conversation ----------------- +[route] +text_strategy = "last_user" # last_user | last_user_plus_system | concat_all +max_chars = 4000 +cache_ttl = "60s" +profile = "balanced" # cost-saver | balanced | quality-first + +# ============================================================================ +# Model pool: mix cheap local models and expensive cloud ones. +# provider = "openai" covers OpenAI, OpenRouter, Together, Groq, and also +# LOCAL servers vLLM / llama.cpp / LM Studio / Ollama (/v1). +# ============================================================================ + +[[models]] +id = "local-qwen" +provider = "openai" +base_url = "http://localhost:8000/v1" +model = "qwen2.5-7b-instruct" +cost_tier = "cheap" +price_in = 0.0 +price_out = 0.0 +caps = ["tools"] + +[[models]] +id = "gpt-4o-mini" +provider = "openai" +base_url = "https://api.openai.com/v1" +model = "gpt-4o-mini" +api_key_env = "OPENAI_API_KEY" +cost_tier = "mid" +price_in = 0.15 +price_out = 0.60 +caps = ["tools", "vision"] + +[[models]] +id = "claude-opus" +provider = "anthropic" +base_url = "https://api.anthropic.com" +model = "claude-opus-4" +api_key_env = "ANTHROPIC_API_KEY" +cost_tier = "expensive" +price_in = 15.0 +price_out = 75.0 +caps = ["tools", "vision"] + +# --- embedding model (for /v1/embeddings in provider mode) ------------------ +[[models]] +id = "local-embed" +provider = "openai" +base_url = "http://localhost:8000/v1" +model = "nomic-embed-text" +cost_tier = "cheap" +kind = "embedding" + +# ============================================================================ +# Routing table: complexity tier → ordered pool (priority = fallback chain) +# ============================================================================ +[routing] +low = ["local-qwen"] +medium = ["gpt-4o-mini", "local-qwen"] +high = ["claude-opus", "gpt-4o-mini"] +default = "gpt-4o-mini" # used when the router is unreachable + +[routing.policy] +mode = "fixed_table" # fixed_table | cost_aware +# for cost_aware: +# min_class = { low = "cheap", medium = "mid", high = "expensive" } +# max_cost_usd_per_request = 0.50 + +# --- resilience ------------------------------------------------------------- +[breaker] +threshold = 5 +cooldown = "30s" + +# ============================================================================ +# Inbound protocols — enable only what you need (toggles apply live in the UI) +# ============================================================================ +[protocols] +openai_chat = true +openai_completions = true +openai_embeddings = true +openai_models = true +anthropic_messages = false +mcp = false +native_passthrough = true + +# --- response routing metadata ---------------------------------------------- +[cortiq] +echo = true # add a "cortiq" field to the response body (X-Cortiq-* headers are always sent) + +# ============================================================================ +# Authentication: virtual gateway keys (agents get these, not provider keys). +# If this section is empty, the gateway runs in open mode (local development). +# ============================================================================ +[[api_keys]] +key = "sk-gw-team-a" +account = "team-a" +rate_per_min = 600 +# allow_models = ["cortiq-auto", "local-qwen"] # restrict available models (optional) + +# --- idempotency and logging ------------------------------------------------ +[idempotency] +ttl = "10m" + +[log] +bodies = false # do NOT log message bodies (privacy) — default +level = "info" + +[telemetry] +metrics = true # GET /metrics (Prometheus) +otlp_endpoint_env = "OTEL_EXPORTER_OTLP_ENDPOINT" # optional + +# ============================================================================ +# Admin web console — embedded in the binary, served at /admin +# ============================================================================ +[admin] +enabled = true +# Name of the env var holding the admin token. If unset (or empty), a token is +# generated at startup and printed to the log (see also the --admin-token flag). +token_env = "CORTIQ_ADMIN_TOKEN" +# listen = "127.0.0.1:9001" # optional: separate bind for admin (default: main listen) + +# ============================================================================ +# Request statistics (dashboard + /metrics). Kept in memory + appended to JSONL. +# ============================================================================ +[stats] +enabled = true +file = "config/stats.jsonl" # empty = in-memory only +ring_size = 500 # how many recent requests to keep in the feed +retention = "7d" # aggregate/series depth (replayed on startup) diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 0000000..12c8236 --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,205 @@ +*Read this in [Русский](ARCHITECTURE.ru.md).* + +# Cortiq Gateway Architecture + +This document describes the internal design of the gateway, request flow, abstractions, and +roadmap. Related documents: [PROTOCOLS.md](PROTOCOLS.md) (protocol contracts), +[ROUTING.md](ROUTING.md) (model selection and cost model). + +--- + +## 1. Purpose and Scope + +**Cortiq Gateway** is an L7 proxy that: + +1. accepts requests in one of the **standard protocols** (OpenAI, Anthropic, MCP); +2. asks **cortiq-router** what type of task it is and how complex; +3. selects a specific model from the **provider pool** (local + cloud); +4. calls the provider, **translating the protocol** when necessary; +5. returns the response to the client (streaming and non-streaming), adding routing metadata; +6. tracks cost and (optionally) closes the feedback loop back to the router. + +What the gateway does **not** do: it does not store or train models (that is the router's +job), and it does not implement the LLMs themselves (that is the providers' job). The gateway +is thin, stateless (except for idempotency caches and rate-limit state), and horizontally +scalable. + +--- + +## 2. Component Diagram + +``` + ┌───────────────────────────────────────────────┐ + │ Cortiq Gateway │ + │ │ + client (any protocol) │ ┌──────────────┐ ┌───────────────────┐ │ + ───────────────────────▶│──▶│ Inbound │──▶│ Core pipeline │ │ + │ │ Protocol │ │ │ │ + │ │ Adapters │ │ 1. extract text │ │ + │ │ (openai/ │ │ 2. route() │────┼──▶ cortiq-router + │ │ anthropic/ │ │ 3. select model │ │ /v1/route + │ │ mcp) │ │ 4. translate │ │ + │ └──────────────┘ │ 5. call provider │────┼──▶ Provider pool + │ │ 6. stream back │ │ (openai/anthropic/ + │ ┌──────────────┐ │ 7. usage/cost │◀───┼── ollama/http) + │ │ Cross-cutting│ │ 8. feedback (opt)│────┼──▶ cortiq-router + │ │ auth · rate │ └───────────────────┘ │ /v1/feedback + │ │ idem · trace │ │ + │ └──────────────┘ │ + └───────────────────────────────────────────────┘ +``` + +Code modules (`src/`): + +| Module | Responsibility | +|---|---| +| `main.rs` | config loading, route registration for enabled protocols, server startup | +| `config.rs` | TOML parsing: model pool, routing table, protocols, keys | +| `router_client.rs` | client for `cortiq-router` (`/v1/route`, `/v1/feedback`) | +| `registry.rs` | model pool registry + `id → provider+endpoint` resolution | +| `routing.rs` | `(label, tier) → ordered model list`; fallback/default | +| `pipeline.rs` | core: extract → route → select → translate → call → stream | +| `providers/mod.rs` | `Provider` trait (unified LLM call interface) | +| `providers/openai.rs` | OpenAI-compatible adapter (covers vLLM/llama.cpp/ollama/openrouter) | +| `providers/anthropic.rs` | Anthropic Messages adapter | +| `protocols/mod.rs` | inbound adapter trait + shared types for the canonical message model | +| `protocols/openai_chat.rs` | `/v1/chat/completions` ↔ canonical model | +| `protocols/anthropic_messages.rs` | `/v1/messages` ↔ canonical model | +| `protocols/mcp.rs` | MCP server (JSON-RPC), routing exposed as a tool | +| `auth.rs` | virtual keys, rate limiting, quotas | +| `telemetry.rs` | Prometheus metrics, OpenTelemetry spans, request IDs | +| `error.rs` | unified error type + rendering into OpenAI error envelope | + +--- + +## 3. Canonical Model (internal neutral format) + +To avoid N incoming protocols × M providers turning into N×M translation paths, +everything is normalized internally to a **single canonical request/response model**. + +``` +ChatRequest { + routing: RoutingDirective, // auto | pinned(model_id) | profile + messages: Vec, // role + content (+ tool_calls) + tools: Vec, + params: GenParams, // temperature, max_tokens, top_p, stop, ... + stream: bool, + meta: RequestMeta, // idempotency key, traceparent, account +} + +ChatResponse { + id, model_used, choices, usage, finish_reason, cortiq: RouteInfo +} +``` + +- Inbound adapter: `protocol-specific → ChatRequest` and `ChatResponse → protocol-specific`. +- Outbound provider: `ChatRequest → provider wire` and `provider wire → ChatResponse`. + +Adding a new protocol = one inbound adapter. Adding a new provider = one outbound adapter. +No combinatorial explosion. + +--- + +## 4. Extension Traits + +```rust +// inbound protocol +#[async_trait] +trait InboundProtocol { + fn routes(&self) -> Router; // axum routes for this protocol + fn name(&self) -> &'static str; // "openai_chat", ... +} + +// outbound provider +#[async_trait] +trait Provider: Send + Sync { + fn id(&self) -> &str; + async fn chat(&self, req: ChatRequest) -> Result; + async fn chat_stream(&self, req: ChatRequest) -> Result; // SSE stream + async fn embed(&self, req: EmbedRequest) -> Result; + fn capabilities(&self) -> Caps; // tools? streaming? vision? +} +``` + +The registry (`registry.rs`) holds a `HashMap>` built +from `[[models]]`. The routing table (`routing.rs`) operates on `model_id`. + +--- + +## 5. `route → select → call` Flow in Detail + +1. **Extract.** Text for classification is taken from `messages`. Strategy from config: + `last_user` (default) | `concat_all` | `last_user_plus_system`. Long text is + truncated to `route.max_chars` (protection against cost/DoS). +2. **Route.** `router_client.route(text, profile)` → `{task_label, complexity}`. + Cached by text hash for `route.cache_ttl` (minor savings on repeated requests). +3. **Select.** `routing.select(label, tier)` → ordered `Vec`. + Considers: model health, model `capabilities` (e.g. whether tools are needed), + and the cost policy (see [ROUTING.md](ROUTING.md)). +4. **Translate + Call.** Canonical `ChatRequest` → provider. Streaming is proxied + chunk-by-chunk (SSE → SSE) without buffering. +5. **Failover.** If a provider returns 5xx / timeout / overloaded — the next model + in the list is tried. The circuit breaker marks an unhealthy model to avoid + hammering it. +6. **Degrade.** If cortiq-router is unavailable, `routing.default` is used (soft + degradation — the request does not fail). + +--- + +## 6. Reliability + +| Mechanism | Behavior | +|---|---| +| Timeouts | separate timeouts for router call, provider connect, and provider stream | +| Failover | ordered model list within the tier | +| Circuit breaker | temporarily excludes a model after repeated errors | +| Router down | `routing.default` | +| All tier providers down | OpenAI error `503 upstream_unavailable`, `retriable=true` | +| Idempotency | repeat with the same `Idempotency-Key` returns the stored response | + +--- + +## 7. Security and Multi-tenancy + +- **Key isolation.** Agents hold only a virtual gateway key; provider keys + (`*_API_KEY`) live in the gateway environment and are never exposed externally. +- **Accounts.** Each `[[api_keys]]` entry maps to an account with its own rate limit, + quota, and optionally its own allowed-model subset and routing table. +- **PII.** Redaction is performed in the router before escalation to the oracle; the + gateway can additionally enable logging without request bodies (`log.bodies = false` + by default). +- **Audit.** Every request records: `request_id`, account, selected model, tokens, cost, + and decision path — without the prompt text by default. + +--- + +## 8. Observability + +`GET /metrics` (Prometheus), `GET /healthz`, `GET /readyz`. Metrics: + +``` +gw_requests_total{protocol,account} +gw_route_calls_total # calls to cortiq-router +gw_model_selected_total{model_id,tier} +gw_provider_calls_total{provider,model_id,outcome} +gw_failovers_total +gw_tokens_total{model_id,direction} +gw_cost_usd_total{account,model_id} +gw_latency_seconds{stage} # route | provider | total (histogram) +``` + +OpenTelemetry spans: `inbound → route → provider`, with `traceparent` forwarding. + +--- + +## 9. Roadmap + +| Phase | Contents | +|---|---| +| **v0.1** | OpenAI Chat/Completions/Embeddings/Models, `openai` provider, routing + fallback, auth, metrics, streaming | +| **v0.2** | `anthropic` provider + inbound Anthropic Messages, cost-aware selection, idempotency, circuit breaker | +| **v0.3** | MCP server, native `ollama` provider, OpenTelemetry, routing cache | +| **v0.4** | Per-account routing tables, feedback loop to router, load tests, Helm chart | +| **v1.0** | Contract stabilization, OpenAPI spec, official examples for crewAI/LangChain/Hermes | + +Current phase: **Phase 0** (skeleton + specification in this repository). diff --git a/docs/ARCHITECTURE.ru.md b/docs/ARCHITECTURE.ru.md new file mode 100644 index 0000000..8619865 --- /dev/null +++ b/docs/ARCHITECTURE.ru.md @@ -0,0 +1,202 @@ +*Read this in [English](ARCHITECTURE.md).* + +# Архитектура Cortiq Gateway + +Документ описывает внутреннее устройство шлюза, поток запроса, абстракции и +дорожную карту. Сопутствующие документы: [PROTOCOLS.md](PROTOCOLS.ru.md) (контракты +протоколов), [ROUTING.md](ROUTING.ru.md) (модель выбора моделей и стоимости). + +--- + +## 1. Назначение и границы + +**Cortiq Gateway** — это L7-прокси, который: + +1. принимает запрос в одном из **стандартных протоколов** (OpenAI, Anthropic, MCP); +2. спрашивает **cortiq-router**, какой это тип задачи и насколько он сложный; +3. выбирает конкретную модель из **пула провайдеров** (локальные + облачные); +4. вызывает провайдера, **транслируя протокол** при необходимости; +5. возвращает ответ клиенту (стриминг и без), добавляя метаданные роутинга; +6. учитывает стоимость и (опц.) замыкает петлю обратной связи в роутер. + +Что шлюз **не** делает: не хранит и не обучает модели (это роутер), не реализует +сами LLM (это провайдеры). Шлюз — тонкий, без состояния (кроме кэшей идемпотентности +и rate-limit), горизонтально масштабируется. + +--- + +## 2. Компонентная схема + +``` + ┌───────────────────────────────────────────────┐ + │ Cortiq Gateway │ + │ │ + client (any protocol) │ ┌──────────────┐ ┌───────────────────┐ │ + ───────────────────────▶│──▶│ Inbound │──▶│ Core pipeline │ │ + │ │ Protocol │ │ │ │ + │ │ Adapters │ │ 1. extract text │ │ + │ │ (openai/ │ │ 2. route() │────┼──▶ cortiq-router + │ │ anthropic/ │ │ 3. select model │ │ /v1/route + │ │ mcp) │ │ 4. translate │ │ + │ └──────────────┘ │ 5. call provider │────┼──▶ Provider pool + │ │ 6. stream back │ │ (openai/anthropic/ + │ ┌──────────────┐ │ 7. usage/cost │◀───┼── ollama/http) + │ │ Cross-cutting│ │ 8. feedback (opt)│────┼──▶ cortiq-router + │ │ auth · rate │ └───────────────────┘ │ /v1/feedback + │ │ idem · trace │ │ + │ └──────────────┘ │ + └───────────────────────────────────────────────┘ +``` + +Модули кода (`src/`): + +| Модуль | Ответственность | +|---|---| +| `main.rs` | загрузка конфига, сборка роутов по включённым протоколам, запуск сервера | +| `config.rs` | парсинг TOML: пул моделей, таблица роутинга, протоколы, ключи | +| `router_client.rs` | клиент к `cortiq-router` (`/v1/route`, `/v1/feedback`) | +| `registry.rs` | реестр моделей пула + резолв `id → провайдер+endpoint` | +| `routing.rs` | `(label, tier) → упорядоченный список моделей`; fallback/default | +| `pipeline.rs` | ядро: extract → route → select → translate → call → stream | +| `providers/mod.rs` | трейт `Provider` (унифицированный вызов LLM) | +| `providers/openai.rs` | OpenAI-совместимый адаптер (covers vLLM/llama.cpp/ollama/openrouter) | +| `providers/anthropic.rs` | адаптер Anthropic Messages | +| `protocols/mod.rs` | трейт входящего адаптера + общие типы канонической модели сообщения | +| `protocols/openai_chat.rs` | вход `/v1/chat/completions` ↔ каноническая модель | +| `protocols/anthropic_messages.rs` | вход `/v1/messages` ↔ каноническая модель | +| `protocols/mcp.rs` | MCP-сервер (JSON-RPC), маршрутизация как инструмент | +| `auth.rs` | виртуальные ключи, rate-limit, квоты | +| `telemetry.rs` | метрики Prometheus, OpenTelemetry-спаны, request-id | +| `error.rs` | единый тип ошибки + рендер в OpenAI-конверт | + +--- + +## 3. Каноническая модель (внутренний нейтральный формат) + +Чтобы N входящих протоколов × M провайдеров не превратились в N×M переводов, +внутри всё приводится к **одной канонической модели** запроса/ответа. + +``` +ChatRequest { + routing: RoutingDirective, // auto | pinned(model_id) | profile + messages: Vec, // role + content (+ tool_calls) + tools: Vec, + params: GenParams, // temperature, max_tokens, top_p, stop, ... + stream: bool, + meta: RequestMeta, // idempotency key, traceparent, account +} + +ChatResponse { + id, model_used, choices, usage, finish_reason, cortiq: RouteInfo +} +``` + +- Входящий адаптер: `protocol-specific → ChatRequest` и `ChatResponse → protocol-specific`. +- Исходящий провайдер: `ChatRequest → provider wire` и `provider wire → ChatResponse`. + +Добавить новый протокол = один входящий адаптер. Добавить нового провайдера = +один исходящий адаптер. Никакого комбинаторного взрыва. + +--- + +## 4. Трейты-расширения + +```rust +// входящий протокол +#[async_trait] +trait InboundProtocol { + fn routes(&self) -> Router; // axum-роуты этого протокола + fn name(&self) -> &'static str; // "openai_chat", ... +} + +// исходящий провайдер +#[async_trait] +trait Provider: Send + Sync { + fn id(&self) -> &str; + async fn chat(&self, req: ChatRequest) -> Result; + async fn chat_stream(&self, req: ChatRequest) -> Result; // SSE-поток + async fn embed(&self, req: EmbedRequest) -> Result; + fn capabilities(&self) -> Caps; // tools? streaming? vision? +} +``` + +Реестр (`registry.rs`) держит `HashMap>`, построенный +из `[[models]]`. Таблица роутинга (`routing.rs`) оперирует `model_id`. + +--- + +## 5. Поток `route → select → call` детально + +1. **Extract.** Из `messages` берётся текст для классификации. Стратегия из конфига: + `last_user` (по умолчанию) | `concat_all` | `last_user_plus_system`. Длинный + текст усечётся до `route.max_chars` (защита от стоимости/DoS). +2. **Route.** `router_client.route(text, profile)` → `{task_label, complexity}`. + Кэшируется по хэшу текста на `route.cache_ttl` (мелкая экономия на повторах). +3. **Select.** `routing.select(label, tier)` → упорядоченный `Vec`. + Учитываются: доступность модели (health), её `capabilities` (нужны ли tools), + и cost-политика (см. [ROUTING.md](ROUTING.ru.md)). +4. **Translate + Call.** Канонический `ChatRequest` → провайдер. Стриминг проксируется + чанк-в-чанк (SSE → SSE) без буферизации. +5. **Failover.** Если провайдер вернул 5xx/таймаут/перегрузку — следующий из списка. + Circuit breaker помечает «больную» модель, чтобы не долбить её. +6. **Degrade.** Если cortiq-router недоступен — берётся `routing.default` (мягкая + деградация, запрос не падает). + +--- + +## 6. Надёжность + +| Механизм | Поведение | +|---|---| +| Таймауты | отдельные на router-вызов, connect и стрим провайдера | +| Failover | по упорядоченному списку моделей полосы | +| Circuit breaker | временно исключает модель после серии ошибок | +| Router down | `routing.default` | +| Все провайдеры полосы down | OpenAI-ошибка `503 upstream_unavailable`, `retriable=true` | +| Идемпотентность | повтор с тем же `Idempotency-Key` отдаёт сохранённый ответ | + +--- + +## 7. Безопасность и мультиарендность + +- **Изоляция ключей.** Агенты держат только виртуальный ключ шлюза; ключи провайдеров + (`*_API_KEY`) живут в окружении шлюза и наружу не уходят. +- **Аккаунты.** Каждый `[[api_keys]]` → аккаунт с rate-limit, квотой, (опц.) своим + подмножеством разрешённых моделей и своей таблицей роутинга. +- **PII.** Редакция выполняется в роутере перед эскалацией к оракулу; шлюз дополнительно + может включить логирование без тел сообщений (`log.bodies = false` по умолчанию). +- **Аудит.** Каждый запрос: `request_id`, аккаунт, выбранная модель, токены, стоимость, + путь решения — без текста промпта по умолчанию. + +--- + +## 8. Наблюдаемость + +`GET /metrics` (Prometheus), `GET /healthz`, `GET /readyz`. Метрики: + +``` +gw_requests_total{protocol,account} +gw_route_calls_total # обращения к cortiq-router +gw_model_selected_total{model_id,tier} +gw_provider_calls_total{provider,model_id,outcome} +gw_failovers_total +gw_tokens_total{model_id,direction} +gw_cost_usd_total{account,model_id} +gw_latency_seconds{stage} # route | provider | total (histogram) +``` + +OpenTelemetry-спаны: `inbound → route → provider`, с пробросом `traceparent`. + +--- + +## 9. Дорожная карта + +| Фаза | Содержимое | +|---|---| +| **v0.1** | OpenAI Chat/Completions/Embeddings/Models, провайдер `openai`, роутинг + fallback, auth, метрики, стриминг | +| **v0.2** | Провайдер `anthropic` + входящий Anthropic Messages, cost-aware выбор, идемпотентность, circuit breaker | +| **v0.3** | MCP-сервер, провайдер `ollama` нативный, OpenTelemetry, кэш роутинга | +| **v0.4** | Per-account таблицы роутинга, feedback-loop в роутер, нагрузочные тесты, Helm-чарт | +| **v1.0** | Стабилизация контракта, OpenAPI-спека, официальные примеры под crewAI/LangChain/Hermes | + +Текущая фаза — **Phase 0** (скелет + спецификация в этом репозитории). diff --git a/docs/PROTOCOLS.md b/docs/PROTOCOLS.md new file mode 100644 index 0000000..aecd61b --- /dev/null +++ b/docs/PROTOCOLS.md @@ -0,0 +1,324 @@ +*Read this in [Русский](PROTOCOLS.ru.md).* + +# Cortiq Gateway Protocols + +Contracts for inbound protocols and cross-standard mechanisms. Each protocol is enabled +by a flag in `[protocols]`. Internally, all requests are normalized to the canonical model +(see [ARCHITECTURE.md](ARCHITECTURE.md#3-canonical-model-internal-neutral-format)). + +Routing rule common to all protocols: + +- `model = "cortiq-auto"` → enable intelligent routing via cortiq-router. +- `model = "cortiq-auto:quality-first"` → routing with the specified policy profile + (`cost-saver` | `balanced` | `quality-first`). +- `model = ""` → passthrough to that model without routing. + +--- + +## Table of Contents + +1. [OpenAI Chat Completions](#1-openai-chat-completions) +2. [OpenAI Completions (legacy)](#2-openai-completions-legacy) +3. [OpenAI Embeddings](#3-openai-embeddings) +4. [OpenAI Models](#4-openai-models) +5. [Anthropic Messages](#5-anthropic-messages) +6. [MCP (Model Context Protocol)](#6-mcp-model-context-protocol) +7. [Native passthrough](#7-native-passthrough) +8. [Cross-standard mechanisms](#8-cross-standard-mechanisms) + +--- + +## 1. OpenAI Chat Completions + +`POST /v1/chat/completions` — the primary endpoint; the de facto standard for agents. + +### Request + +```jsonc +{ + "model": "cortiq-auto", // routing; or a real id for passthrough + "messages": [ + { "role": "system", "content": "You are a helpful assistant." }, + { "role": "user", "content": "Solve x^2 - 5x + 6 = 0" } + ], + "temperature": 0.7, + "max_tokens": 1024, + "stream": false, + "tools": [ /* function-calling, proxied to the provider as-is */ ], + "tool_choice": "auto", + "stop": ["\n\n"], + "top_p": 1.0, + "response_format": { "type": "json_object" } +} +``` + +Standard OpenAI fields are supported; unknown fields are proxied to the provider unchanged +(forward-compatible). + +### Response (non-streaming) + +```jsonc +{ + "id": "chatcmpl-9f...", + "object": "chat.completion", + "created": 1718800000, + "model": "local-qwen", // the ACTUALLY selected model + "choices": [ + { + "index": 0, + "message": { "role": "assistant", "content": "x = 2 or x = 3" }, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 24, + "completion_tokens": 11, + "total_tokens": 35 + }, + "cortiq": { // extension (enabled with cortiq.echo=true) + "task_label": "math", + "complexity": { "score": 0.22, "tier": "low" }, + "selected_model": "local-qwen", + "route_source": "router", // router | cache | fallback | pinned + "router_request_id": "req_...", + "cost_usd": 0.0 + } +} +``` + +> The `cortiq` field is an optional extension. OpenAI SDKs ignore it. If the client does +> not want extra fields, disable `cortiq.echo` — the metadata will remain in the response +> headers. + +### Metadata in response headers (always present) + +``` +X-Cortiq-Request-Id: req_... +X-Cortiq-Task-Label: math +X-Cortiq-Complexity-Score: 0.22 +X-Cortiq-Complexity-Tier: low +X-Cortiq-Selected-Model: local-qwen +X-Cortiq-Route-Source: router +X-Cortiq-Cost-Usd: 0.000000 +``` + +### Response (streaming, `stream: true`) + +SSE in OpenAI format: a series of `chat.completion.chunk` events, terminated by +`data: [DONE]`. The gateway proxies provider chunks one-to-one (without buffering), +adding routing metadata to HTTP headers before the stream begins. + +``` +data: {"id":"chatcmpl-9f","object":"chat.completion.chunk","choices":[{"delta":{"role":"assistant"},"index":0}]} + +data: {"id":"chatcmpl-9f","object":"chat.completion.chunk","choices":[{"delta":{"content":"x = 2"},"index":0}]} + +data: {"id":"chatcmpl-9f","object":"chat.completion.chunk","choices":[{"delta":{},"finish_reason":"stop","index":0}]} + +data: [DONE] +``` + +--- + +## 2. OpenAI Completions (legacy) + +`POST /v1/completions` — for legacy integrations. Internally, `prompt` is wrapped into a +single user message and follows the same pipeline. Response `object` is `"text_completion"`. + +```jsonc +// request +{ "model": "cortiq-auto", "prompt": "Translate to French: hello", "max_tokens": 64 } +// response +{ "object": "text_completion", "model": "local-qwen", + "choices": [ { "text": "bonjour", "index": 0, "finish_reason": "stop" } ], + "usage": { "prompt_tokens": 6, "completion_tokens": 2, "total_tokens": 8 } } +``` + +--- + +## 3. OpenAI Embeddings + +`POST /v1/embeddings`. Two modes (configurable): + +- `provider` — proxy to an embedding model from the pool; +- `router` — return an embedding from the **cortiq-router encoder** (the same vector the + router uses for classification — useful for consistent RAG). + +```jsonc +// request +{ "model": "cortiq-embed", "input": ["first text", "second text"] } +// response +{ + "object": "list", + "data": [ + { "object": "embedding", "index": 0, "embedding": [0.01, -0.02, /* ... */] }, + { "object": "embedding", "index": 1, "embedding": [0.03, 0.00, /* ... */] } + ], + "model": "cortiq-embed", + "usage": { "prompt_tokens": 4, "total_tokens": 4 } +} +``` + +--- + +## 4. OpenAI Models + +`GET /v1/models` — auto-discovery for clients. Returns the gateway's virtual models +(`cortiq-auto`, `cortiq-embed`) and all real models in the pool. + +```jsonc +{ + "object": "list", + "data": [ + { "id": "cortiq-auto", "object": "model", "owned_by": "cortiq-gateway" }, + { "id": "local-qwen", "object": "model", "owned_by": "cortiq-gateway" }, + { "id": "gpt-4o-mini", "object": "model", "owned_by": "cortiq-gateway" }, + { "id": "claude-opus", "object": "model", "owned_by": "cortiq-gateway" } + ] +} +``` + +--- + +## 5. Anthropic Messages + +`POST /v1/messages` — for Claude-native agents and the Anthropic SDK. + +```jsonc +// request +{ + "model": "cortiq-auto", + "max_tokens": 1024, + "system": "You are a helpful assistant.", + "messages": [ { "role": "user", "content": "Solve x^2 - 5x + 6 = 0" } ], + "stream": false +} +// response +{ + "id": "msg_...", + "type": "message", + "role": "assistant", + "model": "local-qwen", + "content": [ { "type": "text", "text": "x = 2 or x = 3" } ], + "stop_reason": "end_turn", + "usage": { "input_tokens": 24, "output_tokens": 11 } +} +``` + +Streaming uses native Anthropic events (`message_start`, `content_block_delta`, +`message_delta`, `message_stop`). If the selected model is a non-Anthropic provider, +the gateway translates through the canonical model in both directions. + +--- + +## 6. MCP (Model Context Protocol) + +The gateway runs an **MCP server** (JSON-RPC 2.0 over HTTP+SSE or stdio) and exposes +routing as tools for MCP-native orchestrators. + +Published tools: + +| Tool | Purpose | +|---|---| +| `route_and_complete` | classify + execute on the selected model, return the response | +| `classify_task` | classification only (task type + complexity), no execution | + +`tools/list` returns JSON schemas. Example `tools/call` invocation: + +```jsonc +// request (JSON-RPC) +{ + "jsonrpc": "2.0", "id": 1, "method": "tools/call", + "params": { + "name": "route_and_complete", + "arguments": { "prompt": "Solve x^2 - 5x + 6 = 0", "profile": "balanced" } + } +} +// response +{ + "jsonrpc": "2.0", "id": 1, + "result": { + "content": [ { "type": "text", "text": "x = 2 or x = 3" } ], + "isError": false, + "_meta": { "task_label": "math", "tier": "low", "selected_model": "local-qwen" } + } +} +``` + +--- + +## 7. Native passthrough + +`POST /route` — a thin wrapper over `cortiq-router /v1/route` for clients that need only +the **routing decision** (without execution). The request body and response match the router +contract (see `cortiq-router/docs/ФОРМАТ_ЗАПРОСА_И_ОТВЕТА.md`). Useful for debugging and +for integrators who want to manage the LLM call themselves. + +--- + +## 8. Cross-standard mechanisms + +Common to all HTTP protocols. + +### 8.1 Authentication + +``` +Authorization: Bearer sk-gw-... +``` +Virtual gateway key. Mapped to an account (`[[api_keys]]`). If no keys are configured, +the gateway runs in open mode (for local development). Provider keys are never exposed. + +### 8.2 Idempotency + +``` +Idempotency-Key: +``` +A repeat request with the same key within the `idempotency.ttl` window returns the +**stored** response (safe agent retries, without double-invoking the LLM or double billing). + +### 8.3 Rate limiting + +On `429`, the following headers are returned: + +``` +Retry-After: 2 +X-RateLimit-Limit: 600 +X-RateLimit-Remaining: 0 +X-RateLimit-Reset: 1718800060 +``` + +### 8.4 Tracing + +W3C `traceparent` is accepted and forwarded; OpenTelemetry spans cover +`inbound→route→provider`. The response includes `X-Request-Id`. This enables an +end-to-end trace from agent → gateway → provider. + +### 8.5 Error format (OpenAI-compatible) + +```jsonc +{ + "error": { + "message": "no healthy model available for tier 'high'", + "type": "upstream_unavailable", // invalid_request_error | authentication_error | rate_limit_error | upstream_unavailable | internal_error + "code": "no_healthy_model", + "param": null + } +} +``` + +OpenAI/Anthropic SDKs parse this envelope natively. Status code mapping: + +| Type | HTTP | retriable | +|---|---|---| +| `invalid_request_error` | 400 | no | +| `authentication_error` | 401 | no | +| `rate_limit_error` | 429 | yes | +| `upstream_unavailable` | 502/503 | yes | +| `internal_error` | 500 | yes | + +### 8.6 Cost tracking + +`usage` is returned in the protocol format (OpenAI/Anthropic). Additionally, cost is +included in the `X-Cortiq-Cost-Usd` header and in `cortiq.cost_usd` (if `cortiq.echo` +is enabled). The price is calculated from the model's `price_in`/`price_out` in the config +multiplied by the token counts. diff --git a/docs/PROTOCOLS.ru.md b/docs/PROTOCOLS.ru.md new file mode 100644 index 0000000..3f356b7 --- /dev/null +++ b/docs/PROTOCOLS.ru.md @@ -0,0 +1,321 @@ +*Read this in [English](PROTOCOLS.md).* + +# Протоколы Cortiq Gateway + +Контракты входящих протоколов и кросс-стандартных механизмов. Каждый протокол +включается флагом в `[protocols]`. Внутри всё приводится к канонической модели +(см. [ARCHITECTURE.md](ARCHITECTURE.ru.md#3-каноническая-модель)). + +Общее правило маршрутизации во всех протоколах: + +- `model = "cortiq-auto"` → включить интеллектуальный роутинг через cortiq-router. +- `model = "cortiq-auto:quality-first"` → роутинг с указанным policy-профилем + (`cost-saver` | `balanced` | `quality-first`). +- `model = "<реальный id из конфига>"` → passthrough к этой модели без роутинга. + +--- + +## Оглавление + +1. [OpenAI Chat Completions](#1-openai-chat-completions) +2. [OpenAI Completions (legacy)](#2-openai-completions-legacy) +3. [OpenAI Embeddings](#3-openai-embeddings) +4. [OpenAI Models](#4-openai-models) +5. [Anthropic Messages](#5-anthropic-messages) +6. [MCP (Model Context Protocol)](#6-mcp-model-context-protocol) +7. [Native passthrough](#7-native-passthrough) +8. [Кросс-стандарты](#8-кросс-стандарты) + +--- + +## 1. OpenAI Chat Completions + +`POST /v1/chat/completions` — основной endpoint, де-факто стандарт для агентов. + +### Запрос + +```jsonc +{ + "model": "cortiq-auto", // роутинг; или реальный id для passthrough + "messages": [ + { "role": "system", "content": "You are a helpful assistant." }, + { "role": "user", "content": "Solve x^2 - 5x + 6 = 0" } + ], + "temperature": 0.7, + "max_tokens": 1024, + "stream": false, + "tools": [ /* function-calling, проксируется к провайдеру как есть */ ], + "tool_choice": "auto", + "stop": ["\n\n"], + "top_p": 1.0, + "response_format": { "type": "json_object" } +} +``` + +Поддерживаются стандартные поля OpenAI; неизвестные поля проксируются к провайдеру +без изменений (forward-compatible). + +### Ответ (без стриминга) + +```jsonc +{ + "id": "chatcmpl-9f...", + "object": "chat.completion", + "created": 1718800000, + "model": "local-qwen", // РЕАЛЬНО выбранная модель + "choices": [ + { + "index": 0, + "message": { "role": "assistant", "content": "x = 2 или x = 3" }, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 24, + "completion_tokens": 11, + "total_tokens": 35 + }, + "cortiq": { // расширение (включается cortiq.echo=true) + "task_label": "math", + "complexity": { "score": 0.22, "tier": "low" }, + "selected_model": "local-qwen", + "route_source": "router", // router | cache | fallback | pinned + "router_request_id": "req_...", + "cost_usd": 0.0 + } +} +``` + +> Поле `cortiq` — необязательное расширение. OpenAI-SDK его игнорируют. Если клиент +> не хочет «лишних» полей — выключите `cortiq.echo`, метаданные останутся в заголовках. + +### Метаданные в заголовках (всегда) + +``` +X-Cortiq-Request-Id: req_... +X-Cortiq-Task-Label: math +X-Cortiq-Complexity-Score: 0.22 +X-Cortiq-Complexity-Tier: low +X-Cortiq-Selected-Model: local-qwen +X-Cortiq-Route-Source: router +X-Cortiq-Cost-Usd: 0.000000 +``` + +### Ответ (стриминг, `stream: true`) + +SSE, формат OpenAI: серия чанков `chat.completion.chunk`, завершается `data: [DONE]`. +Шлюз проксирует чанки провайдера один-в-один (без буферизации), добавив метаданные +роутинга в HTTP-заголовки до начала потока. + +``` +data: {"id":"chatcmpl-9f","object":"chat.completion.chunk","choices":[{"delta":{"role":"assistant"},"index":0}]} + +data: {"id":"chatcmpl-9f","object":"chat.completion.chunk","choices":[{"delta":{"content":"x = 2"},"index":0}]} + +data: {"id":"chatcmpl-9f","object":"chat.completion.chunk","choices":[{"delta":{},"finish_reason":"stop","index":0}]} + +data: [DONE] +``` + +--- + +## 2. OpenAI Completions (legacy) + +`POST /v1/completions` — для старых интеграций. Внутри `prompt` оборачивается в +одно user-сообщение и идёт по тому же пути. Ответ — `object: "text_completion"`. + +```jsonc +// запрос +{ "model": "cortiq-auto", "prompt": "Translate to French: hello", "max_tokens": 64 } +// ответ +{ "object": "text_completion", "model": "local-qwen", + "choices": [ { "text": "bonjour", "index": 0, "finish_reason": "stop" } ], + "usage": { "prompt_tokens": 6, "completion_tokens": 2, "total_tokens": 8 } } +``` + +--- + +## 3. OpenAI Embeddings + +`POST /v1/embeddings`. Два режима (настраивается): + +- `provider` — проксировать к embedding-модели из пула; +- `router` — вернуть эмбеддинг **энкодером cortiq-router** (тот же вектор, что роутер + использует для классификации — удобно для согласованного RAG). + +```jsonc +// запрос +{ "model": "cortiq-embed", "input": ["first text", "second text"] } +// ответ +{ + "object": "list", + "data": [ + { "object": "embedding", "index": 0, "embedding": [0.01, -0.02, /* ... */] }, + { "object": "embedding", "index": 1, "embedding": [0.03, 0.00, /* ... */] } + ], + "model": "cortiq-embed", + "usage": { "prompt_tokens": 4, "total_tokens": 4 } +} +``` + +--- + +## 4. OpenAI Models + +`GET /v1/models` — автодискавери для клиентов. Возвращает виртуальные модели шлюза +(`cortiq-auto`, `cortiq-embed`) и все реальные модели пула. + +```jsonc +{ + "object": "list", + "data": [ + { "id": "cortiq-auto", "object": "model", "owned_by": "cortiq-gateway" }, + { "id": "local-qwen", "object": "model", "owned_by": "cortiq-gateway" }, + { "id": "gpt-4o-mini", "object": "model", "owned_by": "cortiq-gateway" }, + { "id": "claude-opus", "object": "model", "owned_by": "cortiq-gateway" } + ] +} +``` + +--- + +## 5. Anthropic Messages + +`POST /v1/messages` — для Claude-нативных агентов и Anthropic SDK. + +```jsonc +// запрос +{ + "model": "cortiq-auto", + "max_tokens": 1024, + "system": "You are a helpful assistant.", + "messages": [ { "role": "user", "content": "Solve x^2 - 5x + 6 = 0" } ], + "stream": false +} +// ответ +{ + "id": "msg_...", + "type": "message", + "role": "assistant", + "model": "local-qwen", + "content": [ { "type": "text", "text": "x = 2 или x = 3" } ], + "stop_reason": "end_turn", + "usage": { "input_tokens": 24, "output_tokens": 11 } +} +``` + +Стриминг — нативные Anthropic-события (`message_start`, `content_block_delta`, +`message_delta`, `message_stop`). Если выбранная модель — не-Anthropic-провайдер, +шлюз транслирует через каноническую модель в обе стороны. + +--- + +## 6. MCP (Model Context Protocol) + +Шлюз поднимает **MCP-сервер** (JSON-RPC 2.0 поверх HTTP+SSE или stdio) и публикует +маршрутизацию как инструменты для MCP-нативных оркестраторов. + +Публикуемые инструменты: + +| Инструмент | Назначение | +|---|---| +| `route_and_complete` | классифицировать + выполнить на выбранной модели, вернуть ответ | +| `classify_task` | только классификация (тип задачи + сложность), без выполнения | + +`tools/list` отдаёт JSON-схемы. Пример вызова `tools/call`: + +```jsonc +// запрос (JSON-RPC) +{ + "jsonrpc": "2.0", "id": 1, "method": "tools/call", + "params": { + "name": "route_and_complete", + "arguments": { "prompt": "Solve x^2 - 5x + 6 = 0", "profile": "balanced" } + } +} +// ответ +{ + "jsonrpc": "2.0", "id": 1, + "result": { + "content": [ { "type": "text", "text": "x = 2 или x = 3" } ], + "isError": false, + "_meta": { "task_label": "math", "tier": "low", "selected_model": "local-qwen" } + } +} +``` + +--- + +## 7. Native passthrough + +`POST /route` — тонкая обёртка над `cortiq-router /v1/route` для клиентов, которым +нужно только **решение** (без выполнения). Тело и ответ совпадают с контрактом роутера +(см. `cortiq-router/docs/ФОРМАТ_ЗАПРОСА_И_ОТВЕТА.md`). Полезно для отладки и для тех, +кто хочет сам управлять вызовом LLM. + +--- + +## 8. Кросс-стандарты + +Едины для всех HTTP-протоколов. + +### 8.1 Аутентификация + +``` +Authorization: Bearer sk-gw-... +``` +Виртуальный ключ шлюза. Маппится на аккаунт (`[[api_keys]]`). Если ключи не настроены — +открытый режим (для локальной разработки). Ключи провайдеров наружу не отдаются. + +### 8.2 Идемпотентность + +``` +Idempotency-Key: <уникальный-id-операции> +``` +Повтор с тем же ключом в окне `idempotency.ttl` отдаёт **сохранённый** ответ +(безопасные ретраи агентов, без двойного вызова LLM и двойного биллинга). + +### 8.3 Rate-limit + +На `429` возвращаются: + +``` +Retry-After: 2 +X-RateLimit-Limit: 600 +X-RateLimit-Remaining: 0 +X-RateLimit-Reset: 1718800060 +``` + +### 8.4 Трассировка + +Приём и проброс W3C `traceparent`; OpenTelemetry-спаны `inbound→route→provider`. +В ответе — `X-Request-Id`. Это позволяет сшить сквозной трейс агент → шлюз → провайдер. + +### 8.5 Формат ошибки (OpenAI-совместимый) + +```jsonc +{ + "error": { + "message": "no healthy model available for tier 'high'", + "type": "upstream_unavailable", // invalid_request_error | authentication_error | rate_limit_error | upstream_unavailable | internal_error + "code": "no_healthy_model", + "param": null + } +} +``` + +OpenAI/Anthropic SDK парсят такой конверт нативно. Сопоставление статусов: + +| Тип | HTTP | retriable | +|---|---|---| +| `invalid_request_error` | 400 | нет | +| `authentication_error` | 401 | нет | +| `rate_limit_error` | 429 | да | +| `upstream_unavailable` | 502/503 | да | +| `internal_error` | 500 | да | + +### 8.6 Учёт стоимости + +`usage` отдаётся в формате протокола (OpenAI/Anthropic). Дополнительно — стоимость +в заголовке `X-Cortiq-Cost-Usd` и в `cortiq.cost_usd` (если включено `cortiq.echo`). +Цена считается из `price_in`/`price_out` модели в конфиге × токены. diff --git a/docs/ROUTING.md b/docs/ROUTING.md new file mode 100644 index 0000000..7f33ff7 --- /dev/null +++ b/docs/ROUTING.md @@ -0,0 +1,164 @@ +*Read this in [Русский](ROUTING.ru.md).* + +# Routing and Cost + +How Cortiq Gateway translates a router decision (`task_label` + `complexity.tier`) into +selection of a specific model from your pool — and how to make this **cost-aware**: +cheap tasks stay local, expensive ones go to the cloud. + +--- + +## 1. Base model: complexity tier → model pool + +cortiq-router returns a complexity tier (`low` / `medium` / `high`, configurable in the +router). The `[routing]` table maps each tier to an **ordered list** of models — which +serves simultaneously as a priority order and a fallback chain. + +```toml +[routing] +low = ["local-qwen"] # simple → local only (free) +medium = ["gpt-4o-mini", "local-qwen"] # medium → cheap hosted, fall back to local +high = ["claude-opus", "gpt-4o-mini"] # complex → expensive model, fall back to mid +default = "gpt-4o-mini" # if the router is unavailable +``` + +Selection algorithm: + +``` +1. tier := router.complexity.tier (or the default tier if router is unavailable) +2. candidates := routing[tier] (ordered list of model_id) +3. for each model_id in order: + if the model is healthy AND supports the required capabilities (tools/vision): + select it → done +4. if all are unavailable: try the next tier down/up per policy, or return error 503 +``` + +--- + +## 2. Universal pool: cheap local + expensive hosted + +The primary developer scenario: mix a **free local** model with a **paid cloud** API, +and let the gateway decide which one to use. + +```toml +# Local model on vLLM / llama.cpp / Ollama (OpenAI-compatible endpoint) +[[models]] +id = "local-qwen" +provider = "openai" +base_url = "http://localhost:8000/v1" +model = "qwen2.5-7b-instruct" +cost_tier = "cheap" +price_in = 0.0 # local → 0 +price_out = 0.0 +caps = ["tools"] # capabilities (checked during selection) + +# Cheap cloud +[[models]] +id = "gpt-4o-mini" +provider = "openai" +base_url = "https://api.openai.com/v1" +model = "gpt-4o-mini" +api_key_env = "OPENAI_API_KEY" +cost_tier = "mid" +price_in = 0.15 # $/1M input tokens +price_out = 0.60 + +# Expensive cloud for complex tasks +[[models]] +id = "claude-opus" +provider = "anthropic" +base_url = "https://api.anthropic.com" +model = "claude-opus-4" +api_key_env = "ANTHROPIC_API_KEY" +cost_tier = "expensive" +price_in = 15.0 +price_out = 75.0 +caps = ["tools", "vision"] +``` + +Because both `local-qwen` and `gpt-4o-mini` use `provider = "openai"`, the gateway does +not care where the model is physically located — **local servers already speak the OpenAI +API**. This is what makes the proxy truly universal. + +--- + +## 3. Cost-aware mode (optional) + +Instead of a fixed table, you can enable selection by **budget/price** (v0.2): + +```toml +[routing.policy] +mode = "cost_aware" # fixed_table | cost_aware +# in cost_aware mode the gateway picks the cheapest model for each tier +# that meets the minimum quality class for that tier: +min_class = { low = "cheap", medium = "mid", high = "expensive" } +# upper price bound per request (guard against expensive calls) +max_cost_usd_per_request = 0.50 +``` + +Logic: among models that are at least `min_class[tier]` and within the price cap, the +cheapest available model is selected. This yields the "minimally sufficient" model for +the task complexity. + +--- + +## 4. Pinning and passthrough + +- **Passthrough.** `model = "local-qwen"` (a real id) — no router call; direct invocation. + Useful when the client already knows what it wants. +- **Profile pinning.** `model = "cortiq-auto:cost-saver"` — routing with a specific router + policy profile (escalates less often → cheaper). +- **Router version pinning** (v0.4). To prevent routing behavior from drifting due to + router self-learning, you can pin `model_version` — the agent gets reproducible routing. + +--- + +## 5. Text extraction for routing (multi-turn) + +An agent request is not a single string but a system prompt + history + tools. What to +send to the router for classification is configurable: + +```toml +[route] +text_strategy = "last_user" # last_user | concat_all | last_user_plus_system +max_chars = 4000 # truncate long context (cost/DoS protection) +cache_ttl = "60s" # cache routing decisions by text hash +profile = "balanced" # default policy profile +``` + +| Strategy | What is classified | When to use | +|---|---|---| +| `last_user` | last user message | default; cheap and accurate for most agents | +| `last_user_plus_system` | system prompt + last user message | when the role is set by the system prompt | +| `concat_all` | full conversation (truncated) | multi-turn with meaning spread across history | + +--- + +## 6. Failover and circuit breaker + +- **Failover.** On 5xx / timeout / `overloaded` from a provider — try the next model in + the list. +- **Circuit breaker.** After `breaker.threshold` consecutive errors, the model is marked + "open" for `breaker.cooldown`; requests skip it. Half-open: one probe request after the + cooldown expires. +- **Router down.** `routing.default` is used; the request does not fail (soft degradation). + +```toml +[breaker] +threshold = 5 +cooldown = "30s" +``` + +--- + +## 7. Feedback loop (optional, v0.4) + +When enabled, the gateway can send a `/v1/feedback` signal to the router after a successful +completion (e.g. based on the result of agent-side response validation) — the router will +fine-tune the task mask. Over time this makes routing fit your specific pool more precisely. + +```toml +[feedback] +enabled = false +# the ground-truth source is set by the integrator (e.g. the X-Cortiq-Correct-Label header) +``` diff --git a/docs/ROUTING.ru.md b/docs/ROUTING.ru.md new file mode 100644 index 0000000..b546fc3 --- /dev/null +++ b/docs/ROUTING.ru.md @@ -0,0 +1,162 @@ +*Read this in [English](ROUTING.md).* + +# Маршрутизация и стоимость + +Как Cortiq Gateway превращает решение роутера (`task_label` + `complexity.tier`) в +выбор конкретной модели из вашего пула — и как сделать это **cost-aware**: +дешёвое локально, дорогое в облаке. + +--- + +## 1. Базовая модель: полоса сложности → пул моделей + +cortiq-router возвращает полосу сложности (`low` / `medium` / `high`, настраивается +в роутере). Таблица `[routing]` сопоставляет полосе **упорядоченный список** моделей — +это одновременно приоритет и цепочка fallback. + +```toml +[routing] +low = ["local-qwen"] # простое → только локально (бесплатно) +medium = ["gpt-4o-mini", "local-qwen"] # средне → дешёвый хост, откат на локальное +high = ["claude-opus", "gpt-4o-mini"] # сложно → дорогая модель, откат на средн. +default = "gpt-4o-mini" # если роутер недоступен +``` + +Алгоритм выбора: + +``` +1. tier := router.complexity.tier (или default-полоса, если роутер недоступен) +2. candidates := routing[tier] (упорядоченный список model_id) +3. для каждого model_id по порядку: + если модель healthy И поддерживает нужные возможности (tools/vision): + выбрать её → выход +4. если все недоступны: следующая полоса вниз/вверх по политике, либо ошибка 503 +``` + +--- + +## 2. Универсальный пул: локальные дешёвые + хостовые дорогие + +Главный сценарий для разработчика: смешать **бесплатную локальную** модель и +**платный облачный** API, и пусть шлюз сам решает, что куда. + +```toml +# Локальная модель на vLLM / llama.cpp / Ollama (OpenAI-совместимый endpoint) +[[models]] +id = "local-qwen" +provider = "openai" +base_url = "http://localhost:8000/v1" +model = "qwen2.5-7b-instruct" +cost_tier = "cheap" +price_in = 0.0 # локально → 0 +price_out = 0.0 +caps = ["tools"] # что умеет (для проверки на этапе выбора) + +# Дешёвый облачный +[[models]] +id = "gpt-4o-mini" +provider = "openai" +base_url = "https://api.openai.com/v1" +model = "gpt-4o-mini" +api_key_env = "OPENAI_API_KEY" +cost_tier = "mid" +price_in = 0.15 # $/1M входных токенов +price_out = 0.60 + +# Дорогой облачный для сложного +[[models]] +id = "claude-opus" +provider = "anthropic" +base_url = "https://api.anthropic.com" +model = "claude-opus-4" +api_key_env = "ANTHROPIC_API_KEY" +cost_tier = "expensive" +price_in = 15.0 +price_out = 75.0 +caps = ["tools", "vision"] +``` + +Поскольку `local-qwen` и `gpt-4o-mini` оба `provider = "openai"`, шлюзу не важно, +где модель физически — **локальные серверы уже говорят на OpenAI API**. Это и делает +прокси универсальным. + +--- + +## 3. Cost-aware режим (опционально) + +Вместо жёсткой таблицы можно включить выбор по **бюджету/цене** (v0.2): + +```toml +[routing.policy] +mode = "cost_aware" # fixed_table | cost_aware +# при cost_aware шлюз для каждой полосы берёт самую дешёвую модель, +# удовлетворяющую минимальному «классу качества» полосы: +min_class = { low = "cheap", medium = "mid", high = "expensive" } +# верхняя граница цены за запрос (страховка от дорогих вызовов) +max_cost_usd_per_request = 0.50 +``` + +Логика: среди моделей не ниже `min_class[tier]` и не дороже лимита выбирается самая +дешёвая доступная. Это даёт «минимально достаточную» модель под сложность задачи. + +--- + +## 4. Pinning и passthrough + +- **Passthrough.** `model = "local-qwen"` (реальный id) — без обращения к роутеру, + прямой вызов. Полезно, когда клиент сам знает, что хочет. +- **Pinning профиля.** `model = "cortiq-auto:cost-saver"` — роутинг с конкретным + policy-профилем роутера (реже эскалирует → дешевле). +- **Pinning версии роутера** (v0.4). Чтобы поведение не «плыло» из-за самообучения + роутера, можно зафиксировать `model_version` — агент получает воспроизводимый роутинг. + +--- + +## 5. Извлечение текста для маршрутизации (мультитёрн) + +Агентский запрос — это не одна строка, а system + история + tools. Что слать роутеру +на классификацию, настраивается: + +```toml +[route] +text_strategy = "last_user" # last_user | concat_all | last_user_plus_system +max_chars = 4000 # усечение длинного контекста (стоимость/DoS) +cache_ttl = "60s" # кэш решения по хэшу текста +profile = "balanced" # дефолтный policy-профиль +``` + +| Стратегия | Что классифицируем | Когда | +|---|---|---| +| `last_user` | последнее сообщение пользователя | по умолчанию; дёшево и точно для большинства агентов | +| `last_user_plus_system` | system + последнее user | когда роль задаётся системным промптом | +| `concat_all` | весь диалог (усечённый) | мультитёрн со смыслом, размазанным по истории | + +--- + +## 6. Failover и circuit breaker + +- **Failover.** При 5xx/таймауте/`overloaded` от провайдера — следующая модель списка. +- **Circuit breaker.** После `breaker.threshold` ошибок подряд модель помечается + «открытой» на `breaker.cooldown`, запросы её минуют. Полупроброс — один пробный + запрос после кулдауна. +- **Router down.** Берётся `routing.default`, запрос не падает (мягкая деградация). + +```toml +[breaker] +threshold = 5 +cooldown = "30s" +``` + +--- + +## 7. Петля обратной связи (опционально, v0.4) + +Если включено, шлюз после успешного выполнения может отправить в роутер +`/v1/feedback` сигнал (например, по результату валидации ответа агентом) — роутер +дообучит маску задачи. Так маршрутизация со временем точнее ложится на ваш пул. + +```toml +[feedback] +enabled = false +# источник истины задаёт интегратор (например, заголовок X-Cortiq-Correct-Label) +``` diff --git a/docs/screenshots/dashboard.png b/docs/screenshots/dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..d8f09ef69d825bd23a51c654f72851e841795338 GIT binary patch literal 235339 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ξ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�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⪙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 ZRp&O> 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 literal 0 HcmV?d00001 diff --git a/docs/screenshots/models.png b/docs/screenshots/models.png new file mode 100644 index 0000000000000000000000000000000000000000..a7ae94ef03f3b6fb39fc06fbf08d8e6aab7d8a65 GIT binary patch literal 149399 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

4>pZ)PTX{s=K;%1Rpywl&`D*80vX4o{h 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

Fi~Qn)JI3uO_Absg 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 Response { + match WebAssets::get(path) { + Some(content) => { + let mime = mime_guess::from_path(path).first_or_octet_stream(); + ( + [(header::CONTENT_TYPE, mime.as_ref())], + content.data.into_owned(), + ) + .into_response() + } + None => { + // SPA: unknown path under /admin → serve index.html + match WebAssets::get("index.html") { + Some(content) => ( + [(header::CONTENT_TYPE, "text/html; charset=utf-8")], + content.data.into_owned(), + ) + .into_response(), + None => (StatusCode::NOT_FOUND, "not found").into_response(), + } + } + } +} + +/// Application-wide fallback: serves `/admin/*`; everything else → 404 JSON. +pub async fn fallback(uri: Uri) -> Response { + let path = uri.path(); + if let Some(rest) = path.strip_prefix("/admin") { + let rest = rest.trim_start_matches('/'); + let file = if rest.is_empty() { "index.html" } else { rest }; + serve_file(file) + } else { + ( + StatusCode::NOT_FOUND, + axum::Json(serde_json::json!({ + "error": { "message": "not found", "type": "not_found", "code": "not_found" } + })), + ) + .into_response() + } +} diff --git a/src/admin/mod.rs b/src/admin/mod.rs new file mode 100644 index 0000000..d8d3aa0 --- /dev/null +++ b/src/admin/mod.rs @@ -0,0 +1,756 @@ +//! Admin API for the web management panel (`/admin/api/*`) + SPA serving (`/admin/*`). +//! +//! All endpoints under `/admin/api` are protected by a Bearer admin token. Config changes +//! go through `AppState::reload` (validation → build `Live` → atomic TOML write +//! → swap), so they are applied without a restart. Secrets are never returned — +//! only their presence status. + +pub mod assets; + +use crate::config::{ + AdminCfg, ApiKeyCfg, BreakerCfg, Config, CortiqCfg, LogCfg, ModelCfg, ProtocolsCfg, RouteCfg, + RouterCfg, RoutingCfg, RoutingPolicy, StatsCfg, TelemetryCfg, TierTargets, +}; +use crate::model::{ChatRequest, GenParams, Message, RequestMeta, RoutingDirective}; +use crate::state::SharedState; +use crate::stats::parse_duration_secs; +use axum::{ + extract::{Path, Query, Request, State}, + http::{header, StatusCode}, + middleware::{self, Next}, + response::{IntoResponse, Response}, + routing::{get, post}, + Json, Router, +}; +use serde::Deserialize; +use serde_json::{json, Value}; +use std::collections::HashMap; +use std::time::Instant; + +// ───────────────────────────── common types / helpers ─────────────────────── + +type ApiResult = Result, ApiError>; + +pub struct ApiError { + status: StatusCode, + message: String, +} +impl ApiError { + fn bad(msg: impl Into) -> Self { + Self { + status: StatusCode::BAD_REQUEST, + message: msg.into(), + } + } + fn not_found(msg: impl Into) -> Self { + Self { + status: StatusCode::NOT_FOUND, + message: msg.into(), + } + } +} +impl From for ApiError { + fn from(e: anyhow::Error) -> Self { + Self::bad(e.to_string()) + } +} +impl IntoResponse for ApiError { + fn into_response(self) -> Response { + ( + self.status, + Json(json!({"error": {"message": self.message, "type": "admin_error"}})), + ) + .into_response() + } +} + +fn ok(v: Value) -> ApiResult { + Ok(Json(v)) +} + +fn current_cfg(state: &SharedState) -> Config { + state.live().cfg.clone() +} + +/// Random hex token from `n_bytes` bytes of cryptographic randomness. +pub fn random_token(n_bytes: usize) -> String { + let mut buf = vec![0u8; n_bytes]; + if let Ok(mut f) = std::fs::File::open("/dev/urandom") { + use std::io::Read; + let _ = f.read_exact(&mut buf); + } else { + let t = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap_or_default() + .as_nanos(); + for (i, b) in buf.iter_mut().enumerate() { + *b = ((t >> ((i % 16) * 8)) as u8) ^ (i as u8).wrapping_mul(31); + } + } + buf.iter().map(|b| format!("{b:02x}")).collect() +} + +fn constant_time_eq(a: &[u8], b: &[u8]) -> bool { + if a.len() != b.len() { + return false; + } + let mut diff = 0u8; + for (x, y) in a.iter().zip(b.iter()) { + diff |= x ^ y; + } + diff == 0 +} + +fn mask_key(key: &str) -> String { + let n = key.chars().count(); + if n <= 8 { + return "•".repeat(n.max(3)); + } + let head: String = key.chars().take(6).collect(); + let tail: String = key.chars().skip(n - 4).collect(); + format!("{head}…{tail}") +} + +fn tiers_to_map(routing: &RoutingCfg) -> HashMap> { + routing + .tiers + .iter() + .map(|(k, v)| { + let list = match v { + TierTargets::List(l) => l.clone(), + TierTargets::One(s) => vec![s.clone()], + }; + (k.clone(), list) + }) + .collect() +} + +fn parse_routing(model: &str) -> RoutingDirective { + if let Some(rest) = model.strip_prefix("cortiq-auto") { + let profile = rest.strip_prefix(':').map(|p| p.to_string()); + RoutingDirective::Auto { profile } + } else { + RoutingDirective::Pinned { + model_id: model.to_string(), + } + } +} + +// ───────────────────────────── router ─────────────────────────────────────── + +/// Admin API routes (token-protected). Mounted into the main router. +/// The token is captured in a middleware closure so it does not depend on State. +pub fn api_routes(admin_token: String) -> Router { + Router::new() + .route("/admin/api/health", get(health)) + .route("/admin/api/meta", get(meta)) + .route("/admin/api/config", get(get_config).put(put_config)) + .route("/admin/api/models", get(list_models).post(create_model)) + .route( + "/admin/api/models/:id", + axum::routing::put(update_model).delete(delete_model), + ) + .route("/admin/api/models/:id/probe", post(probe_model)) + .route("/admin/api/routing", get(get_routing).put(put_routing)) + .route( + "/admin/api/protocols", + get(get_protocols).put(put_protocols), + ) + .route("/admin/api/settings", get(get_settings).put(put_settings)) + .route("/admin/api/keys", get(list_keys).post(create_key)) + .route("/admin/api/keys/:key", axum::routing::delete(delete_key)) + .route( + "/admin/api/secrets", + get(list_secrets).put(set_secret).delete(clear_secret), + ) + .route("/admin/api/stats", get(get_stats)) + .route("/admin/api/requests", get(get_requests)) + .route("/admin/api/test", post(run_test)) + .route_layer(middleware::from_fn(move |req: Request, next: Next| { + let expected = admin_token.clone(); + async move { auth(expected, req, next).await } + })) +} + +/// Extract Bearer admin token from the `Authorization` header. +fn bearer_token(req: &Request) -> String { + req.headers() + .get(header::AUTHORIZATION) + .and_then(|v| v.to_str().ok()) + .map(|v| { + v.strip_prefix("Bearer ") + .or_else(|| v.strip_prefix("bearer ")) + .unwrap_or(v) + .trim() + }) + .unwrap_or("") + .to_string() +} + +/// Admin authentication middleware (constant-time comparison). +async fn auth(expected: String, req: Request, next: Next) -> Response { + let token = bearer_token(&req); + if !expected.is_empty() && constant_time_eq(token.as_bytes(), expected.as_bytes()) { + next.run(req).await + } else { + ( + StatusCode::UNAUTHORIZED, + Json(json!({"error": {"message": "invalid or missing admin token", "type": "authentication_error", "code": "unauthorized"}})), + ) + .into_response() + } +} + +// ───────────────────────────── metrics ────────────────────────────────────── + +/// `GET /metrics` (Prometheus). Exposed when `telemetry.metrics = true`. +pub async fn metrics(State(state): State) -> Response { + let live = state.live(); + if !live.cfg.telemetry.metrics { + return (StatusCode::NOT_FOUND, "metrics disabled").into_response(); + } + let body = state.stats.prometheus(); + ([(header::CONTENT_TYPE, "text/plain; version=0.0.4")], body).into_response() +} + +// ───────────────────────────── health / meta ─────────────────────────────── + +async fn probe_router(url: &str) -> (bool, u64) { + let client = match reqwest::Client::builder() + .timeout(std::time::Duration::from_millis(1500)) + .danger_accept_invalid_certs(true) + .build() + { + Ok(c) => c, + Err(_) => return (false, 0), + }; + let started = Instant::now(); + let target = format!("{}/healthz", url.trim_end_matches('/')); + let ok = client + .get(&target) + .send() + .await + .map(|r| r.status().as_u16() < 500) + .unwrap_or(false); + (ok, started.elapsed().as_millis() as u64) +} + +async fn health(State(state): State) -> ApiResult { + let live = state.live(); + let (router_ok, router_ms) = probe_router(&live.cfg.router.url).await; + let models: Vec = live + .cfg + .models + .iter() + .map(|m| { + let key = match &m.api_key_env { + Some(env) => state.secrets.source(env), + None => "none", + }; + json!({ + "id": m.id, + "provider": m.provider, + "model": m.model, + "kind": m.kind, + "cost_tier": m.cost_tier, + "key_source": key, + "in_registry": live.registry.get(&m.id).is_some(), + }) + }) + .collect(); + ok(json!({ + "ok": true, + "version": env!("CARGO_PKG_VERSION"), + "listen": live.cfg.listen, + "router": { "url": live.cfg.router.url, "reachable": router_ok, "latency_ms": router_ms }, + "models": models, + })) +} + +async fn meta() -> ApiResult { + ok(json!({ + "version": env!("CARGO_PKG_VERSION"), + "providers": ["openai", "anthropic", "ollama", "http"], + "provider_impl": { "openai": true, "ollama": true, "http": true, "anthropic": false }, + "cost_tiers": ["cheap", "mid", "expensive"], + "kinds": ["chat", "embedding"], + "profiles": ["cost-saver", "balanced", "quality-first"], + "text_strategies": ["last_user", "last_user_plus_system", "concat_all"], + "policy_modes": ["fixed_table", "cost_aware"], + "tiers": ["low", "medium", "high"], + "caps": ["tools", "vision"], + "protocols_impl": { + "openai_chat": true, "openai_completions": false, "openai_embeddings": false, + "openai_models": false, "anthropic_messages": false, "mcp": false, "native_passthrough": false + }, + "languages": ["en", "ru", "de", "fr", "es", "zh", "tr"], + })) +} + +// ───────────────────────────── config ────────────────────────────────────── + +async fn get_config(State(state): State) -> ApiResult { + let cfg = current_cfg(&state); + ok(serde_json::to_value(&cfg).map_err(|e| ApiError::bad(e.to_string()))?) +} + +async fn put_config(State(state): State, Json(cfg): Json) -> ApiResult { + state.reload(cfg)?; + ok(json!({ "ok": true })) +} + +// ───────────────────────────── models ────────────────────────────────────── + +async fn list_models(State(state): State) -> ApiResult { + let live = state.live(); + let models: Vec = live + .cfg + .models + .iter() + .map(|m| { + let mut v = serde_json::to_value(m).unwrap_or(json!({})); + let key_source = match &m.api_key_env { + Some(env) => state.secrets.source(env), + None => "none", + }; + v["key_source"] = json!(key_source); + v + }) + .collect(); + ok(json!({ "models": models })) +} + +async fn create_model(State(state): State, Json(m): Json) -> ApiResult { + let mut cfg = current_cfg(&state); + if cfg.models.iter().any(|x| x.id == m.id) { + return Err(ApiError::bad(format!("model id '{}' already exists", m.id))); + } + cfg.models.push(m); + state.reload(cfg)?; + ok(json!({ "ok": true })) +} + +async fn update_model( + State(state): State, + Path(id): Path, + Json(m): Json, +) -> ApiResult { + let mut cfg = current_cfg(&state); + let idx = cfg + .models + .iter() + .position(|x| x.id == id) + .ok_or_else(|| ApiError::not_found(format!("model '{id}' not found")))?; + // if the id was renamed — must not conflict with an existing one + if m.id != id && cfg.models.iter().any(|x| x.id == m.id) { + return Err(ApiError::bad(format!("model id '{}' already exists", m.id))); + } + cfg.models[idx] = m; + state.reload(cfg)?; + ok(json!({ "ok": true })) +} + +async fn delete_model(State(state): State, Path(id): Path) -> ApiResult { + let mut cfg = current_cfg(&state); + let before = cfg.models.len(); + cfg.models.retain(|x| x.id != id); + if cfg.models.len() == before { + return Err(ApiError::not_found(format!("model '{id}' not found"))); + } + state.reload(cfg)?; + ok(json!({ "ok": true })) +} + +async fn probe_model(State(state): State, Path(id): Path) -> ApiResult { + let live = state.live(); + let mcfg = live + .cfg + .models + .iter() + .find(|m| m.id == id) + .ok_or_else(|| ApiError::not_found(format!("model '{id}' not found")))? + .clone(); + + if mcfg.provider == "anthropic" { + return ok(json!({ + "ok": false, + "error": "anthropic provider not yet implemented (planned v0.2)", + })); + } + let provider = live + .registry + .get(&id) + .ok_or_else(|| ApiError::bad(format!("model '{id}' has no runtime provider")))?; + + let req = ChatRequest { + routing: RoutingDirective::Pinned { + model_id: id.clone(), + }, + messages: vec![Message { + role: "user".into(), + content: "ping".into(), + tool_calls: vec![], + }], + tools: vec![], + params: GenParams { + temperature: Some(0.0), + max_tokens: Some(1), + ..Default::default() + }, + stream: false, + meta: RequestMeta { + protocol: "probe".into(), + ..Default::default() + }, + }; + let started = Instant::now(); + let res = provider.chat(req).await; + let latency_ms = started.elapsed().as_millis() as u64; + match res { + Ok(_) => ok(json!({ "ok": true, "latency_ms": latency_ms })), + Err(e) => ok(json!({ "ok": false, "latency_ms": latency_ms, "error": e.to_string() })), + } +} + +// ───────────────────────────── routing ───────────────────────────────────── + +async fn get_routing(State(state): State) -> ApiResult { + let live = state.live(); + ok(json!({ + "tiers": tiers_to_map(&live.cfg.routing), + "default": live.cfg.routing.default, + "policy": live.cfg.routing.policy, + })) +} + +#[derive(Deserialize)] +struct RoutingBody { + #[serde(default)] + tiers: HashMap>, + default: String, + #[serde(default)] + policy: RoutingPolicy, +} + +async fn put_routing(State(state): State, Json(body): Json) -> ApiResult { + let mut cfg = current_cfg(&state); + cfg.routing = RoutingCfg { + tiers: body + .tiers + .into_iter() + .map(|(k, v)| (k, TierTargets::List(v))) + .collect(), + default: body.default, + policy: body.policy, + }; + state.reload(cfg)?; + ok(json!({ "ok": true })) +} + +// ───────────────────────────── protocols ─────────────────────────────────── + +async fn get_protocols(State(state): State) -> ApiResult { + let live = state.live(); + ok(serde_json::to_value(&live.cfg.protocols).unwrap_or(json!({}))) +} + +async fn put_protocols(State(state): State, Json(p): Json) -> ApiResult { + let mut cfg = current_cfg(&state); + cfg.protocols = p; + state.reload(cfg)?; + ok(json!({ "ok": true })) +} + +// ───────────────────────────── settings ──────────────────────────────────── + +async fn get_settings(State(state): State) -> ApiResult { + let live = state.live(); + let c = &live.cfg; + // admin section without token value (not stored here — only the env name) + ok(json!({ + "listen": c.listen, + "router": c.router, + "route": c.route, + "breaker": c.breaker, + "log": c.log, + "telemetry": c.telemetry, + "cortiq": c.cortiq, + "stats": c.stats, + "admin": c.admin, + })) +} + +#[derive(Deserialize)] +struct SettingsBody { + listen: Option, + router: Option, + route: Option, + breaker: Option, + log: Option, + telemetry: Option, + cortiq: Option, + stats: Option, + admin: Option, +} + +async fn put_settings(State(state): State, Json(b): Json) -> ApiResult { + let mut cfg = current_cfg(&state); + let mut needs_restart = false; + if let Some(v) = b.listen { + if v != cfg.listen { + needs_restart = true; + } + cfg.listen = v; + } + if let Some(v) = b.router { + cfg.router = v; + } + if let Some(v) = b.route { + cfg.route = v; + } + if let Some(v) = b.breaker { + cfg.breaker = v; + } + if let Some(v) = b.log { + cfg.log = v; + } + if let Some(v) = b.telemetry { + cfg.telemetry = v; + } + if let Some(v) = b.cortiq { + cfg.cortiq = v; + } + if let Some(v) = b.stats { + cfg.stats = v; + } + if let Some(v) = b.admin { + if v.listen != cfg.admin.listen { + needs_restart = true; + } + cfg.admin = v; + } + state.reload(cfg)?; + ok(json!({ "ok": true, "needs_restart": needs_restart })) +} + +// ───────────────────────────── keys ──────────────────────────────────────── + +async fn list_keys(State(state): State) -> ApiResult { + let live = state.live(); + let keys: Vec = live + .cfg + .api_keys + .iter() + .map(|k| { + json!({ + "key": k.key, + "key_masked": mask_key(&k.key), + "account": k.account, + "rate_per_min": k.rate_per_min, + "allow_models": k.allow_models, + }) + }) + .collect(); + ok(json!({ "keys": keys, "open_mode": live.cfg.api_keys.is_empty() })) +} + +#[derive(Deserialize)] +struct NewKey { + #[serde(default)] + key: String, + account: String, + #[serde(default)] + rate_per_min: u32, + #[serde(default)] + allow_models: Vec, +} + +async fn create_key(State(state): State, Json(b): Json) -> ApiResult { + let key = if b.key.trim().is_empty() { + format!("sk-gw-{}", random_token(18)) + } else { + b.key.trim().to_string() + }; + let mut cfg = current_cfg(&state); + if cfg.api_keys.iter().any(|k| k.key == key) { + return Err(ApiError::bad("key already exists")); + } + cfg.api_keys.push(ApiKeyCfg { + key: key.clone(), + account: b.account, + rate_per_min: b.rate_per_min, + allow_models: b.allow_models, + }); + state.reload(cfg)?; + // show the full key only once + ok(json!({ "ok": true, "key": key })) +} + +async fn delete_key(State(state): State, Path(key): Path) -> ApiResult { + let mut cfg = current_cfg(&state); + let before = cfg.api_keys.len(); + cfg.api_keys.retain(|k| k.key != key); + if cfg.api_keys.len() == before { + return Err(ApiError::not_found("key not found")); + } + state.reload(cfg)?; + ok(json!({ "ok": true })) +} + +// ───────────────────────────── secrets ───────────────────────────────────── + +async fn list_secrets(State(state): State) -> ApiResult { + let live = state.live(); + // collect all env names referenced in the config + let mut names: Vec = Vec::new(); + for m in &live.cfg.models { + if let Some(env) = &m.api_key_env { + if !names.contains(env) { + names.push(env.clone()); + } + } + } + if let Some(env) = &live.cfg.router.api_key_env { + if !names.contains(env) { + names.push(env.clone()); + } + } + let secrets: Vec = names + .iter() + .map(|n| json!({ "name": n, "source": state.secrets.source(n) })) + .collect(); + ok(json!({ "secrets": secrets })) +} + +#[derive(Deserialize)] +struct SecretBody { + name: String, + value: String, +} + +async fn set_secret(State(state): State, Json(b): Json) -> ApiResult { + if b.name.trim().is_empty() { + return Err(ApiError::bad("secret name is required")); + } + state.secrets.set(b.name.trim(), &b.value)?; + // rebuild providers with the new key (without writing TOML) + state.rebuild()?; + ok(json!({ "ok": true })) +} + +#[derive(Deserialize)] +struct NameQuery { + name: String, +} + +async fn clear_secret(State(state): State, Query(q): Query) -> ApiResult { + state.secrets.clear(q.name.trim())?; + state.rebuild()?; + ok(json!({ "ok": true })) +} + +// ───────────────────────────── stats / requests ──────────────────────────── + +#[derive(Deserialize)] +struct StatsQuery { + #[serde(default)] + range: Option, + #[serde(default)] + groupby: Option, +} + +async fn get_stats(State(state): State, Query(q): Query) -> ApiResult { + let range_secs = q + .range + .as_deref() + .and_then(parse_duration_secs) + .unwrap_or(24 * 3600); + let groupby = q.groupby.as_deref().unwrap_or("model"); + ok(state.stats.snapshot(range_secs, groupby)) +} + +#[derive(Deserialize)] +struct RecentQuery { + #[serde(default)] + limit: Option, + #[serde(default)] + offset: Option, +} + +async fn get_requests(State(state): State, Query(q): Query) -> ApiResult { + let limit = q.limit.unwrap_or(50).min(500); + let offset = q.offset.unwrap_or(0); + let items = state.stats.recent(limit, offset); + ok(json!({ "requests": items })) +} + +// ───────────────────────────── playground (test) ─────────────────────────── + +#[derive(Deserialize)] +struct TestBody { + #[serde(default = "default_test_model")] + model: String, + messages: Vec, + #[serde(default)] + temperature: Option, + #[serde(default)] + max_tokens: Option, +} +fn default_test_model() -> String { + "cortiq-auto".into() +} + +async fn run_test(State(state): State, Json(b): Json) -> ApiResult { + if b.messages.is_empty() { + return Err(ApiError::bad("messages must not be empty")); + } + let req = ChatRequest { + routing: parse_routing(&b.model), + messages: b.messages, + tools: vec![], + params: GenParams { + temperature: b.temperature, + max_tokens: b.max_tokens, + ..Default::default() + }, + stream: false, + meta: RequestMeta { + account: "playground".into(), + protocol: "playground".into(), + ..Default::default() + }, + }; + let started = Instant::now(); + let res = state.pipeline.run(req, &state).await; + let latency_ms = started.elapsed().as_millis() as u64; + match res { + Ok(resp) => { + let answer = resp + .choices + .first() + .map(|c| c.message.content.clone()) + .unwrap_or_default(); + ok(json!({ + "ok": true, + "latency_ms": latency_ms, + "answer": answer, + "model_used": resp.model_used, + "usage": { + "prompt_tokens": resp.usage.prompt_tokens, + "completion_tokens": resp.usage.completion_tokens, + "total_tokens": resp.usage.total_tokens, + }, + "cortiq": { + "task_label": resp.cortiq.task_label, + "complexity": { "score": resp.cortiq.complexity_score, "tier": resp.cortiq.complexity_tier }, + "selected_model": resp.cortiq.selected_model, + "route_source": resp.cortiq.route_source, + "router_request_id": resp.cortiq.router_request_id, + "cost_usd": resp.cortiq.cost_usd, + "failover": resp.cortiq.failover, + }, + })) + } + Err(e) => ok(json!({ "ok": false, "latency_ms": latency_ms, "error": e.to_string() })), + } +} diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..a10ff34 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,474 @@ +//! Configuration loading from TOML. Structs mirror config/gateway.example.toml. +//! Secrets are read from environment variables by the names given in `*_env` fields. + +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Config { + pub listen: String, + pub router: RouterCfg, + #[serde(default)] + pub route: RouteCfg, + #[serde(default)] + pub models: Vec, + pub routing: RoutingCfg, + #[serde(default)] + pub breaker: BreakerCfg, + #[serde(default)] + pub protocols: ProtocolsCfg, + #[serde(default)] + pub cortiq: CortiqCfg, + #[serde(default)] + pub api_keys: Vec, + #[serde(default)] + pub idempotency: IdempotencyCfg, + #[serde(default)] + pub log: LogCfg, + #[serde(default)] + pub telemetry: TelemetryCfg, + #[serde(default)] + pub admin: AdminCfg, + #[serde(default)] + pub stats: StatsCfg, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct RouterCfg { + pub url: String, + #[serde(default = "default_router_timeout")] + pub timeout_ms: u64, + #[serde(default = "default_verify_tls")] + pub verify_tls: bool, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub api_key_env: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub taxonomy_id: Option, +} +fn default_router_timeout() -> u64 { + 800 +} +fn default_verify_tls() -> bool { + true +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct RouteCfg { + #[serde(default = "default_text_strategy")] + pub text_strategy: String, + #[serde(default = "default_max_chars")] + pub max_chars: usize, + #[serde(default = "default_cache_ttl")] + pub cache_ttl: String, + #[serde(default = "default_profile")] + pub profile: String, +} +impl Default for RouteCfg { + fn default() -> Self { + Self { + text_strategy: default_text_strategy(), + max_chars: default_max_chars(), + cache_ttl: default_cache_ttl(), + profile: default_profile(), + } + } +} +fn default_text_strategy() -> String { + "last_user".into() +} +fn default_max_chars() -> usize { + 4000 +} +fn default_cache_ttl() -> String { + "60s".into() +} +fn default_profile() -> String { + "balanced".into() +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct ModelCfg { + pub id: String, + pub provider: String, // openai | anthropic | ollama | http + pub base_url: String, + pub model: String, + #[serde(default)] + pub cost_tier: String, + #[serde(default)] + pub price_in: f64, + #[serde(default)] + pub price_out: f64, + #[serde(default = "default_kind")] + pub kind: String, // chat | embedding + #[serde(default, skip_serializing_if = "Option::is_none")] + pub api_key_env: Option, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub caps: Vec, +} +fn default_kind() -> String { + "chat".into() +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct RoutingCfg { + #[serde(flatten)] + pub tiers: HashMap, + pub default: String, + #[serde(default)] + pub policy: RoutingPolicy, +} + +/// A routing tier is either a list of model_ids or the string `default`. +/// (`default` is handled by a separate field; only tier lists appear here.) +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(untagged)] +pub enum TierTargets { + List(Vec), + One(String), +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct RoutingPolicy { + #[serde(default = "default_mode")] + pub mode: String, // fixed_table | cost_aware + #[serde(default, skip_serializing_if = "Option::is_none")] + pub max_cost_usd_per_request: Option, + #[serde(default, skip_serializing_if = "HashMap::is_empty")] + pub min_class: HashMap, +} +impl Default for RoutingPolicy { + fn default() -> Self { + Self { + mode: default_mode(), + min_class: HashMap::new(), + max_cost_usd_per_request: None, + } + } +} +fn default_mode() -> String { + "fixed_table".into() +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct BreakerCfg { + #[serde(default = "default_breaker_threshold")] + pub threshold: u32, + #[serde(default = "default_breaker_cooldown")] + pub cooldown: String, +} +impl Default for BreakerCfg { + fn default() -> Self { + Self { + threshold: default_breaker_threshold(), + cooldown: default_breaker_cooldown(), + } + } +} +fn default_breaker_threshold() -> u32 { + 5 +} +fn default_breaker_cooldown() -> String { + "30s".into() +} + +#[derive(Clone, Debug, Serialize, Deserialize, Default)] +pub struct ProtocolsCfg { + #[serde(default)] + pub openai_chat: bool, + #[serde(default)] + pub openai_completions: bool, + #[serde(default)] + pub openai_embeddings: bool, + #[serde(default)] + pub openai_models: bool, + #[serde(default)] + pub anthropic_messages: bool, + #[serde(default)] + pub mcp: bool, + #[serde(default)] + pub native_passthrough: bool, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct CortiqCfg { + #[serde(default)] + pub echo: bool, +} +impl Default for CortiqCfg { + fn default() -> Self { + Self { echo: true } + } +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct ApiKeyCfg { + pub key: String, + pub account: String, + #[serde(default)] + pub rate_per_min: u32, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub allow_models: Vec, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct IdempotencyCfg { + #[serde(default = "default_idem_ttl")] + pub ttl: String, +} +impl Default for IdempotencyCfg { + fn default() -> Self { + Self { + ttl: default_idem_ttl(), + } + } +} +fn default_idem_ttl() -> String { + "10m".into() +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct LogCfg { + #[serde(default)] + pub bodies: bool, + #[serde(default = "default_log_level")] + pub level: String, +} +impl Default for LogCfg { + fn default() -> Self { + Self { + bodies: false, + level: default_log_level(), + } + } +} +fn default_log_level() -> String { + "info".into() +} + +#[derive(Clone, Debug, Serialize, Deserialize, Default)] +pub struct TelemetryCfg { + #[serde(default)] + pub metrics: bool, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub otlp_endpoint_env: Option, +} + +/// Access to the web management panel and admin API. +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct AdminCfg { + /// Whether the admin panel and admin API (`/admin`, `/admin/api/*`) are enabled. + #[serde(default = "default_admin_enabled")] + pub enabled: bool, + /// Name of the env variable holding the admin token. If unset (or empty), + /// a token is generated at startup and printed to the log. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub token_env: Option, + /// Optional separate bind address for the admin surface (e.g. `127.0.0.1:9001`). + /// If unset, the admin interface lives on the main `listen` address under `/admin`. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub listen: Option, +} +impl Default for AdminCfg { + fn default() -> Self { + Self { + enabled: default_admin_enabled(), + token_env: None, + listen: None, + } + } +} +fn default_admin_enabled() -> bool { + true +} + +/// Request statistics tracking (for the dashboard and `/metrics`). +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct StatsCfg { + /// Whether to track request statistics. + #[serde(default = "default_stats_enabled")] + pub enabled: bool, + /// Append-only request log file (JSONL). Empty means in-memory only. + #[serde(default = "default_stats_file")] + pub file: String, + /// How many recent requests to keep in memory (the "recent" ring buffer). + #[serde(default = "default_stats_ring")] + pub ring_size: usize, + /// Retention window for aggregates/time-series replayed on startup, e.g. `7d`. + #[serde(default = "default_stats_retention")] + pub retention: String, +} +impl Default for StatsCfg { + fn default() -> Self { + Self { + enabled: default_stats_enabled(), + file: default_stats_file(), + ring_size: default_stats_ring(), + retention: default_stats_retention(), + } + } +} +fn default_stats_enabled() -> bool { + true +} +fn default_stats_file() -> String { + "config/stats.jsonl".into() +} +fn default_stats_ring() -> usize { + 500 +} +fn default_stats_retention() -> String { + "7d".into() +} + +impl Config { + /// Load and validate the config from a file. + pub fn load(path: &str) -> anyhow::Result { + let raw = std::fs::read_to_string(path) + .map_err(|e| anyhow::anyhow!("cannot read config {path}: {e}"))?; + let cfg: Config = toml::from_str(&raw)?; + cfg.validate()?; + Ok(cfg) + } + + /// Integrity validation: non-empty model pool, valid routing targets. + pub fn validate(&self) -> anyhow::Result<()> { + if self.models.is_empty() { + anyhow::bail!("config: at least one [[models]] entry is required"); + } + // uniqueness of model ids + let mut seen = std::collections::HashSet::new(); + for m in &self.models { + if !seen.insert(m.id.as_str()) { + anyhow::bail!("config: duplicate model id '{}'", m.id); + } + } + // every target in [routing] must exist in the model pool + let ids: std::collections::HashSet<&str> = + self.models.iter().map(|m| m.id.as_str()).collect(); + if !ids.contains(self.routing.default.as_str()) { + anyhow::bail!( + "config: routing.default '{}' is not a known model id", + self.routing.default + ); + } + for (tier, targets) in &self.routing.tiers { + let list = match targets { + TierTargets::List(v) => v.clone(), + TierTargets::One(s) => vec![s.clone()], + }; + for id in &list { + if !ids.contains(id.as_str()) { + anyhow::bail!( + "config: routing.{} references unknown model id '{}'", + tier, + id + ); + } + } + } + Ok(()) + } + + /// Serialize the config to a TOML string (no secrets — they are intentionally absent here). + pub fn to_toml_string(&self) -> anyhow::Result { + let header = "# Cortiq Gateway — configuration (managed via the admin panel).\n\ + # This file is rewritten by the panel; manual edits are preserved\n\ + # only until the next change made through the UI.\n\n"; + let body = toml::to_string_pretty(self)?; + Ok(format!("{header}{body}")) + } + + /// Atomically save the config to a file (write to a temporary file then rename). + pub fn save(&self, path: &str) -> anyhow::Result<()> { + self.validate()?; + let data = self.to_toml_string()?; + let p = std::path::Path::new(path); + let dir = p.parent().unwrap_or_else(|| std::path::Path::new(".")); + std::fs::create_dir_all(dir).ok(); + let tmp = p.with_extension("toml.tmp"); + std::fs::write(&tmp, data.as_bytes()) + .map_err(|e| anyhow::anyhow!("cannot write config tmp {}: {e}", tmp.display()))?; + std::fs::rename(&tmp, p) + .map_err(|e| anyhow::anyhow!("cannot replace config {path}: {e}"))?; + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + const SAMPLE: &str = r#" +listen = "0.0.0.0:9000" + +[router] +url = "http://localhost:8080" +api_key_env = "CORTIQ_ROUTER_KEY" + +[[models]] +id = "local-qwen" +provider = "openai" +base_url = "http://localhost:8000/v1" +model = "qwen2.5-7b-instruct" +cost_tier = "cheap" +caps = ["tools"] + +[[models]] +id = "gpt-4o-mini" +provider = "openai" +base_url = "https://api.openai.com/v1" +model = "gpt-4o-mini" +api_key_env = "OPENAI_API_KEY" +cost_tier = "mid" +price_in = 0.15 +price_out = 0.6 + +[routing] +low = ["local-qwen"] +medium = ["gpt-4o-mini", "local-qwen"] +default = "gpt-4o-mini" + +[routing.policy] +mode = "cost_aware" +max_cost_usd_per_request = 0.5 +min_class = { low = "cheap", medium = "mid" } +"#; + + #[test] + fn roundtrip_preserves_routing_and_models() { + let cfg: Config = toml::from_str(SAMPLE).expect("parse sample"); + cfg.validate().expect("sample valid"); + + // key risk: serialization of flattened [routing] + nested policy + let serialized = cfg.to_toml_string().expect("serialize"); + let back: Config = toml::from_str(&serialized).expect("re-parse serialized"); + back.validate().expect("roundtrip valid"); + + assert_eq!(back.listen, "0.0.0.0:9000"); + assert_eq!(back.models.len(), 2); + assert_eq!(back.routing.default, "gpt-4o-mini"); + assert_eq!(back.routing.policy.mode, "cost_aware"); + assert_eq!(back.routing.policy.max_cost_usd_per_request, Some(0.5)); + assert_eq!( + back.routing.policy.min_class.get("low").map(String::as_str), + Some("cheap") + ); + + let low = back.routing.tiers.get("low").expect("low tier present"); + match low { + TierTargets::List(v) => assert_eq!(v, &vec!["local-qwen".to_string()]), + TierTargets::One(s) => assert_eq!(s, "local-qwen"), + } + + // admin/stats sections receive defaults + assert!(back.admin.enabled); + assert!(back.stats.enabled); + } + + #[test] + fn validate_rejects_unknown_routing_target() { + let mut cfg: Config = toml::from_str(SAMPLE).unwrap(); + cfg.routing.default = "does-not-exist".into(); + assert!(cfg.validate().is_err()); + } +} diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..5a11244 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,74 @@ +//! Unified gateway error type + rendering into an OpenAI-compatible envelope +//! `{"error": {message, type, code, param}}` that SDK clients parse natively. +//! See docs/PROTOCOLS.md §8.5. + +use axum::{http::StatusCode, response::IntoResponse, Json}; +use serde_json::json; + +#[derive(Debug, thiserror::Error)] +pub enum GatewayError { + #[error("{0}")] + InvalidRequest(String), + #[error("authentication failed: {0}")] + Unauthorized(String), + #[error("rate limit exceeded")] + RateLimited { retry_after_secs: u64 }, + #[error("upstream unavailable: {0}")] + UpstreamUnavailable(String), + #[error("internal error: {0}")] + Internal(String), +} + +impl GatewayError { + fn parts(&self) -> (StatusCode, &'static str, &'static str) { + match self { + Self::InvalidRequest(_) => ( + StatusCode::BAD_REQUEST, + "invalid_request_error", + "invalid_request", + ), + Self::Unauthorized(_) => ( + StatusCode::UNAUTHORIZED, + "authentication_error", + "unauthorized", + ), + Self::RateLimited { .. } => ( + StatusCode::TOO_MANY_REQUESTS, + "rate_limit_error", + "rate_limited", + ), + Self::UpstreamUnavailable(_) => ( + StatusCode::BAD_GATEWAY, + "upstream_unavailable", + "no_healthy_model", + ), + Self::Internal(_) => ( + StatusCode::INTERNAL_SERVER_ERROR, + "internal_error", + "internal", + ), + } + } +} + +impl IntoResponse for GatewayError { + fn into_response(self) -> axum::response::Response { + let (status, typ, code) = self.parts(); + let body = Json(json!({ + "error": { + "message": self.to_string(), + "type": typ, + "code": code, + "param": serde_json::Value::Null, + } + })); + let mut resp = (status, body).into_response(); + if let Self::RateLimited { retry_after_secs } = self { + resp.headers_mut() + .insert("retry-after", retry_after_secs.to_string().parse().unwrap()); + } + resp + } +} + +pub type Result = std::result::Result; diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..9b2ceaa --- /dev/null +++ b/src/main.rs @@ -0,0 +1,107 @@ +//! Cortiq Gateway — entry point. +//! +//! Loads the config, builds the shared state, assembles routes from protocols and +//! the admin panel, and starts the HTTP server. See docs/ARCHITECTURE.md. + +// Part of the canonical model / error API surface (auth, rate-limit, idempotency, +// traceparent, vision/streaming caps) is intentionally reserved for upcoming phases; +// allow the unused items until those features land. +#![allow(dead_code)] + +mod admin; +mod config; +mod error; +mod model; +mod pipeline; +mod protocols; +mod providers; +mod registry; +mod router_client; +mod routing; +mod secrets; +mod state; +mod stats; + +use axum::{routing::get, Router}; +use clap::Parser; +use config::Config; +use state::SharedState; + +#[derive(Parser)] +#[command( + name = "cortiq-gateway", + version, + about = "Universal LLM gateway with intelligent routing" +)] +struct Args { + /// Path to the TOML config file. + #[arg(long, default_value = "config/gateway.toml")] + config: String, + /// Admin token for the web panel (overrides `[admin].token_env`). + #[arg(long)] + admin_token: Option, +} + +/// Resolve the admin token: env from `[admin].token_env` → `--admin-token` → +/// generate a random one. Returns `(token, generated)`. +fn resolve_admin_token(cfg: &Config, args: &Args) -> (String, bool) { + if let Some(env) = &cfg.admin.token_env { + if let Ok(v) = std::env::var(env) { + if !v.is_empty() { + return (v, false); + } + } + } + if let Some(t) = &args.admin_token { + if !t.is_empty() { + return (t.clone(), false); + } + } + (admin::random_token(24), true) +} + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let args = Args::parse(); + + let cfg = Config::load(&args.config)?; + tracing_subscriber::fmt() + .with_env_filter( + tracing_subscriber::EnvFilter::try_from_default_env() + .unwrap_or_else(|_| cfg.log.level.clone().into()), + ) + .init(); + + let listen = cfg.listen.clone(); + let admin_enabled = cfg.admin.enabled; + let (admin_token, generated) = resolve_admin_token(&cfg, &args); + + let state = SharedState::build(cfg, args.config.clone())?; + + let mut app = Router::new() + .route("/healthz", get(|| async { "ok" })) + .route("/readyz", get(|| async { "ready" })) + .route("/metrics", get(admin::metrics)) + .merge(protocols::build_router()); + + if admin_enabled { + app = app + .merge(admin::api_routes(admin_token.clone())) + .fallback(admin::assets::fallback); + } + + let app = app.with_state(state); + + let listener = tokio::net::TcpListener::bind(&listen).await?; + tracing::info!("cortiq-gateway listening on {listen}"); + if admin_enabled { + tracing::info!("admin console: http://{listen}/admin"); + if generated { + tracing::warn!( + "admin token (auto-generated, set [admin].token_env to persist): {admin_token}" + ); + } + } + axum::serve(listener, app).await?; + Ok(()) +} diff --git a/src/model.rs b/src/model.rs new file mode 100644 index 0000000..ec9efe6 --- /dev/null +++ b/src/model.rs @@ -0,0 +1,102 @@ +//! Canonical (protocol-neutral) request/response model. +//! +//! All incoming protocols are translated into these types, and providers translate +//! from them. This way N protocols × M providers do not become N×M translations: +//! each adapter only knows its own protocol ↔ canonical mapping. See docs/ARCHITECTURE.md §3. + +use serde::{Deserialize, Serialize}; + +/// How to handle routing for a specific request. +#[derive(Clone, Debug)] +pub enum RoutingDirective { + /// `model = "cortiq-auto"` — ask cortiq-router and pick a model from the pool. + Auto { profile: Option }, + /// `model = ""` — call a specific model directly, bypassing routing. + Pinned { model_id: String }, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Message { + pub role: String, // system | user | assistant | tool + #[serde(default)] + pub content: String, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub tool_calls: Vec, +} + +#[derive(Clone, Debug, Default)] +pub struct GenParams { + pub temperature: Option, + pub max_tokens: Option, + pub top_p: Option, + pub stop: Vec, + /// Fields we do not interpret but must proxy through to the provider. + pub passthrough: serde_json::Map, +} + +#[derive(Clone, Debug, Default)] +pub struct RequestMeta { + pub account: String, + pub protocol: String, + pub idempotency_key: Option, + pub traceparent: Option, +} + +/// Canonical form of a generation request. +#[derive(Clone, Debug)] +pub struct ChatRequest { + pub routing: RoutingDirective, + pub messages: Vec, + pub tools: Vec, + pub params: GenParams, + pub stream: bool, + pub meta: RequestMeta, +} + +#[derive(Clone, Debug, Serialize)] +pub struct Usage { + pub prompt_tokens: u32, + pub completion_tokens: u32, + pub total_tokens: u32, +} + +/// Routing metadata attached to the response (X-Cortiq-* headers and the `cortiq` field). +#[derive(Clone, Debug, Serialize)] +pub struct RouteInfo { + pub task_label: String, + pub complexity_score: f32, + pub complexity_tier: String, + pub selected_model: String, + pub route_source: String, // router | cache | fallback | pinned + pub router_request_id: Option, + pub cost_usd: f64, + #[serde(default)] + pub failover: bool, +} + +#[derive(Clone, Debug, Serialize)] +pub struct Choice { + pub index: u32, + pub message: Message, + pub finish_reason: String, +} + +/// Canonical form of a response. +#[derive(Clone, Debug)] +pub struct ChatResponse { + pub id: String, + pub model_used: String, + pub choices: Vec, + pub usage: Usage, + pub cortiq: RouteInfo, +} + +/// Decision from cortiq-router (the subset of its contract needed by the gateway). +#[derive(Clone, Debug)] +pub struct RouteDecision { + pub task_label: String, + pub complexity_score: f32, + pub complexity_tier: String, + pub router_request_id: Option, + pub source: String, // router | cache | fallback +} diff --git a/src/pipeline.rs b/src/pipeline.rs new file mode 100644 index 0000000..8cd96db --- /dev/null +++ b/src/pipeline.rs @@ -0,0 +1,251 @@ +//! Canonical request processing pipeline (Pipeline). +//! Coordinates stages: Extract -> Route -> Select -> Translate & Call, +//! and also measures latency and records per-request statistics. + +use crate::error::{GatewayError, Result}; +use crate::model::{ + ChatRequest, ChatResponse, Message, RouteDecision, RouteInfo, RoutingDirective, +}; +use crate::state::SharedState; +use crate::stats::RequestRecord; +use std::time::{Instant, SystemTime, UNIX_EPOCH}; + +pub struct Pipeline; + +impl Pipeline { + pub fn new() -> Self { + Self + } + + /// Run the routing and generation pipeline. + pub async fn run(&self, req: ChatRequest, state: &SharedState) -> Result { + let started = Instant::now(); + let account = req.meta.account.clone(); + let protocol = req.meta.protocol.clone(); + let directive = match &req.routing { + RoutingDirective::Pinned { .. } => "pinned", + RoutingDirective::Auto { .. } => "auto", + } + .to_string(); + + let result = self.run_inner(req, state).await; + + // record statistics (for both success and error) + let latency_ms = started.elapsed().as_millis() as u64; + let ts = SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap_or_default() + .as_secs(); + let rec = match &result { + Ok(resp) => RequestRecord { + ts, + account, + protocol, + directive, + task_label: resp.cortiq.task_label.clone(), + tier: resp.cortiq.complexity_tier.clone(), + score: resp.cortiq.complexity_score, + model_id: resp.cortiq.selected_model.clone(), + route_source: resp.cortiq.route_source.clone(), + prompt_tokens: resp.usage.prompt_tokens, + completion_tokens: resp.usage.completion_tokens, + cost_usd: resp.cortiq.cost_usd, + latency_ms, + outcome: "ok".to_string(), + failover: resp.cortiq.failover, + error: None, + }, + Err(err) => RequestRecord { + ts, + account, + protocol, + directive, + task_label: String::new(), + tier: String::new(), + score: 0.0, + model_id: String::new(), + route_source: String::new(), + prompt_tokens: 0, + completion_tokens: 0, + cost_usd: 0.0, + latency_ms, + outcome: "error".to_string(), + failover: false, + error: Some(err.to_string()), + }, + }; + state.stats.record(rec); + + result + } + + async fn run_inner(&self, req: ChatRequest, state: &SharedState) -> Result { + let live = state.live(); + + // 1. Extract text for classification + let text = self.extract_text( + &req.messages, + &live.cfg.route.text_strategy, + live.cfg.route.max_chars, + ); + + // 2. Obtain the router decision (or use the pinned model) + let (decision, route_source) = match &req.routing { + RoutingDirective::Pinned { model_id: _ } => { + let dec = RouteDecision { + task_label: "pinned".to_string(), + complexity_score: 0.0, + complexity_tier: "pinned".to_string(), + router_request_id: None, + source: "pinned".to_string(), + }; + (dec, "pinned".to_string()) + } + RoutingDirective::Auto { profile } => { + let prof = profile.as_deref().unwrap_or(&live.cfg.route.profile); + match live.router.route(&text, prof).await { + Ok(Some(dec)) => { + let src = dec.source.clone(); + (dec, src) + } + Ok(None) | Err(_) => { + tracing::warn!( + "Router is unavailable. Gracefully degrading to default model." + ); + let dec = RouteDecision { + task_label: "degraded".to_string(), + complexity_score: 0.5, + complexity_tier: "degraded".to_string(), + router_request_id: None, + source: "fallback".to_string(), + }; + (dec, "fallback".to_string()) + } + } + } + }; + + // 3. Select candidates by complexity tier / pinned model + let candidates = match &req.routing { + RoutingDirective::Pinned { model_id } => vec![model_id.clone()], + RoutingDirective::Auto { .. } => { + if route_source == "fallback" { + vec![live.routing.default_model().to_string()] + } else { + live.routing.candidates(&decision.complexity_tier) + } + } + }; + + // Filter candidates by capabilities (e.g. tools support) + let needs_tools = !req.tools.is_empty(); + let mut final_candidates = Vec::new(); + for model_id in candidates { + if let Some(prov) = live.registry.get(&model_id) { + if needs_tools && !prov.caps().tools { + tracing::debug!( + "Candidate '{}' skipped: lacks support for requested tools", + model_id + ); + continue; + } + final_candidates.push(model_id); + } + } + + if final_candidates.is_empty() { + return Err(GatewayError::UpstreamUnavailable( + "No healthy model available that satisfies required capabilities (e.g. tools)" + .to_string(), + )); + } + + // 4. Attempt provider call with failover (fall back to alternatives on error) + let mut last_err = None; + let mut attempt = 0usize; + for model_id in final_candidates { + let provider = match live.registry.get(&model_id) { + Some(p) => p, + None => continue, + }; + + tracing::info!( + "Routing request (label: {}, tier: {}) to model '{}' via source '{}'", + decision.task_label, + decision.complexity_tier, + model_id, + route_source + ); + + match provider.chat(req.clone()).await { + Ok(mut resp) => { + let cost = + provider.price(resp.usage.prompt_tokens, resp.usage.completion_tokens); + resp.cortiq = RouteInfo { + task_label: decision.task_label.clone(), + complexity_score: decision.complexity_score, + complexity_tier: decision.complexity_tier.clone(), + selected_model: model_id, + route_source: route_source.clone(), + router_request_id: decision.router_request_id.clone(), + cost_usd: cost, + failover: attempt > 0, + }; + return Ok(resp); + } + Err(err) => { + tracing::warn!( + "Provider '{}' call failed: {:?}. Attempting failover...", + model_id, + err + ); + last_err = Some(err); + attempt += 1; + } + } + } + + Err(last_err.unwrap_or_else(|| { + GatewayError::UpstreamUnavailable("All candidate models failed".to_string()) + })) + } + + fn extract_text(&self, messages: &[Message], strategy: &str, max_chars: usize) -> String { + let raw_text = match strategy { + "last_user" => messages + .iter() + .rfind(|m| m.role == "user") + .map(|m| m.content.clone()) + .unwrap_or_default(), + "last_user_plus_system" => { + let system_msgs: Vec = messages + .iter() + .filter(|m| m.role == "system") + .map(|m| m.content.clone()) + .collect(); + let last_user = messages + .iter() + .rfind(|m| m.role == "user") + .map(|m| m.content.as_str()) + .unwrap_or(""); + if system_msgs.is_empty() { + last_user.to_string() + } else { + format!("{}\n{}", system_msgs.join("\n"), last_user) + } + } + // "concat_all" and any unknown strategy fall back to concatenating all turns + _ => messages + .iter() + .map(|m| format!("{}: {}", m.role, m.content)) + .collect::>() + .join("\n"), + }; + + if raw_text.chars().count() > max_chars { + raw_text.chars().take(max_chars).collect() + } else { + raw_text + } + } +} diff --git a/src/protocols/mod.rs b/src/protocols/mod.rs new file mode 100644 index 0000000..273bccd --- /dev/null +++ b/src/protocols/mod.rs @@ -0,0 +1,17 @@ +//! Incoming protocol adapters. Each one builds its own axum routes and translates +//! its protocol to/from the canonical model. Enabled via flags in `[protocols]`. + +pub mod openai_chat; + +use crate::state::SharedState; +use axum::Router; + +/// Build the protocols router. Implemented adapters are **always** mounted; +/// each handler checks the live `protocols.*` flag from config itself, so +/// toggles in the admin panel take effect without a restart (hot switching). +pub fn build_router() -> Router { + Router::new().merge(openai_chat::routes()) + // TODO: openai_completions, openai_embeddings, openai_models, + // anthropic_messages, mcp, native_passthrough — add here as well, + // with a check of the corresponding flag inside the handler. +} diff --git a/src/protocols/openai_chat.rs b/src/protocols/openai_chat.rs new file mode 100644 index 0000000..1f65119 --- /dev/null +++ b/src/protocols/openai_chat.rs @@ -0,0 +1,168 @@ +//! Incoming adapter for OpenAI Chat Completions: `POST /v1/chat/completions`. +//! Translates the OpenAI request body into a canonical [`ChatRequest`], passes it +//! to the pipeline, then converts the canonical [`ChatResponse`] back to OpenAI format. + +use crate::error::{GatewayError, Result}; +use crate::model::{ChatRequest, GenParams, Message, RequestMeta, RoutingDirective}; +use crate::state::SharedState; +use axum::{extract::State, routing::post, Json, Router}; +use serde::Deserialize; + +pub fn routes() -> Router { + Router::new().route("/v1/chat/completions", post(handler)) +} + +#[derive(Deserialize)] +struct OpenAiChatRequest { + model: String, + messages: Vec, + #[serde(default)] + temperature: Option, + #[serde(default)] + max_tokens: Option, + #[serde(default)] + top_p: Option, + #[serde(default)] + stream: bool, + #[serde(default)] + tools: Vec, + #[serde(flatten)] + rest: serde_json::Map, +} + +/// Parse the `model` field value into a routing directive. +/// `cortiq-auto[:profile]` → Auto; otherwise → Pinned(real id). +fn parse_routing(model: &str) -> RoutingDirective { + if let Some(rest) = model.strip_prefix("cortiq-auto") { + let profile = rest.strip_prefix(':').map(|p| p.to_string()); + RoutingDirective::Auto { profile } + } else { + RoutingDirective::Pinned { + model_id: model.to_string(), + } + } +} + +async fn handler( + State(state): State, + Json(req): Json, +) -> Result { + // hot protocol toggle: if the adapter is disabled in config — return 404 + if !state.live().cfg.protocols.openai_chat { + return Err(GatewayError::InvalidRequest( + "openai_chat protocol is disabled".into(), + )); + } + if req.messages.is_empty() { + return Err(GatewayError::InvalidRequest( + "messages must not be empty".into(), + )); + } + + let canonical = ChatRequest { + routing: parse_routing(&req.model), + messages: req.messages, + tools: req.tools, + params: GenParams { + temperature: req.temperature, + max_tokens: req.max_tokens, + top_p: req.top_p, + stop: Vec::new(), + passthrough: req.rest, + }, + stream: req.stream, + meta: RequestMeta { + protocol: "openai_chat".into(), + ..Default::default() + }, + }; + + if req.stream { + return Err(GatewayError::InvalidRequest( + "Streaming is not yet supported in this version".into(), + )); + } + + let resp = state.pipeline.run(canonical, &state).await?; + + let mut headers = axum::http::HeaderMap::new(); + headers.insert( + "X-Cortiq-Task-Label", + axum::http::HeaderValue::from_str(&resp.cortiq.task_label) + .unwrap_or(axum::http::HeaderValue::from_static("")), + ); + headers.insert( + "X-Cortiq-Complexity-Score", + axum::http::HeaderValue::from_str(&resp.cortiq.complexity_score.to_string()) + .unwrap_or(axum::http::HeaderValue::from_static("0.0")), + ); + headers.insert( + "X-Cortiq-Complexity-Tier", + axum::http::HeaderValue::from_str(&resp.cortiq.complexity_tier) + .unwrap_or(axum::http::HeaderValue::from_static("")), + ); + headers.insert( + "X-Cortiq-Selected-Model", + axum::http::HeaderValue::from_str(&resp.cortiq.selected_model) + .unwrap_or(axum::http::HeaderValue::from_static("")), + ); + headers.insert( + "X-Cortiq-Route-Source", + axum::http::HeaderValue::from_str(&resp.cortiq.route_source) + .unwrap_or(axum::http::HeaderValue::from_static("")), + ); + headers.insert( + "X-Cortiq-Cost-Usd", + axum::http::HeaderValue::from_str(&resp.cortiq.cost_usd.to_string()) + .unwrap_or(axum::http::HeaderValue::from_static("0.0")), + ); + if let Some(req_id) = &resp.cortiq.router_request_id { + headers.insert( + "X-Cortiq-Request-Id", + axum::http::HeaderValue::from_str(req_id) + .unwrap_or(axum::http::HeaderValue::from_static("")), + ); + } + + let mut body = serde_json::json!({ + "id": resp.id, + "object": "chat.completion", + "created": std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap_or_default() + .as_secs(), + "model": resp.model_used, + "choices": resp.choices.iter().map(|c| { + serde_json::json!({ + "index": c.index, + "message": { + "role": c.message.role, + "content": c.message.content, + "tool_calls": if c.message.tool_calls.is_empty() { serde_json::Value::Null } else { serde_json::Value::Array(c.message.tool_calls.clone()) }, + }, + "finish_reason": c.finish_reason, + }) + }).collect::>(), + "usage": { + "prompt_tokens": resp.usage.prompt_tokens, + "completion_tokens": resp.usage.completion_tokens, + "total_tokens": resp.usage.total_tokens, + } + }); + + if state.live().cfg.cortiq.echo { + body["cortiq"] = serde_json::json!({ + "task_label": resp.cortiq.task_label, + "complexity": { + "score": resp.cortiq.complexity_score, + "tier": resp.cortiq.complexity_tier, + }, + "selected_model": resp.cortiq.selected_model, + "route_source": resp.cortiq.route_source, + "router_request_id": resp.cortiq.router_request_id, + "cost_usd": resp.cortiq.cost_usd, + }); + } + + Ok((headers, Json(body))) +} diff --git a/src/providers/anthropic.rs b/src/providers/anthropic.rs new file mode 100644 index 0000000..0af8d20 --- /dev/null +++ b/src/providers/anthropic.rs @@ -0,0 +1,57 @@ +//! Anthropic Messages provider (v0.2). Translates the canonical ChatRequest to +//! `POST /v1/messages` and back. The `system` message is extracted into a separate field. + +use super::{Caps, Provider}; +use crate::config::ModelCfg; +use crate::error::{GatewayError, Result}; +use crate::model::{ChatRequest, ChatResponse}; +use async_trait::async_trait; + +pub struct AnthropicProvider { + id: String, + #[allow(dead_code)] + base_url: String, + #[allow(dead_code)] + model: String, + #[allow(dead_code)] + api_key: Option, + caps: Caps, + price_in: f64, + price_out: f64, +} + +impl AnthropicProvider { + pub fn new(cfg: &ModelCfg, api_key: Option) -> anyhow::Result { + Ok(Self { + id: cfg.id.clone(), + base_url: cfg.base_url.trim_end_matches('/').to_string(), + model: cfg.model.clone(), + api_key, + caps: Caps::from_list(&cfg.caps), + price_in: cfg.price_in, + price_out: cfg.price_out, + }) + } +} + +#[async_trait] +impl Provider for AnthropicProvider { + fn id(&self) -> &str { + &self.id + } + fn caps(&self) -> &Caps { + &self.caps + } + fn price(&self, prompt_tokens: u32, completion_tokens: u32) -> f64 { + (prompt_tokens as f64 * self.price_in + completion_tokens as f64 * self.price_out) + / 1_000_000.0 + } + async fn chat(&self, _req: ChatRequest) -> Result { + // TODO(v0.2): extract system from messages → "system" field; messages → content blocks; + // add x-api-key + anthropic-version headers; map response → canonical form. + // Returns an error (not a panic) so that failover/playground continue to work normally. + Err(GatewayError::UpstreamUnavailable( + "anthropic provider not yet implemented (planned v0.2)".to_string(), + )) + } +} diff --git a/src/providers/mod.rs b/src/providers/mod.rs new file mode 100644 index 0000000..e7daf0d --- /dev/null +++ b/src/providers/mod.rs @@ -0,0 +1,46 @@ +//! Outgoing provider adapters. The [`Provider`] trait is the single call site for LLMs; +//! adapters translate the canonical [`ChatRequest`] to and from each provider's API format. +//! +//! Most local servers (vLLM, llama.cpp, LM Studio, Ollama `/v1`) are OpenAI-compatible +//! → [`openai::OpenAiProvider`] is sufficient for all of them. + +pub mod anthropic; +pub mod openai; + +use crate::model::{ChatRequest, ChatResponse}; +use async_trait::async_trait; + +/// Model capabilities — checked at selection time (whether tools/vision are needed). +#[derive(Clone, Debug, Default)] +pub struct Caps { + pub tools: bool, + pub vision: bool, + pub streaming: bool, +} + +impl Caps { + pub fn from_list(list: &[String]) -> Self { + Self { + tools: list.iter().any(|c| c == "tools"), + vision: list.iter().any(|c| c == "vision"), + streaming: true, + } + } +} + +#[async_trait] +pub trait Provider: Send + Sync { + /// The model_id from config (not the provider's model name). + fn id(&self) -> &str; + + fn caps(&self) -> &Caps; + + /// Cost of a request in USD — computed from price_in/price_out × tokens (for billing). + fn price(&self, prompt_tokens: u32, completion_tokens: u32) -> f64; + + /// Non-streaming chat call. + async fn chat(&self, req: ChatRequest) -> crate::error::Result; + + // TODO(v0.1): async fn chat_stream(...) -> Result (SSE). + // TODO(v0.1): async fn embed(...) -> Result. +} diff --git a/src/providers/openai.rs b/src/providers/openai.rs new file mode 100644 index 0000000..8012624 --- /dev/null +++ b/src/providers/openai.rs @@ -0,0 +1,157 @@ +//! OpenAI-compatible provider. Covers OpenAI, OpenRouter, Together, Groq, +//! and local servers such as vLLM / llama.cpp / LM Studio / Ollama (`/v1`). + +use super::{Caps, Provider}; +use crate::config::ModelCfg; +use crate::error::{GatewayError, Result}; +use crate::model::{ChatRequest, ChatResponse}; +use async_trait::async_trait; + +pub struct OpenAiProvider { + id: String, + base_url: String, + model: String, + api_key: Option, + caps: Caps, + price_in: f64, + price_out: f64, + http: reqwest::Client, +} + +impl OpenAiProvider { + pub fn new(cfg: &ModelCfg, api_key: Option) -> anyhow::Result { + Ok(Self { + id: cfg.id.clone(), + base_url: cfg.base_url.trim_end_matches('/').to_string(), + model: cfg.model.clone(), + api_key, + caps: Caps::from_list(&cfg.caps), + price_in: cfg.price_in, + price_out: cfg.price_out, + http: reqwest::Client::new(), + }) + } + + /// Canonical request → OpenAI Chat Completions request body. + fn to_wire(&self, req: &ChatRequest) -> serde_json::Value { + let mut body = serde_json::json!({ + "model": self.model, + "messages": req.messages, + "stream": req.stream, + }); + if let Some(t) = req.params.temperature { + body["temperature"] = t.into(); + } + if let Some(m) = req.params.max_tokens { + body["max_tokens"] = m.into(); + } + if !req.tools.is_empty() { + body["tools"] = serde_json::Value::Array(req.tools.clone()); + } + // uninterpreted fields are proxied as-is + for (k, v) in &req.params.passthrough { + body[k] = v.clone(); + } + body + } +} + +#[async_trait] +impl Provider for OpenAiProvider { + fn id(&self) -> &str { + &self.id + } + fn caps(&self) -> &Caps { + &self.caps + } + fn price(&self, prompt_tokens: u32, completion_tokens: u32) -> f64 { + (prompt_tokens as f64 * self.price_in + completion_tokens as f64 * self.price_out) + / 1_000_000.0 + } + + async fn chat(&self, req: ChatRequest) -> Result { + let mut r = self + .http + .post(format!("{}/chat/completions", self.base_url)) + .json(&self.to_wire(&req)); + if let Some(key) = &self.api_key { + r = r.bearer_auth(key); + } + let resp = r + .send() + .await + .map_err(|e| GatewayError::UpstreamUnavailable(e.to_string()))?; + if !resp.status().is_success() { + let status = resp.status(); + let err_body = resp.text().await.unwrap_or_default(); + return Err(GatewayError::UpstreamUnavailable(format!( + "provider {} returned HTTP {}: {}", + self.id, status, err_body + ))); + } + let v: serde_json::Value = resp + .json() + .await + .map_err(|e| GatewayError::Internal(format!("Failed to parse JSON response: {}", e)))?; + + let id = v["id"].as_str().unwrap_or("").to_string(); + let model_used = v["model"].as_str().unwrap_or(&self.model).to_string(); + + let choices_arr = v["choices"].as_array().ok_or_else(|| { + GatewayError::Internal( + "invalid openai response: choices is missing or not an array".to_string(), + ) + })?; + + let mut choices = Vec::new(); + for (i, c) in choices_arr.iter().enumerate() { + let msg_val = &c["message"]; + let role = msg_val["role"].as_str().unwrap_or("assistant").to_string(); + let content = msg_val["content"].as_str().unwrap_or("").to_string(); + + let tool_calls = msg_val["tool_calls"] + .as_array() + .cloned() + .unwrap_or_default(); + + choices.push(crate::model::Choice { + index: c["index"].as_u64().unwrap_or(i as u64) as u32, + message: crate::model::Message { + role, + content, + tool_calls, + }, + finish_reason: c["finish_reason"].as_str().unwrap_or("stop").to_string(), + }); + } + + let usage_val = &v["usage"]; + let prompt_tokens = usage_val["prompt_tokens"].as_u64().unwrap_or(0) as u32; + let completion_tokens = usage_val["completion_tokens"].as_u64().unwrap_or(0) as u32; + let total_tokens = usage_val["total_tokens"] + .as_u64() + .unwrap_or((prompt_tokens + completion_tokens) as u64) + as u32; + + Ok(ChatResponse { + id, + model_used, + choices, + usage: crate::model::Usage { + prompt_tokens, + completion_tokens, + total_tokens, + }, + cortiq: crate::model::RouteInfo { + task_label: String::new(), + complexity_score: 0.0, + complexity_tier: String::new(), + selected_model: self.id.clone(), + route_source: String::new(), + router_request_id: None, + cost_usd: 0.0, + failover: false, + }, + }) + } +} diff --git a/src/registry.rs b/src/registry.rs new file mode 100644 index 0000000..9961770 --- /dev/null +++ b/src/registry.rs @@ -0,0 +1,43 @@ +//! Model pool registry: builds providers from `[[models]]` and resolves +//! `model_id → Arc`. + +use crate::config::Config; +use crate::providers::{anthropic::AnthropicProvider, openai::OpenAiProvider, Provider}; +use crate::secrets::SecretStore; +use std::collections::HashMap; +use std::sync::Arc; + +pub struct Registry { + by_id: HashMap>, +} + +impl Registry { + pub fn from_config(cfg: &Config, secrets: &SecretStore) -> anyhow::Result { + let mut by_id: HashMap> = HashMap::new(); + for m in &cfg.models { + if m.kind == "embedding" { + continue; // embedding models are handled by a separate branch (v0.1) + } + // provider key: secret store → environment variable + let api_key = m + .api_key_env + .as_ref() + .and_then(|name| secrets.resolve(name)); + let provider: Arc = match m.provider.as_str() { + "openai" | "ollama" | "http" => Arc::new(OpenAiProvider::new(m, api_key)?), + "anthropic" => Arc::new(AnthropicProvider::new(m, api_key)?), + other => anyhow::bail!("unknown provider '{}' for model '{}'", other, m.id), + }; + by_id.insert(m.id.clone(), provider); + } + Ok(Self { by_id }) + } + + pub fn get(&self, model_id: &str) -> Option> { + self.by_id.get(model_id).cloned() + } + + pub fn ids(&self) -> impl Iterator { + self.by_id.keys() + } +} diff --git a/src/router_client.rs b/src/router_client.rs new file mode 100644 index 0000000..09febea --- /dev/null +++ b/src/router_client.rs @@ -0,0 +1,78 @@ +//! Client for cortiq-router. Issues `POST /v1/route` and (optionally) `POST /v1/feedback`. +//! Returns the decision as a [`RouteDecision`]. When the router is unavailable the caller +//! falls back to `routing.default` (graceful degradation). + +use crate::config::RouterCfg; +use crate::model::RouteDecision; + +pub struct RouterClient { + http: reqwest::Client, + url: String, + api_key: Option, + taxonomy_id: Option, +} + +impl RouterClient { + pub fn new(cfg: &RouterCfg) -> anyhow::Result { + let mut builder = + reqwest::Client::builder().timeout(std::time::Duration::from_millis(cfg.timeout_ms)); + + if !cfg.verify_tls { + builder = builder + .danger_accept_invalid_certs(true) + .danger_accept_invalid_hostnames(true); + } + + let http = builder.build()?; + let api_key = cfg + .api_key_env + .as_ref() + .and_then(|name| std::env::var(name).ok()); + Ok(Self { + http, + url: cfg.url.trim_end_matches('/').to_string(), + api_key, + taxonomy_id: cfg.taxonomy_id.clone(), + }) + } + + /// Classify text. Returns `Ok(None)` on network error/timeout — + /// the caller treats this as "router unavailable" and uses the default tier. + pub async fn route(&self, text: &str, profile: &str) -> anyhow::Result> { + let mut body = serde_json::json!({ + "input": { "text": text }, + "options": { "policy_profile": profile, "allow_oracle": true } + }); + if let Some(tax) = &self.taxonomy_id { + body["taxonomy_id"] = serde_json::Value::String(tax.clone()); + } + + let mut req = self.http.post(format!("{}/v1/route", self.url)).json(&body); + if let Some(key) = &self.api_key { + req = req.bearer_auth(key); + } + + let resp = match req.send().await { + Ok(r) => r, + Err(_) => return Ok(None), // degradation + }; + if !resp.status().is_success() { + return Ok(None); + } + let v: serde_json::Value = resp.json().await?; + let d = &v["decision"]; + Ok(Some(RouteDecision { + task_label: d["task_label"] + .as_str() + .unwrap_or("__unknown__") + .to_string(), + complexity_score: d["complexity"]["score"].as_f64().unwrap_or(0.5) as f32, + complexity_tier: d["complexity"]["tier"] + .as_str() + .unwrap_or("medium") + .to_string(), + router_request_id: v["request_id"].as_str().map(|s| s.to_string()), + source: "router".into(), + })) + } +} diff --git a/src/routing.rs b/src/routing.rs new file mode 100644 index 0000000..a49a637 --- /dev/null +++ b/src/routing.rs @@ -0,0 +1,48 @@ +//! Model selection: `(task_label, complexity_tier) → ordered list of model_ids`. +//! The list serves as both a priority order and a fallback chain. See docs/ROUTING.md. + +use crate::config::{Config, TierTargets}; + +pub struct RoutingTable { + tiers: std::collections::HashMap>, + default: String, +} + +impl RoutingTable { + pub fn from_config(cfg: &Config) -> Self { + let tiers = cfg + .routing + .tiers + .iter() + .map(|(tier, targets)| { + let list = match targets { + TierTargets::List(v) => v.clone(), + TierTargets::One(s) => vec![s.clone()], + }; + (tier.clone(), list) + }) + .collect(); + Self { + tiers, + default: cfg.routing.default.clone(), + } + } + + /// Candidates for the given complexity tier, in preference order. + /// If the tier is not defined, the sole candidate is `default`. + pub fn candidates(&self, tier: &str) -> Vec { + self.tiers + .get(tier) + .cloned() + .unwrap_or_else(|| vec![self.default.clone()]) + } + + /// Default model (used when the router is unavailable). + pub fn default_model(&self) -> &str { + &self.default + } +} + +// TODO(v0.2): cost_aware mode and circuit breaker — pick the cheapest available +// model no lower than min_class[tier], respecting max_cost_usd_per_request, +// and skip models whose circuit breaker is open. diff --git a/src/secrets.rs b/src/secrets.rs new file mode 100644 index 0000000..612a04f --- /dev/null +++ b/src/secrets.rs @@ -0,0 +1,96 @@ +//! Secret store (provider API key values) kept outside the main config. +//! +//! The file `config/secrets.toml` (in `.gitignore`, mode `0600`) is a map of +//! `env_name -> value`. Key resolution order: store entry > environment variable. +//! This allows setting keys directly from the admin panel without a restart, +//! without writing secrets into `gateway.toml`. Values are never exposed via the +//! API — only their presence status is returned (see `source`). + +use std::collections::BTreeMap; +use std::sync::RwLock; + +pub struct SecretStore { + path: String, + values: RwLock>, +} + +impl SecretStore { + /// Load the store from a file (missing file or parse error → empty store). + pub fn load(path: &str) -> Self { + let values = std::fs::read_to_string(path) + .ok() + .and_then(|raw| toml::from_str::>(&raw).ok()) + .unwrap_or_default(); + Self { + path: path.to_string(), + values: RwLock::new(values), + } + } + + /// Secret value by env name: store first, then environment variable. + pub fn resolve(&self, env_name: &str) -> Option { + if let Some(v) = self.values.read().unwrap().get(env_name) { + if !v.is_empty() { + return Some(v.clone()); + } + } + std::env::var(env_name).ok().filter(|v| !v.is_empty()) + } + + /// Value source for display in the UI: `store` | `env` | `missing`. + pub fn source(&self, env_name: &str) -> &'static str { + let in_store = self + .values + .read() + .unwrap() + .get(env_name) + .map(|v| !v.is_empty()) + .unwrap_or(false); + if in_store { + "store" + } else if std::env::var(env_name) + .ok() + .filter(|v| !v.is_empty()) + .is_some() + { + "env" + } else { + "missing" + } + } + + /// Set a secret (persisted to file with mode 0600). + pub fn set(&self, env_name: &str, value: &str) -> anyhow::Result<()> { + self.values + .write() + .unwrap() + .insert(env_name.to_string(), value.to_string()); + self.persist() + } + + /// Remove a secret from the store (an environment variable value, if present, remains). + pub fn clear(&self, env_name: &str) -> anyhow::Result<()> { + self.values.write().unwrap().remove(env_name); + self.persist() + } + + fn persist(&self) -> anyhow::Result<()> { + let data = { + let map = self.values.read().unwrap(); + toml::to_string(&*map)? + }; + let p = std::path::Path::new(&self.path); + if let Some(dir) = p.parent() { + std::fs::create_dir_all(dir).ok(); + } + let tmp = p.with_extension("toml.tmp"); + std::fs::write(&tmp, data.as_bytes())?; + std::fs::rename(&tmp, p)?; + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + let _ = std::fs::set_permissions(p, std::fs::Permissions::from_mode(0o600)); + } + Ok(()) + } +} diff --git a/src/state.rs b/src/state.rs new file mode 100644 index 0000000..37b8efb --- /dev/null +++ b/src/state.rs @@ -0,0 +1,107 @@ +//! Shared gateway state accessible across all request handlers. +//! +//! The config-derived part (`Live`) lives behind an `ArcSwap`, which allows +//! hot-reloading the model pool, routing table, and router connection without +//! a restart: the admin API validates the new config, builds a new `Live`, +//! atomically writes the TOML, and swaps the pointer. + +use crate::config::Config; +use crate::registry::Registry; +use crate::router_client::RouterClient; +use crate::routing::RoutingTable; +use crate::secrets::SecretStore; +use crate::stats::Stats; +use arc_swap::ArcSwap; +use std::sync::Arc; + +#[derive(Clone)] +pub struct SharedState(pub Arc); + +/// The portion of state that is rebuilt whenever the config changes. +pub struct Live { + pub cfg: Config, + pub registry: Registry, + pub routing: RoutingTable, + pub router: RouterClient, +} + +impl Live { + pub fn build(cfg: Config, secrets: &SecretStore) -> anyhow::Result { + let router = RouterClient::new(&cfg.router)?; + let registry = Registry::from_config(&cfg, secrets)?; + let routing = RoutingTable::from_config(&cfg); + Ok(Self { + cfg, + registry, + routing, + router, + }) + } +} + +pub struct AppState { + pub live: ArcSwap, + pub stats: Arc, + pub secrets: SecretStore, + pub config_path: String, + pub pipeline: crate::pipeline::Pipeline, +} + +impl std::ops::Deref for SharedState { + type Target = AppState; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl SharedState { + pub fn build(cfg: Config, config_path: String) -> anyhow::Result { + let secrets_path = sibling(&config_path, "secrets.toml"); + let secrets = SecretStore::load(&secrets_path); + let stats = Stats::new(&cfg.stats); + let live = Live::build(cfg, &secrets)?; + Ok(SharedState(Arc::new(AppState { + live: ArcSwap::from_pointee(live), + stats, + secrets, + config_path, + pipeline: crate::pipeline::Pipeline::new(), + }))) + } + + /// Current snapshot of the rebuildable state (safe to hold across await points). + pub fn live(&self) -> Arc { + self.0.live.load_full() + } +} + +impl AppState { + /// Replace the config entirely: validate → build → write to disk → swap. + /// If any step fails, the active state and file are left unchanged. + pub fn reload(&self, new_cfg: Config) -> anyhow::Result<()> { + new_cfg.validate()?; + let live = Live::build(new_cfg.clone(), &self.secrets)?; + new_cfg.save(&self.config_path)?; + self.live.store(Arc::new(live)); + Ok(()) + } + + /// Rebuild `Live` from the current config without writing to disk + /// (e.g. after a secret change — only provider keys changed). + pub fn rebuild(&self) -> anyhow::Result<()> { + let cfg = self.live.load_full().cfg.clone(); + let live = Live::build(cfg, &self.secrets)?; + self.live.store(Arc::new(live)); + Ok(()) + } +} + +/// Path to file `name` next to `path` (in the same directory). +fn sibling(path: &str, name: &str) -> String { + std::path::Path::new(path) + .parent() + .map(|d| d.join(name)) + .unwrap_or_else(|| std::path::PathBuf::from(name)) + .to_string_lossy() + .into_owned() +} diff --git a/src/stats.rs b/src/stats.rs new file mode 100644 index 0000000..d8dc75a --- /dev/null +++ b/src/stats.rs @@ -0,0 +1,395 @@ +//! Request statistics tracking for the dashboard and `GET /metrics`. +//! +//! Everything is held in memory (aggregates + per-minute buckets for the retention +//! window + a ring buffer of recent requests) and optionally appended to a JSONL +//! file that is replayed on startup — so statistics survive a restart with no +//! database dependency. + +use crate::config::StatsCfg; +use serde::{Deserialize, Serialize}; +use std::collections::{HashMap, VecDeque}; +use std::io::Write; +use std::sync::Mutex; +use std::time::{SystemTime, UNIX_EPOCH}; + +fn now_secs() -> u64 { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap_or_default() + .as_secs() +} + +/// A single record for a completed request (one JSONL line and one "recent" ring entry). +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct RequestRecord { + pub ts: u64, + #[serde(default)] + pub account: String, + #[serde(default)] + pub protocol: String, + #[serde(default)] + pub directive: String, // auto | pinned + #[serde(default)] + pub task_label: String, + #[serde(default)] + pub tier: String, + #[serde(default)] + pub score: f32, + #[serde(default)] + pub model_id: String, + #[serde(default)] + pub route_source: String, + #[serde(default)] + pub prompt_tokens: u32, + #[serde(default)] + pub completion_tokens: u32, + #[serde(default)] + pub cost_usd: f64, + #[serde(default)] + pub latency_ms: u64, + #[serde(default)] + pub outcome: String, // ok | error + #[serde(default)] + pub failover: bool, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub error: Option, +} + +#[derive(Clone, Debug, Default, Serialize)] +pub struct Totals { + pub requests: u64, + pub ok: u64, + pub errors: u64, + pub failovers: u64, + pub prompt_tokens: u64, + pub completion_tokens: u64, + pub cost_usd: f64, + pub latency_ms_sum: u64, +} + +impl Totals { + fn apply(&mut self, r: &RequestRecord) { + self.requests += 1; + if r.outcome == "ok" { + self.ok += 1; + } else { + self.errors += 1; + } + if r.failover { + self.failovers += 1; + } + self.prompt_tokens += r.prompt_tokens as u64; + self.completion_tokens += r.completion_tokens as u64; + self.cost_usd += r.cost_usd; + self.latency_ms_sum += r.latency_ms; + } +} + +/// Per-minute bucket for time-series charts. +#[derive(Clone, Debug, Default, Serialize)] +pub struct Bucket { + pub minute: u64, // unix seconds, rounded down to the minute + pub requests: u64, + pub errors: u64, + pub prompt_tokens: u64, + pub completion_tokens: u64, + pub cost_usd: f64, + pub latency_ms_sum: u64, +} + +#[derive(Default)] +struct Inner { + total: Totals, + by_model: HashMap, + by_account: HashMap, + by_tier: HashMap, + by_label: HashMap, + buckets: VecDeque, + recent: VecDeque, +} + +pub struct Stats { + enabled: bool, + file: Option, + ring_size: usize, + retention_secs: u64, + inner: Mutex, +} + +impl Stats { + pub fn new(cfg: &StatsCfg) -> std::sync::Arc { + let file = if cfg.file.trim().is_empty() { + None + } else { + Some(cfg.file.clone()) + }; + let s = Stats { + enabled: cfg.enabled, + file, + ring_size: cfg.ring_size.max(1), + retention_secs: parse_duration_secs(&cfg.retention).unwrap_or(7 * 86_400), + inner: Mutex::new(Inner::default()), + }; + s.replay(); + std::sync::Arc::new(s) + } + + /// Replay the JSONL file into aggregates (within the retention window only). + fn replay(&self) { + let Some(path) = &self.file else { return }; + let Ok(content) = std::fs::read_to_string(path) else { + return; + }; + let cutoff = now_secs().saturating_sub(self.retention_secs); + let mut inner = self.inner.lock().unwrap(); + for line in content.lines() { + let line = line.trim(); + if line.is_empty() { + continue; + } + if let Ok(rec) = serde_json::from_str::(line) { + // push everything to the "recent" ring (it self-limits by size), + // but apply to aggregates/series only entries within the window. + Self::push_recent(&mut inner, &rec, self.ring_size); + if rec.ts >= cutoff { + Self::apply_aggregates(&mut inner, &rec, self.retention_secs); + } + } + } + } + + fn push_recent(inner: &mut Inner, rec: &RequestRecord, ring_size: usize) { + inner.recent.push_back(rec.clone()); + while inner.recent.len() > ring_size { + inner.recent.pop_front(); + } + } + + fn apply_aggregates(inner: &mut Inner, rec: &RequestRecord, retention_secs: u64) { + inner.total.apply(rec); + inner + .by_model + .entry(rec.model_id.clone()) + .or_default() + .apply(rec); + inner + .by_account + .entry(if rec.account.is_empty() { + "anonymous".to_string() + } else { + rec.account.clone() + }) + .or_default() + .apply(rec); + inner + .by_tier + .entry(rec.tier.clone()) + .or_default() + .apply(rec); + inner + .by_label + .entry(rec.task_label.clone()) + .or_default() + .apply(rec); + + let minute = rec.ts - (rec.ts % 60); + match inner.buckets.back_mut() { + Some(b) if b.minute == minute => fill_bucket(b, rec), + Some(b) if b.minute > minute => { /* arrived older than the tail — ignore for series */ + } + _ => { + let mut b = Bucket { + minute, + ..Default::default() + }; + fill_bucket(&mut b, rec); + inner.buckets.push_back(b); + } + } + // trim old buckets outside the retention window + let cutoff = now_secs().saturating_sub(retention_secs); + while let Some(front) = inner.buckets.front() { + if front.minute < cutoff { + inner.buckets.pop_front(); + } else { + break; + } + } + } + + /// Record a new request event. + pub fn record(&self, rec: RequestRecord) { + if !self.enabled { + return; + } + { + let mut inner = self.inner.lock().unwrap(); + Self::apply_aggregates(&mut inner, &rec, self.retention_secs); + Self::push_recent(&mut inner, &rec, self.ring_size); + } + if let Some(path) = &self.file { + if let Ok(line) = serde_json::to_string(&rec) { + if let Ok(mut f) = std::fs::OpenOptions::new() + .create(true) + .append(true) + .open(path) + { + let _ = writeln!(f, "{line}"); + } + } + } + } + + /// Snapshot for the admin API: aggregates + time series for `range_secs` + breakdown by `groupby`. + pub fn snapshot(&self, range_secs: u64, groupby: &str) -> serde_json::Value { + let inner = self.inner.lock().unwrap(); + let cutoff = now_secs().saturating_sub(range_secs); + let series: Vec<&Bucket> = inner + .buckets + .iter() + .filter(|b| b.minute >= cutoff) + .collect(); + + let breakdown_src = match groupby { + "account" => &inner.by_account, + "tier" => &inner.by_tier, + "label" => &inner.by_label, + _ => &inner.by_model, + }; + let mut breakdown: Vec = breakdown_src + .iter() + .map(|(k, t)| { + serde_json::json!({ + "key": k, + "requests": t.requests, + "ok": t.ok, + "errors": t.errors, + "prompt_tokens": t.prompt_tokens, + "completion_tokens": t.completion_tokens, + "cost_usd": t.cost_usd, + "avg_latency_ms": avg(t.latency_ms_sum, t.requests), + }) + }) + .collect(); + breakdown.sort_by(|a, b| { + b["requests"] + .as_u64() + .unwrap_or(0) + .cmp(&a["requests"].as_u64().unwrap_or(0)) + }); + + serde_json::json!({ + "totals": { + "requests": inner.total.requests, + "ok": inner.total.ok, + "errors": inner.total.errors, + "failovers": inner.total.failovers, + "prompt_tokens": inner.total.prompt_tokens, + "completion_tokens": inner.total.completion_tokens, + "total_tokens": inner.total.prompt_tokens + inner.total.completion_tokens, + "cost_usd": inner.total.cost_usd, + "avg_latency_ms": avg(inner.total.latency_ms_sum, inner.total.requests), + "success_rate": if inner.total.requests > 0 { + inner.total.ok as f64 / inner.total.requests as f64 + } else { 0.0 }, + }, + "groupby": groupby, + "breakdown": breakdown, + "series": series, + }) + } + + /// Recent requests (newest first), with pagination. + pub fn recent(&self, limit: usize, offset: usize) -> Vec { + let inner = self.inner.lock().unwrap(); + inner + .recent + .iter() + .rev() + .skip(offset) + .take(limit) + .cloned() + .collect() + } + + /// Metrics text in Prometheus format. + pub fn prometheus(&self) -> String { + let inner = self.inner.lock().unwrap(); + let mut out = String::new(); + let t = &inner.total; + out.push_str("# HELP gw_requests_total Total gateway requests.\n"); + out.push_str("# TYPE gw_requests_total counter\n"); + out.push_str(&format!("gw_requests_total {}\n", t.requests)); + out.push_str("# HELP gw_failovers_total Total provider failovers.\n"); + out.push_str("# TYPE gw_failovers_total counter\n"); + out.push_str(&format!("gw_failovers_total {}\n", t.failovers)); + out.push_str("# HELP gw_tokens_total Total tokens by direction.\n"); + out.push_str("# TYPE gw_tokens_total counter\n"); + out.push_str(&format!( + "gw_tokens_total{{direction=\"in\"}} {}\n", + t.prompt_tokens + )); + out.push_str(&format!( + "gw_tokens_total{{direction=\"out\"}} {}\n", + t.completion_tokens + )); + out.push_str("# HELP gw_cost_usd_total Total estimated cost in USD.\n"); + out.push_str("# TYPE gw_cost_usd_total counter\n"); + out.push_str(&format!("gw_cost_usd_total {:.6}\n", t.cost_usd)); + out.push_str("# HELP gw_provider_calls_total Calls by model and outcome.\n"); + out.push_str("# TYPE gw_provider_calls_total counter\n"); + for (model, mt) in &inner.by_model { + let model = escape_label(model); + out.push_str(&format!( + "gw_provider_calls_total{{model_id=\"{model}\",outcome=\"ok\"}} {}\n", + mt.ok + )); + out.push_str(&format!( + "gw_provider_calls_total{{model_id=\"{model}\",outcome=\"error\"}} {}\n", + mt.errors + )); + } + out + } +} + +fn fill_bucket(b: &mut Bucket, r: &RequestRecord) { + b.requests += 1; + if r.outcome != "ok" { + b.errors += 1; + } + b.prompt_tokens += r.prompt_tokens as u64; + b.completion_tokens += r.completion_tokens as u64; + b.cost_usd += r.cost_usd; + b.latency_ms_sum += r.latency_ms; +} + +fn avg(sum: u64, n: u64) -> u64 { + sum.checked_div(n).unwrap_or(0) +} + +fn escape_label(s: &str) -> String { + s.replace('\\', "\\\\") + .replace('"', "\\\"") + .replace('\n', " ") +} + +/// Parse a duration string of the form `7d` / `24h` / `90m` / `3600s` into seconds. +pub fn parse_duration_secs(s: &str) -> Option { + let s = s.trim(); + if s.is_empty() { + return None; + } + let (num, mult) = if let Some(n) = s.strip_suffix('d') { + (n, 86_400) + } else if let Some(n) = s.strip_suffix('h') { + (n, 3_600) + } else if let Some(n) = s.strip_suffix('m') { + (n, 60) + } else if let Some(n) = s.strip_suffix('s') { + (n, 1) + } else { + (s, 1) + }; + num.trim().parse::().ok().map(|v| v * mult) +} diff --git a/web/css/styles.css b/web/css/styles.css new file mode 100644 index 0000000..1845488 --- /dev/null +++ b/web/css/styles.css @@ -0,0 +1,309 @@ +/* =========================================================================== + allaigate Gateway Console — design system (build-free, no framework) + Ported from cortiq-console, extended with light theme, charts, KPIs, modal. + =========================================================================== */ +:root, +:root[data-theme="dark"] { + --bg: #0a0e1a; + --bg-2: #0e1424; + --panel: #131a2c; + --card: #151d31; + --card-2: #121a2c; + --border: #243049; + --border-soft: #1d2740; + --text: #e6ecf7; + --muted: #8b97b0; + --faint: #5e6b85; + --accent: #6366f1; + --accent-2: #5eead4; + --gold: #f59e0b; + --good: #34d399; + --warn: #fbbf24; + --bad: #f87171; + --grid: #ffffff14; + --shadow: 0 8px 30px rgba(0, 0, 0, 0.35); + --hover: #ffffff0a; + --bg-grad: radial-gradient(1200px 700px at 80% -10%, #16203a 0%, var(--bg) 55%); + --radius: 14px; + --radius-sm: 9px; + --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; + --sans: "Inter", system-ui, -apple-system, Segoe UI, Roboto, sans-serif; +} + +:root[data-theme="light"] { + --bg: #f5f7fb; + --bg-2: #ffffff; + --panel: #ffffff; + --card: #ffffff; + --card-2: #f7f9fc; + --border: #d8e0ee; + --border-soft: #e6ebf4; + --text: #0f172a; + --muted: #5a6781; + --faint: #8a96ad; + --accent: #5457e6; + --accent-2: #0ea5a4; + --gold: #d97706; + --good: #10b981; + --warn: #d97706; + --bad: #ef4444; + --grid: #0f172a14; + --shadow: 0 8px 24px rgba(15, 23, 42, 0.08); + --hover: #0f172a08; + --bg-grad: radial-gradient(1200px 700px at 80% -10%, #e7edf9 0%, var(--bg) 55%); +} + +* { box-sizing: border-box; } +html, body { height: 100%; } +body { + margin: 0; + font-family: var(--sans); + background: var(--bg-grad); + color: var(--text); + font-size: 14px; + -webkit-font-smoothing: antialiased; +} +a { color: var(--accent-2); text-decoration: none; } +a:hover { text-decoration: underline; } +h1, h2, h3 { font-weight: 700; letter-spacing: -0.01em; } +h2 { font-size: 20px; margin: 0 0 4px; } +h3 { font-size: 15px; margin: 0 0 10px; } +code, .mono { font-family: var(--mono); } +.boot { padding: 60px; text-align: center; color: var(--faint); } + +/* ---- layout -------------------------------------------------------------- */ +.app { display: grid; grid-template-columns: 250px 1fr; min-height: 100vh; } +.sidebar { + background: linear-gradient(180deg, var(--bg-2), var(--bg)); + border-right: 1px solid var(--border-soft); + padding: 18px 14px; + display: flex; flex-direction: column; gap: 4px; + position: sticky; top: 0; height: 100vh; +} +.main { display: flex; flex-direction: column; min-width: 0; } +.content { padding: 24px 32px 64px; max-width: 1220px; width: 100%; } + +/* ---- brand + nav --------------------------------------------------------- */ +.brand { display: flex; align-items: center; gap: 10px; padding: 6px 8px 16px; } +.brand img { width: 30px; height: 30px; } +.brand b { font-size: 16px; } +.brand .sub { color: var(--muted); font-weight: 500; font-size: 13px; } +.nav-item { + display: flex; align-items: center; gap: 11px; + padding: 10px 12px; border-radius: var(--radius-sm); + color: var(--muted); cursor: pointer; font-weight: 500; + border: 1px solid transparent; user-select: none; +} +.nav-item:hover { background: var(--hover); color: var(--text); } +.nav-item.active { background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--text); border-color: color-mix(in srgb, var(--accent) 35%, transparent); } +.nav-item .ico { width: 18px; text-align: center; opacity: 0.95; font-size: 15px; } +.nav-spacer { flex: 1; } +.nav-foot { font-size: 11px; color: var(--faint); padding: 8px; } + +/* ---- topbar -------------------------------------------------------------- */ +.topbar { + display: flex; align-items: center; gap: 14px; + padding: 13px 32px; border-bottom: 1px solid var(--border-soft); + position: sticky; top: 0; background: color-mix(in srgb, var(--bg) 85%, transparent); + backdrop-filter: blur(8px); z-index: 5; +} +.topbar .title { font-weight: 600; font-size: 15px; } +.topbar .right { margin-left: auto; display: flex; align-items: center; gap: 10px; } +.icon-btn { + background: var(--panel); border: 1px solid var(--border); color: var(--muted); + width: 34px; height: 32px; border-radius: 8px; cursor: pointer; font-size: 15px; + display: inline-flex; align-items: center; justify-content: center; +} +.icon-btn:hover { color: var(--text); border-color: var(--accent); } +.lang-select { + background: var(--panel); border: 1px solid var(--border); color: var(--text); + border-radius: 8px; padding: 6px 8px; font-size: 12px; font-weight: 600; width: auto; +} + +/* ---- status pill --------------------------------------------------------- */ +.pill { + display: inline-flex; align-items: center; gap: 7px; + padding: 5px 11px; border-radius: 999px; font-size: 12px; font-weight: 600; + border: 1px solid var(--border); background: var(--panel); +} +.dot { width: 8px; height: 8px; border-radius: 50%; background: var(--faint); } +.dot.ok { background: var(--good); box-shadow: 0 0 0 3px color-mix(in srgb, var(--good) 18%, transparent); } +.dot.bad { background: var(--bad); box-shadow: 0 0 0 3px color-mix(in srgb, var(--bad) 18%, transparent); } +.dot.warn { background: var(--warn); } + +/* ---- cards --------------------------------------------------------------- */ +.card { + background: linear-gradient(180deg, var(--card), var(--card-2)); + border: 1px solid var(--border-soft); border-radius: var(--radius); + padding: 20px; box-shadow: var(--shadow); margin-bottom: 18px; +} +.card .card-head { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; } +.card .card-head .sub { color: var(--muted); font-weight: 400; font-size: 13px; } +.card .card-head .right { margin-left: auto; display: flex; gap: 8px; align-items: center; } +.grid { display: grid; gap: 18px; } +.grid.cols-2 { grid-template-columns: repeat(2, 1fr); } +.grid.cols-3 { grid-template-columns: repeat(3, 1fr); } +@media (max-width: 980px) { .grid.cols-2, .grid.cols-3 { grid-template-columns: 1fr; } .app { grid-template-columns: 1fr; } .sidebar { display: none; } } + +.page-head { margin-bottom: 20px; } +.page-head .flex { justify-content: space-between; align-items: flex-start; } +.page-head p { color: var(--muted); margin: 6px 0 0; max-width: 74ch; } + +/* ---- KPI ----------------------------------------------------------------- */ +.kpis { display: grid; grid-template-columns: repeat(6, 1fr); gap: 14px; margin-bottom: 18px; } +@media (max-width: 1100px) { .kpis { grid-template-columns: repeat(3, 1fr); } } +@media (max-width: 620px) { .kpis { grid-template-columns: repeat(2, 1fr); } } +.kpi { + background: linear-gradient(180deg, var(--card), var(--card-2)); + border: 1px solid var(--border-soft); border-radius: var(--radius); padding: 14px 16px; +} +.kpi .big { font-size: 24px; font-weight: 800; letter-spacing: -0.02em; } +.kpi .lbl { color: var(--muted); font-size: 12px; margin-top: 3px; } + +/* ---- forms --------------------------------------------------------------- */ +label.field { display: block; margin-bottom: 14px; } +label.field > span { display: block; color: var(--muted); font-size: 12px; margin-bottom: 6px; font-weight: 600; } +input, select, textarea { + width: 100%; background: var(--bg-2); border: 1px solid var(--border); + color: var(--text); border-radius: var(--radius-sm); padding: 10px 12px; + font-family: inherit; font-size: 14px; outline: none; +} +input:focus, select:focus, textarea:focus { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent); } +textarea { resize: vertical; min-height: 64px; } +.row { display: flex; gap: 12px; flex-wrap: wrap; } +.row > * { flex: 1; min-width: 150px; } +.inline { display: flex; align-items: center; gap: 8px; } +.check { display: flex; align-items: center; gap: 8px; cursor: pointer; margin-bottom: 12px; } +.check input { width: auto; } +.hint { color: var(--faint); font-size: 12px; margin-top: 4px; } + +/* ---- buttons ------------------------------------------------------------- */ +.btn { + display: inline-flex; align-items: center; justify-content: center; gap: 8px; + background: var(--panel); color: var(--text); border: 1px solid var(--border); + border-radius: var(--radius-sm); padding: 10px 16px; cursor: pointer; + font-weight: 600; font-size: 14px; font-family: inherit; transition: 0.12s; +} +.btn:hover { border-color: var(--accent); background: var(--hover); } +.btn:disabled { opacity: 0.5; cursor: not-allowed; } +.btn.primary { background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 88%, #fff), var(--accent)); border-color: var(--accent); color: #fff; } +.btn.primary:hover { filter: brightness(1.08); } +.btn.gold { background: linear-gradient(180deg, color-mix(in srgb, var(--gold) 85%, #fff), var(--gold)); border-color: var(--gold); color: #1a1206; } +.btn.ghost { background: transparent; } +.btn.danger { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 35%, transparent); } +.btn.danger:hover { background: color-mix(in srgb, var(--bad) 10%, transparent); } +.btn.sm { padding: 6px 11px; font-size: 12.5px; } + +/* ---- badges -------------------------------------------------------------- */ +.badge { + display: inline-flex; align-items: center; gap: 6px; padding: 3px 9px; + border-radius: 999px; font-size: 11.5px; font-weight: 700; border: 1px solid var(--border); + background: var(--bg-2); color: var(--muted); +} +.badge.tier-low, .badge.cheap, .badge.ok { color: var(--good); border-color: color-mix(in srgb, var(--good) 40%, transparent); background: color-mix(in srgb, var(--good) 8%, transparent); } +.badge.tier-medium, .badge.mid, .badge.warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 40%, transparent); background: color-mix(in srgb, var(--warn) 8%, transparent); } +.badge.tier-high, .badge.expensive, .badge.bad, .badge.error { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 40%, transparent); background: color-mix(in srgb, var(--bad) 8%, transparent); } +.badge.router, .badge.store { color: var(--accent-2); border-color: color-mix(in srgb, var(--accent-2) 40%, transparent); background: color-mix(in srgb, var(--accent-2) 8%, transparent); } +.badge.env { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 40%, transparent); background: color-mix(in srgb, var(--accent) 8%, transparent); } + +/* ---- tables -------------------------------------------------------------- */ +.table-wrap { overflow-x: auto; } +table { width: 100%; border-collapse: collapse; } +th, td { text-align: left; padding: 11px 12px; border-bottom: 1px solid var(--border-soft); white-space: nowrap; } +th { color: var(--faint); font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; font-weight: 700; } +tr:last-child td { border-bottom: 0; } +td .mono { font-size: 12.5px; color: var(--muted); } +tbody tr:hover td { background: var(--hover); } + +/* ---- chips (routing) ----------------------------------------------------- */ +.tierrow { display: flex; align-items: center; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--border-soft); } +.tierrow:last-child { border-bottom: 0; } +.tierrow .tname { width: 110px; font-weight: 700; } +.chips { display: flex; gap: 8px; flex-wrap: wrap; flex: 1; align-items: center; } +.chip { display: inline-flex; align-items: center; gap: 7px; background: var(--bg-2); border: 1px solid var(--border); border-radius: 999px; padding: 5px 6px 5px 11px; font-weight: 600; font-size: 13px; } +.chip .ord { width: 16px; height: 16px; border-radius: 50%; background: var(--accent); color: #fff; font-size: 10px; display: inline-flex; align-items: center; justify-content: center; font-weight: 800; } +.chip .arrow { cursor: pointer; color: var(--faint); padding: 0 1px; } +.chip .arrow:hover { color: var(--text); } +.chip .x { cursor: pointer; color: var(--faint); border-radius: 50%; width: 18px; height: 18px; display: inline-flex; align-items: center; justify-content: center; } +.chip .x:hover { color: var(--bad); background: color-mix(in srgb, var(--bad) 12%, transparent); } + +/* ---- toggle list (protocols) --------------------------------------------- */ +.togglerow { display: flex; align-items: center; gap: 14px; padding: 14px 0; border-bottom: 1px solid var(--border-soft); } +.togglerow:last-child { border-bottom: 0; } +.togglerow .meta { flex: 1; } +.togglerow .meta .name { font-weight: 600; display: flex; gap: 8px; align-items: center; } +.togglerow .meta .desc { color: var(--muted); font-size: 12.5px; margin-top: 3px; } +.switch { position: relative; width: 44px; height: 24px; flex: none; } +.switch input { opacity: 0; width: 0; height: 0; } +.switch .slider { position: absolute; inset: 0; background: var(--border); border-radius: 999px; transition: 0.15s; cursor: pointer; } +.switch .slider::before { content: ""; position: absolute; width: 18px; height: 18px; left: 3px; top: 3px; background: #fff; border-radius: 50%; transition: 0.15s; } +.switch input:checked + .slider { background: var(--accent); } +.switch input:checked + .slider::before { transform: translateX(20px); } +.switch input:disabled + .slider { opacity: 0.5; cursor: not-allowed; } + +/* ---- charts -------------------------------------------------------------- */ +.chart { width: 100%; height: 180px; display: block; } +.chart .axis { stroke: var(--grid); stroke-width: 1; } +.chart .area { fill: color-mix(in srgb, var(--accent) 16%, transparent); } +.chart .line { fill: none; stroke: var(--accent); stroke-width: 2; } +.chart .bar { fill: var(--accent); } +.barlist { display: flex; flex-direction: column; gap: 10px; } +.barlist .b { display: grid; grid-template-columns: 130px 1fr auto; gap: 10px; align-items: center; font-size: 13px; } +.barlist .b .track { background: var(--bg-2); border-radius: 5px; height: 10px; overflow: hidden; } +.barlist .b .track > i { display: block; height: 100%; background: linear-gradient(90deg, var(--accent-2), var(--accent)); } +.barlist .b .val { color: var(--muted); font-weight: 600; min-width: 56px; text-align: right; } + +/* ---- playground ---------------------------------------------------------- */ +.pg { display: grid; grid-template-columns: 1fr 340px; gap: 18px; align-items: start; } +@media (max-width: 1024px) { .pg { grid-template-columns: 1fr; } } +.answer { white-space: pre-wrap; word-break: break-word; line-height: 1.55; background: var(--panel); border: 1px solid var(--border-soft); border-radius: 12px; padding: 14px 16px; min-height: 120px; } +.routecard .kv { display: flex; justify-content: space-between; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--border-soft); } +.routecard .kv:last-child { border-bottom: 0; } +.routecard .kv .k { color: var(--muted); } +.routecard .kv .v { font-weight: 600; text-align: right; } +.scorebar { height: 7px; background: var(--bg-2); border-radius: 4px; overflow: hidden; margin-top: 6px; } +.scorebar > i { display: block; height: 100%; background: linear-gradient(90deg, var(--accent-2), var(--accent)); } + +/* ---- modal --------------------------------------------------------------- */ +.modal-backdrop { position: fixed; inset: 0; background: rgba(3, 7, 18, 0.6); display: flex; align-items: flex-start; justify-content: center; padding: 48px 16px; z-index: 40; overflow: auto; } +.modal { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); width: 100%; max-width: 560px; padding: 22px; } +.modal h3 { font-size: 17px; margin-bottom: 16px; } +.modal .modal-foot { display: flex; justify-content: flex-end; gap: 10px; margin-top: 8px; } + +/* ---- login --------------------------------------------------------------- */ +.login-wrap { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 20px; } +.login-card { width: 100%; max-width: 400px; background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); padding: 30px; } +.login-card .brand { justify-content: center; padding-top: 0; } +.login-card h2 { text-align: center; } +.login-card p.sub { color: var(--muted); text-align: center; margin: 4px 0 22px; } + +/* ---- misc ---------------------------------------------------------------- */ +.empty { text-align: center; color: var(--faint); padding: 40px 20px; } +.spinner { width: 16px; height: 16px; border: 2px solid color-mix(in srgb, var(--text) 25%, transparent); border-top-color: var(--text); border-radius: 50%; animation: spin 0.7s linear infinite; display: inline-block; } +@keyframes spin { to { transform: rotate(360deg); } } +.divider { height: 1px; background: var(--border-soft); margin: 18px 0; } +.muted { color: var(--muted); } +.right-align { text-align: right; } +.flex { display: flex; gap: 10px; align-items: center; } +.flex.wrap { flex-wrap: wrap; } +.grow { flex: 1; } +.seg { display: inline-flex; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; } +.seg button { background: transparent; border: 0; color: var(--muted); padding: 6px 12px; cursor: pointer; font-size: 12.5px; font-weight: 600; } +.seg button.active { background: var(--accent); color: #fff; } + +/* ---- toasts -------------------------------------------------------------- */ +.toasts { position: fixed; bottom: 22px; right: 22px; display: flex; flex-direction: column; gap: 10px; z-index: 60; } +.toast { + background: var(--panel); border: 1px solid var(--border); border-left: 3px solid var(--accent); + padding: 12px 16px; border-radius: 10px; box-shadow: var(--shadow); min-width: 220px; + animation: slidein 0.18s ease; font-size: 13px; +} +.toast.good { border-left-color: var(--good); } +.toast.bad { border-left-color: var(--bad); } +.toast.warn { border-left-color: var(--warn); } +@keyframes slidein { from { transform: translateX(20px); opacity: 0; } to { transform: none; opacity: 1; } } + +/* ---- callout ------------------------------------------------------------- */ +.callout { border: 1px solid var(--border); border-left: 3px solid var(--warn); background: color-mix(in srgb, var(--warn) 6%, transparent); border-radius: 10px; padding: 13px 15px; color: var(--muted); margin-bottom: 16px; } +.callout.info { border-left-color: var(--accent-2); background: color-mix(in srgb, var(--accent-2) 6%, transparent); } +.callout b { color: var(--text); } diff --git a/web/favicon.svg b/web/favicon.svg new file mode 100644 index 0000000..80d2659 --- /dev/null +++ b/web/favicon.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/web/index.html b/web/index.html new file mode 100644 index 0000000..0b17335 --- /dev/null +++ b/web/index.html @@ -0,0 +1,24 @@ + + + + + allaigate · Gateway Console + + + + + + + + +

Loading…
+
+ + + diff --git a/web/js/api.js b/web/js/api.js new file mode 100644 index 0000000..2e7fc9f --- /dev/null +++ b/web/js/api.js @@ -0,0 +1,93 @@ +// Thin client over the gateway's /admin/api surface. Adds the Bearer admin token, +// parses JSON, and throws Error(message) on non-2xx so views can try/catch. +// A 401 sets an "unauthorized" flag the app uses to show the login screen. + +const BASE = "/admin/api"; +const TOKEN_KEY = "allaigate_token"; + +let onUnauthorized = null; +export function setUnauthorizedHandler(fn) { + onUnauthorized = fn; +} + +export function getToken() { + return localStorage.getItem(TOKEN_KEY) || ""; +} +export function setToken(tok) { + if (tok) localStorage.setItem(TOKEN_KEY, tok); + else localStorage.removeItem(TOKEN_KEY); +} + +async function j(method, path, body) { + const opt = { method, headers: { Authorization: "Bearer " + getToken() } }; + if (body !== undefined) { + opt.headers["content-type"] = "application/json"; + opt.body = JSON.stringify(body); + } + const r = await fetch(BASE + path, opt); + if (r.status === 401) { + if (onUnauthorized) onUnauthorized(); + throw new Error("unauthorized"); + } + const text = await r.text(); + let data = null; + try { + data = text ? JSON.parse(text) : null; + } catch { + data = text; + } + if (!r.ok) { + const msg = + (data && data.error && (data.error.message || data.error)) || + (data && (data.detail || data.message)) || + r.statusText; + throw new Error(typeof msg === "string" ? msg : JSON.stringify(msg)); + } + return data; +} + +export const api = { + // meta / health + meta: () => j("GET", "/meta"), + health: () => j("GET", "/health"), + + // config + getConfig: () => j("GET", "/config"), + putConfig: (b) => j("PUT", "/config", b), + + // models + listModels: () => j("GET", "/models"), + createModel: (b) => j("POST", "/models", b), + updateModel: (id, b) => j("PUT", "/models/" + encodeURIComponent(id), b), + deleteModel: (id) => j("DELETE", "/models/" + encodeURIComponent(id)), + probeModel: (id) => j("POST", "/models/" + encodeURIComponent(id) + "/probe"), + + // routing + getRouting: () => j("GET", "/routing"), + putRouting: (b) => j("PUT", "/routing", b), + + // protocols + getProtocols: () => j("GET", "/protocols"), + putProtocols: (b) => j("PUT", "/protocols", b), + + // settings + getSettings: () => j("GET", "/settings"), + putSettings: (b) => j("PUT", "/settings", b), + + // keys + listKeys: () => j("GET", "/keys"), + createKey: (b) => j("POST", "/keys", b), + deleteKey: (k) => j("DELETE", "/keys/" + encodeURIComponent(k)), + + // secrets + listSecrets: () => j("GET", "/secrets"), + setSecret: (name, value) => j("PUT", "/secrets", { name, value }), + clearSecret: (name) => j("DELETE", "/secrets?name=" + encodeURIComponent(name)), + + // stats + stats: (range, groupby) => j("GET", `/stats?range=${range}&groupby=${groupby}`), + requests: (limit = 50, offset = 0) => j("GET", `/requests?limit=${limit}&offset=${offset}`), + + // playground + test: (b) => j("POST", "/test", b), +}; diff --git a/web/js/app.js b/web/js/app.js new file mode 100644 index 0000000..7720e32 --- /dev/null +++ b/web/js/app.js @@ -0,0 +1,228 @@ +// App bootstrap: login gate, sidebar, topbar, hash router, language + theme. +import { h, mount, toast } from "./ui.js"; +import { t, getLang, setLang, onLangChange, LANGS } from "./i18n.js"; +import { api, getToken, setToken, setUnauthorizedHandler } from "./api.js"; +import { renderLogin } from "./views/login.js"; +import { renderDashboard } from "./views/dashboard.js"; +import { renderModels } from "./views/models.js"; +import { renderRouting } from "./views/routing.js"; +import { renderProtocols } from "./views/protocols.js"; +import { renderKeys } from "./views/keys.js"; +import { renderPlayground } from "./views/playground.js"; +import { renderSettings } from "./views/settings.js"; + +const ROUTES = [ + { id: "dashboard", icon: "▤", view: renderDashboard }, + { id: "models", icon: "▦", view: renderModels }, + { id: "routing", icon: "⇄", view: renderRouting }, + { id: "protocols", icon: "⇆", view: renderProtocols }, + { id: "keys", icon: "🔑", view: renderKeys }, + { id: "playground", icon: "✦", view: renderPlayground }, + { id: "settings", icon: "⚙", view: renderSettings }, +]; + +export const appState = { meta: null, health: null, version: "" }; + +function currentRoute() { + const id = location.hash.replace(/^#\/?/, "") || "dashboard"; + return ROUTES.find((r) => r.id === id) || ROUTES[0]; +} + +const FAVICON = + "data:image/svg+xml;utf8," + + encodeURIComponent( + '' + ); + +function sidebar(activeId) { + return h( + "aside", + { class: "sidebar", id: "sidebar" }, + h( + "div", + { class: "brand" }, + h("img", { src: FAVICON, alt: "" }), + h("div", {}, h("b", {}, "allaigate"), h("div", { class: "sub" }, t("brand.sub"))) + ), + ...ROUTES.map((r) => + h( + "a", + { class: "nav-item" + (r.id === activeId ? " active" : ""), href: "#/" + r.id }, + h("span", { class: "ico" }, r.icon), + t("nav." + r.id) + ) + ), + h("div", { class: "nav-spacer" }), + h("div", { class: "nav-foot" }, t("nav.foot", { v: appState.version || "—" })) + ); +} + +function statusPills() { + const h_ = appState.health; + const gwOk = !!appState.meta; + const routerOk = h_?.router?.reachable; + return h( + "div", + { class: "flex" }, + h( + "span", + { class: "pill" }, + h("span", { class: "dot " + (gwOk ? "ok" : "bad") }), + t("status.gateway") + ": " + (gwOk ? t("status.online") : t("status.offline")) + ), + h( + "span", + { class: "pill", title: h_?.router?.url || "" }, + h("span", { class: "dot " + (h_ ? (routerOk ? "ok" : "bad") : "warn") }), + t("status.router") + ": " + (h_ ? (routerOk ? t("status.online") : t("status.offline")) : t("status.checking")) + ) + ); +} + +function langSelect() { + const sel = h( + "select", + { + class: "lang-select", + title: "Language", + onChange: (e) => setLang(e.target.value), + }, + ...LANGS.map((l) => h("option", { value: l.code, selected: l.code === getLang() }, l.label)) + ); + return sel; +} + +function themeToggle() { + const cur = document.documentElement.getAttribute("data-theme") || "dark"; + return h( + "button", + { + class: "icon-btn", + title: t("theme.toggle"), + onClick: () => { + const next = (document.documentElement.getAttribute("data-theme") || "dark") === "dark" ? "light" : "dark"; + document.documentElement.setAttribute("data-theme", next); + localStorage.setItem("allaigate_theme", next); + renderShell(); + }, + }, + cur === "dark" ? "☀" : "☾" + ); +} + +function topbar(activeId) { + return h( + "header", + { class: "topbar" }, + h("div", { class: "title" }, t("nav." + activeId)), + h( + "div", + { class: "right" }, + statusPills(), + themeToggle(), + langSelect(), + h( + "button", + { + class: "icon-btn", + title: t("logout"), + onClick: () => { + setToken(""); + boot(); + }, + }, + "⎋" + ) + ) + ); +} + +async function renderView() { + const route = currentRoute(); + const view = document.getElementById("view"); + if (!view) return; + mount(view, h("div", { class: "empty" }, h("span", { class: "spinner" }), " ", t("common.loading"))); + try { + const node = await route.view(); + mount(view, node); + } catch (e) { + if (String(e.message) === "unauthorized") return; + mount(view, h("div", { class: "callout" }, String(e.message || e))); + } +} + +function renderShell() { + const route = currentRoute(); + mount( + document.getElementById("app"), + h( + "div", + { class: "app" }, + sidebar(route.id), + h("main", { class: "main" }, topbar(route.id), h("div", { class: "content", id: "view" })) + ) + ); + renderView(); +} + +function showLogin() { + mount(document.getElementById("app"), renderLogin(boot)); +} + +async function refreshHealth() { + try { + appState.health = await api.health(); + } catch { + appState.health = null; + } + // re-render topbar only if shell present + const route = currentRoute(); + const main = document.querySelector(".main"); + if (main) { + const old = main.querySelector(".topbar"); + if (old) old.replaceWith(topbar(route.id)); + } +} + +export async function boot() { + // convenience: /admin?token=… logs in once, then is stripped from the URL + const urlTok = new URLSearchParams(location.search).get("token"); + if (urlTok) { + setToken(urlTok); + history.replaceState({}, "", location.pathname + location.hash); + } + if (!getToken()) { + showLogin(); + return; + } + try { + appState.meta = await api.meta(); + appState.version = appState.meta.version || ""; + } catch (e) { + if (String(e.message) === "unauthorized") { + showLogin(); + return; + } + // gateway reachable but error — still show shell + } + if (!location.hash) location.hash = "#/dashboard"; + renderShell(); + refreshHealth(); +} + +setUnauthorizedHandler(() => { + toast(t("login.failed"), "bad"); + setToken(""); + showLogin(); +}); +onLangChange(() => { + if (document.querySelector(".app")) renderShell(); +}); +window.addEventListener("hashchange", () => { + if (document.querySelector(".app")) renderShell(); +}); +setInterval(() => { + if (document.querySelector(".app")) refreshHealth(); +}, 20000); + +boot(); diff --git a/web/js/charts.js b/web/js/charts.js new file mode 100644 index 0000000..0819e8d --- /dev/null +++ b/web/js/charts.js @@ -0,0 +1,56 @@ +// Dependency-free SVG charts. Build-free, theme-aware via CSS classes. +import { h } from "./ui.js"; + +const SVGNS = "http://www.w3.org/2000/svg"; +function s(tag, attrs = {}, ...children) { + const el = document.createElementNS(SVGNS, tag); + for (const [k, v] of Object.entries(attrs)) if (v != null) el.setAttribute(k, v); + for (const c of children.flat()) if (c != null) el.appendChild(c); + return el; +} + +// Area+line chart from time buckets. `field` is a key on each bucket. +export function lineChart(buckets, field) { + const W = 600, H = 180, padL = 8, padR = 8, padT = 12, padB = 14; + const data = (buckets || []).map((b) => Number(b[field] || 0)); + const svg = s("svg", { class: "chart", viewBox: `0 0 ${W} ${H}`, preserveAspectRatio: "none" }); + // baseline + mid gridlines + for (let i = 0; i <= 2; i++) { + const y = padT + ((H - padT - padB) * i) / 2; + svg.appendChild(s("line", { class: "axis", x1: padL, y1: y, x2: W - padR, y2: y })); + } + if (data.length < 2) return svg; + const max = Math.max(1, ...data); + const innerW = W - padL - padR, innerH = H - padT - padB; + const x = (i) => padL + (innerW * i) / (data.length - 1); + const y = (v) => padT + innerH - (innerH * v) / max; + let line = "", area = `M ${x(0)} ${y(0)}`; + data.forEach((v, i) => { + const cmd = i === 0 ? "M" : "L"; + line += `${cmd} ${x(i).toFixed(1)} ${y(v).toFixed(1)} `; + area += ` L ${x(i).toFixed(1)} ${y(v).toFixed(1)}`; + }); + area += ` L ${x(data.length - 1)} ${y(0)} Z`; + svg.appendChild(s("path", { class: "area", d: area })); + svg.appendChild(s("path", { class: "line", d: line })); + return svg; +} + +// Horizontal bar list. items: [{key, value, sub}] +export function barList(items, fmt) { + const max = Math.max(1, ...items.map((i) => i.value)); + return h( + "div", + { class: "barlist" }, + items.length === 0 ? h("div", { class: "empty" }, "—") : null, + ...items.map((it) => + h( + "div", + { class: "b" }, + h("div", { class: "mono", title: it.key }, it.key || "—"), + h("div", { class: "track" }, h("i", { style: `width:${(it.value / max) * 100}%` })), + h("div", { class: "val" }, fmt ? fmt(it.value) : it.value) + ) + ) + ); +} diff --git a/web/js/i18n.js b/web/js/i18n.js new file mode 100644 index 0000000..f94ca39 --- /dev/null +++ b/web/js/i18n.js @@ -0,0 +1,56 @@ +// i18n engine. English is the source of truth; other languages override per key +// and fall back to English for any missing key. +import en from "./i18n/en.js"; +import ru from "./i18n/ru.js"; +import de from "./i18n/de.js"; +import fr from "./i18n/fr.js"; +import es from "./i18n/es.js"; +import zh from "./i18n/zh.js"; +import tr from "./i18n/tr.js"; + +const DICTS = { en, ru, de, fr, es, zh, tr }; +export const LANGS = [ + { code: "en", label: "English" }, + { code: "ru", label: "Русский" }, + { code: "de", label: "Deutsch" }, + { code: "fr", label: "Français" }, + { code: "es", label: "Español" }, + { code: "zh", label: "中文" }, + { code: "tr", label: "Türkçe" }, +]; + +const listeners = new Set(); + +function detect() { + const saved = localStorage.getItem("allaigate_lang"); + if (saved && DICTS[saved]) return saved; + const url = new URLSearchParams(location.search).get("lang"); + if (url && DICTS[url]) return url; + const nav = (navigator.language || "en").slice(0, 2).toLowerCase(); + return DICTS[nav] ? nav : "en"; +} + +let lang = detect(); + +export function getLang() { + return lang; +} + +export function setLang(l) { + lang = DICTS[l] ? l : "en"; + localStorage.setItem("allaigate_lang", lang); + document.documentElement.setAttribute("lang", lang); + listeners.forEach((fn) => fn(lang)); +} + +export function onLangChange(fn) { + listeners.add(fn); + return () => listeners.delete(fn); +} + +export function t(key, vars) { + const d = DICTS[lang] || en; + let s = d[key] ?? en[key] ?? key; + if (vars) for (const k of Object.keys(vars)) s = s.split("{" + k + "}").join(vars[k]); + return s; +} diff --git a/web/js/i18n/de.js b/web/js/i18n/de.js new file mode 100644 index 0000000..ee1409c --- /dev/null +++ b/web/js/i18n/de.js @@ -0,0 +1,256 @@ +// Deutsch — German translation for allaigate admin console. +export default { + // brand / common + "brand.sub": "Gateway", + "common.loading": "Laden…", + "common.save": "Speichern", + "common.saving": "Wird gespeichert…", + "common.cancel": "Abbrechen", + "common.add": "Hinzufügen", + "common.edit": "Bearbeiten", + "common.delete": "Löschen", + "common.close": "Schließen", + "common.test": "Testen", + "common.copy": "Kopieren", + "common.copied": "Kopiert", + "common.confirm": "Bestätigen", + "common.none": "keine", + "common.saved": "Gespeichert", + "common.error": "Fehler", + "common.ok": "OK", + "common.refresh": "Aktualisieren", + "common.actions": "Aktionen", + "common.optional": "optional", + "common.search": "Suchen", + "common.all": "alle", + + // nav + "nav.dashboard": "Dashboard", + "nav.models": "Modelle", + "nav.routing": "Routing", + "nav.protocols": "Protokolle", + "nav.keys": "API-Schlüssel", + "nav.playground": "Playground", + "nav.settings": "Einstellungen", + "nav.foot": "Gateway · v{v}", + + // topbar / status + "status.router": "Router", + "status.gateway": "Gateway", + "status.online": "online", + "status.offline": "offline", + "status.checking": "Prüfe…", + "theme.toggle": "Design", + "logout": "Abmelden", + + // login + "login.title": "allaigate Gateway", + "login.subtitle": "Admin-Token eingeben, um dieses Gateway zu verwalten.", + "login.token": "Admin-Token", + "login.tokenPlaceholder": "Admin-Token einfügen", + "login.submit": "Konsole öffnen", + "login.hint": "Das Token wird beim Start im Gateway-Log ausgegeben oder über [admin].token_env gesetzt.", + "login.failed": "Ungültiger Admin-Token.", + + // dashboard + "dash.title": "Dashboard", + "dash.subtitle": "Live-Traffic, Kosten und Routing-Analyse für Ihren Modell-Pool.", + "dash.range": "Zeitraum", + "dash.range.1h": "1h", + "dash.range.24h": "24h", + "dash.range.7d": "7d", + "dash.kpi.requests": "Anfragen", + "dash.kpi.tokens": "Tokens", + "dash.kpi.cost": "Kosten", + "dash.kpi.latency": "Ø Latenz", + "dash.kpi.success": "Erfolgsrate", + "dash.kpi.failovers": "Failovers", + "dash.series.title": "Anfragen im Zeitverlauf", + "dash.series.cost": "Kosten im Zeitverlauf", + "dash.series.empty": "Kein Traffic in diesem Zeitraum.", + "dash.breakdown.title": "Aufschlüsselung", + "dash.groupby.model": "nach Modell", + "dash.groupby.tier": "nach Tier", + "dash.groupby.label": "nach Aufgabe", + "dash.groupby.account": "nach Account", + "dash.recent.title": "Letzte Anfragen", + "dash.recent.empty": "Noch keine Anfragen aufgezeichnet. Playground ausprobieren.", + "dash.col.time": "Zeit", + "dash.col.model": "Modell", + "dash.col.tier": "Tier", + "dash.col.task": "Aufgabe", + "dash.col.tokens": "Tokens", + "dash.col.cost": "Kosten", + "dash.col.latency": "Latenz", + "dash.col.outcome": "Ergebnis", + "dash.col.requests": "Anfragen", + "dash.col.errors": "Fehler", + "dash.health.title": "Status", + "dash.health.reachable": "erreichbar", + "dash.health.unreachable": "nicht erreichbar", + + // models + "models.title": "Modelle", + "models.subtitle": "Ihr Modell-Pool — lokale Modelle und Cloud-APIs kombinieren.", + "models.add": "Modell hinzufügen", + "models.empty": "Noch keine Modelle. Erstes Modell hinzufügen.", + "models.col.id": "ID", + "models.col.provider": "Anbieter", + "models.col.model": "Modell", + "models.col.tier": "Kostenstufe", + "models.col.key": "Schlüssel", + "models.col.caps": "Fähigkeiten", + "models.col.price": "Preis (ein/aus)", + "models.probe": "Prüfen", + "models.probe.ok": "Erreichbar ({ms} ms)", + "models.probe.fail": "Fehlgeschlagen: {err}", + "models.form.addTitle": "Modell hinzufügen", + "models.form.editTitle": "Modell bearbeiten", + "models.form.id": "ID", + "models.form.idHint": "Eindeutige ID für das Routing, z. B. local-qwen", + "models.form.provider": "Anbieter", + "models.form.baseUrl": "Basis-URL", + "models.form.model": "Modellname", + "models.form.kind": "Typ", + "models.form.costTier": "Kostenstufe", + "models.form.priceIn": "Preis ein ($/1M)", + "models.form.priceOut": "Preis aus ($/1M)", + "models.form.apiKeyEnv": "API-Schlüssel Umgebungsvariable", + "models.form.apiKeyEnvHint": "Name der Umgebungsvariable / des gespeicherten Geheimnisses für den Anbieterschlüssel.", + "models.form.caps": "Fähigkeiten", + "models.form.secret": "Geheimwert", + "models.form.secretStored": "gespeichert", + "models.form.secretEnv": "aus Umgebung", + "models.form.secretMissing": "nicht gesetzt", + "models.form.secretPlaceholder": "Schlüssel setzen oder ersetzen (nur Schreiben)", + "models.deleteConfirm": "Modell \"{id}\" löschen?", + + // routing + "routing.title": "Routing", + "routing.subtitle": "Komplexitätsstufen einer priorisierten Modellliste zuordnen (Priorität = Fallback).", + "routing.default": "Standardmodell", + "routing.defaultHint": "Wird verwendet, wenn der Router nicht erreichbar ist.", + "routing.tiers": "Stufen", + "routing.tierHint": "Chips ziehen zum Sortieren; erstes bevorzugt, die übrigen sind Fallbacks.", + "routing.addModel": "+ hinzufügen", + "routing.addTier": "Stufe hinzufügen", + "routing.tierName": "Stufenname", + "routing.policy": "Richtlinie", + "routing.policy.mode": "Modus", + "routing.policy.fixed": "Feste Tabelle", + "routing.policy.costAware": "Kostenoptimiert", + "routing.policy.maxCost": "Max. Kosten pro Anfrage ($)", + "routing.policy.minClass": "Mindestklasse je Stufe", + "routing.empty": "Keine Modelle verfügbar — zuerst Modelle hinzufügen.", + + // protocols + "protocols.title": "Protokolle", + "protocols.subtitle": "Nur benötigte eingehende API-Oberflächen aktivieren. Änderungen wirken sofort.", + "protocols.implemented": "implementiert", + "protocols.planned": "geplant", + "protocols.openai_chat": "OpenAI Chat Completions", + "protocols.openai_chat.d": "POST /v1/chat/completions — kompatibel mit OpenAI SDK, LangChain, crewAI.", + "protocols.openai_completions": "OpenAI Completions (legacy)", + "protocols.openai_completions.d": "POST /v1/completions — Legacy-Integrationen.", + "protocols.openai_embeddings": "OpenAI Embeddings", + "protocols.openai_embeddings.d": "POST /v1/embeddings — RAG-Pipelines.", + "protocols.openai_models": "OpenAI Models", + "protocols.openai_models.d": "GET /v1/models — automatische Client-Erkennung.", + "protocols.anthropic_messages": "Anthropic Messages", + "protocols.anthropic_messages.d": "POST /v1/messages — Claude-native Agenten.", + "protocols.mcp": "MCP (Model Context Protocol)", + "protocols.mcp.d": "JSON-RPC / SSE — MCP-native Orchestratoren.", + "protocols.native_passthrough": "Nativer Passthrough", + "protocols.native_passthrough.d": "POST /route — direkter Zugriff auf die Routing-Entscheidung.", + + // keys + "keys.title": "API-Schlüssel", + "keys.subtitle": "Virtuelle Gateway-Schlüssel für Ihre Agenten. Anbieterschlüssel verlassen das Gateway nicht.", + "keys.add": "Neuer Schlüssel", + "keys.empty": "Keine Schlüssel konfiguriert — Gateway im offenen Modus (keine Authentifizierung).", + "keys.openMode": "Offener Modus: Alle Anfragen werden akzeptiert (kein Schlüssel erforderlich).", + "keys.col.key": "Schlüssel", + "keys.col.account": "Account", + "keys.col.rate": "Rate / Min.", + "keys.col.models": "Erlaubte Modelle", + "keys.form.title": "Neuer API-Schlüssel", + "keys.form.account": "Account", + "keys.form.rate": "Ratenlimit / Min.", + "keys.form.allow": "Erlaubte Modelle", + "keys.form.allowHint": "Leer lassen, um alle Modelle zu erlauben.", + "keys.form.custom": "Eigener Schlüssel (optional)", + "keys.form.customHint": "Leer lassen für automatische Generierung sk-gw-…", + "keys.created": "Schlüssel erstellt — jetzt kopieren, er wird nicht mehr angezeigt:", + "keys.revoke": "Widerrufen", + "keys.revokeConfirm": "Diesen Schlüssel widerrufen?", + "keys.allowAll": "alle", + + // playground + "pg.title": "Playground", + "pg.subtitle": "Prompt durch die Live-Pipeline senden und Routing-Entscheidung prüfen.", + "pg.system": "System-Prompt", + "pg.systemPlaceholder": "optionale Systemnachricht", + "pg.prompt": "Prompt", + "pg.promptPlaceholder": "Etwas fragen…", + "pg.mode": "Modus", + "pg.mode.auto": "Auto (Route)", + "pg.mode.pinned": "Fixiertes Modell", + "pg.profile": "Profil", + "pg.model": "Modell", + "pg.temp": "Temperatur", + "pg.maxTokens": "Max. Tokens", + "pg.send": "Senden", + "pg.sending": "Wird gesendet…", + "pg.answer": "Antwort", + "pg.empty": "Antwort und Routing-Entscheidung erscheinen hier.", + "pg.decision": "Routing-Entscheidung", + "pg.task": "Aufgabe", + "pg.tier": "Tier", + "pg.score": "Komplexität", + "pg.selected": "Gewähltes Modell", + "pg.source": "Route-Quelle", + "pg.cost": "Kosten", + "pg.latency": "Latenz", + "pg.tokens": "Tokens (ein/aus)", + "pg.failover": "Failover", + "pg.error": "Anfrage fehlgeschlagen", + + // settings + "settings.title": "Einstellungen", + "settings.subtitle": "Gateway-Verbindung, Routing-Eingabe, Zuverlässigkeit und Beobachtbarkeit.", + "settings.router": "Router-Verbindung", + "settings.router.url": "Router-URL", + "settings.router.keyEnv": "Router-Schlüssel Umgebungsvariable", + "settings.router.timeout": "Timeout (ms)", + "settings.router.verifyTls": "TLS-Zertifikat prüfen", + "settings.router.taxonomy": "Taxonomie-ID", + "settings.route": "Routing-Eingabe", + "settings.route.strategy": "Textstrategie", + "settings.route.maxChars": "Max. Zeichen", + "settings.route.cacheTtl": "Cache-TTL", + "settings.route.profile": "Standardprofil", + "settings.breaker": "Circuit Breaker", + "settings.breaker.threshold": "Fehlerschwelle", + "settings.breaker.cooldown": "Cooldown", + "settings.log": "Protokollierung", + "settings.log.level": "Log-Ebene", + "settings.log.bodies": "Nachrichtentexte protokollieren (Datenschutz aus)", + "settings.telemetry": "Telemetrie", + "settings.telemetry.metrics": "Prometheus /metrics bereitstellen", + "settings.cortiq": "Antwort-Metadaten", + "settings.cortiq.echo": "cortiq-Routing-Block in Antworten einbetten", + "settings.stats": "Statistiken", + "settings.stats.enabled": "Anfrage-Statistiken aufzeichnen", + "settings.stats.file": "Statistikdatei (JSONL)", + "settings.stats.retention": "Aufbewahrung", + "settings.listen": "Lausch-Adresse", + "settings.export": "Konfiguration exportieren", + "settings.import": "Konfiguration importieren", + "settings.needsRestart": "Gespeichert. Einige Änderungen (Lausch-Adresse) erfordern einen Neustart.", + + // toasts / misc + "toast.saved": "Änderungen gespeichert", + "toast.deleted": "Gelöscht", + "toast.probing": "Prüfe…", + "toast.imported": "Konfiguration importiert", +}; diff --git a/web/js/i18n/en.js b/web/js/i18n/en.js new file mode 100644 index 0000000..eb2d6b7 --- /dev/null +++ b/web/js/i18n/en.js @@ -0,0 +1,257 @@ +// English — source of truth. Other languages override per key; missing keys fall +// back to English. Keep keys identical across all language files. +export default { + // brand / common + "brand.sub": "Gateway", + "common.loading": "Loading…", + "common.save": "Save", + "common.saving": "Saving…", + "common.cancel": "Cancel", + "common.add": "Add", + "common.edit": "Edit", + "common.delete": "Delete", + "common.close": "Close", + "common.test": "Test", + "common.copy": "Copy", + "common.copied": "Copied", + "common.confirm": "Confirm", + "common.none": "none", + "common.saved": "Saved", + "common.error": "Error", + "common.ok": "OK", + "common.refresh": "Refresh", + "common.actions": "Actions", + "common.optional": "optional", + "common.search": "Search", + "common.all": "all", + + // nav + "nav.dashboard": "Dashboard", + "nav.models": "Models", + "nav.routing": "Routing", + "nav.protocols": "Protocols", + "nav.keys": "API keys", + "nav.playground": "Playground", + "nav.settings": "Settings", + "nav.foot": "Gateway · v{v}", + + // topbar / status + "status.router": "Router", + "status.gateway": "Gateway", + "status.online": "online", + "status.offline": "offline", + "status.checking": "checking…", + "theme.toggle": "Theme", + "logout": "Log out", + + // login + "login.title": "allaigate Gateway", + "login.subtitle": "Enter the admin token to manage this gateway.", + "login.token": "Admin token", + "login.tokenPlaceholder": "paste admin token", + "login.submit": "Open console", + "login.hint": "The token is printed in the gateway log on startup, or set via [admin].token_env.", + "login.failed": "Invalid admin token.", + + // dashboard + "dash.title": "Dashboard", + "dash.subtitle": "Live traffic, cost and routing analytics for your model pool.", + "dash.range": "Range", + "dash.range.1h": "1h", + "dash.range.24h": "24h", + "dash.range.7d": "7d", + "dash.kpi.requests": "Requests", + "dash.kpi.tokens": "Tokens", + "dash.kpi.cost": "Cost", + "dash.kpi.latency": "Avg latency", + "dash.kpi.success": "Success rate", + "dash.kpi.failovers": "Failovers", + "dash.series.title": "Requests over time", + "dash.series.cost": "Cost over time", + "dash.series.empty": "No traffic yet in this range.", + "dash.breakdown.title": "Breakdown", + "dash.groupby.model": "by model", + "dash.groupby.tier": "by tier", + "dash.groupby.label": "by task", + "dash.groupby.account": "by account", + "dash.recent.title": "Recent requests", + "dash.recent.empty": "No requests recorded yet. Try the Playground.", + "dash.col.time": "Time", + "dash.col.model": "Model", + "dash.col.tier": "Tier", + "dash.col.task": "Task", + "dash.col.tokens": "Tokens", + "dash.col.cost": "Cost", + "dash.col.latency": "Latency", + "dash.col.outcome": "Outcome", + "dash.col.requests": "Requests", + "dash.col.errors": "Errors", + "dash.health.title": "Health", + "dash.health.reachable": "reachable", + "dash.health.unreachable": "unreachable", + + // models + "models.title": "Models", + "models.subtitle": "Your model pool — mix cheap local models with cloud APIs.", + "models.add": "Add model", + "models.empty": "No models yet. Add your first model to get started.", + "models.col.id": "ID", + "models.col.provider": "Provider", + "models.col.model": "Model", + "models.col.tier": "Cost tier", + "models.col.key": "Key", + "models.col.caps": "Capabilities", + "models.col.price": "Price (in/out)", + "models.probe": "Probe", + "models.probe.ok": "Reachable ({ms} ms)", + "models.probe.fail": "Failed: {err}", + "models.form.addTitle": "Add model", + "models.form.editTitle": "Edit model", + "models.form.id": "ID", + "models.form.idHint": "Unique id used in routing, e.g. local-qwen", + "models.form.provider": "Provider", + "models.form.baseUrl": "Base URL", + "models.form.model": "Model name", + "models.form.kind": "Kind", + "models.form.costTier": "Cost tier", + "models.form.priceIn": "Price in ($/1M)", + "models.form.priceOut": "Price out ($/1M)", + "models.form.apiKeyEnv": "API key env name", + "models.form.apiKeyEnvHint": "Name of the env var / stored secret holding this provider's key.", + "models.form.caps": "Capabilities", + "models.form.secret": "Secret value", + "models.form.secretStored": "stored", + "models.form.secretEnv": "from env", + "models.form.secretMissing": "not set", + "models.form.secretPlaceholder": "set or replace key (write-only)", + "models.deleteConfirm": "Delete model \"{id}\"?", + + // routing + "routing.title": "Routing", + "routing.subtitle": "Map complexity tiers to an ordered list of models (priority = fallback).", + "routing.default": "Default model", + "routing.defaultHint": "Used when the router is unreachable.", + "routing.tiers": "Tiers", + "routing.tierHint": "Drag chips to reorder; first is preferred, the rest are fallbacks.", + "routing.addModel": "+ add", + "routing.addTier": "Add tier", + "routing.tierName": "Tier name", + "routing.policy": "Policy", + "routing.policy.mode": "Mode", + "routing.policy.fixed": "Fixed table", + "routing.policy.costAware": "Cost-aware", + "routing.policy.maxCost": "Max cost per request ($)", + "routing.policy.minClass": "Minimum class per tier", + "routing.empty": "No models available — add models first.", + + // protocols + "protocols.title": "Protocols", + "protocols.subtitle": "Enable only the inbound API surfaces you need. Toggles apply live.", + "protocols.implemented": "implemented", + "protocols.planned": "planned", + "protocols.openai_chat": "OpenAI Chat Completions", + "protocols.openai_chat.d": "POST /v1/chat/completions — works with OpenAI SDK, LangChain, crewAI.", + "protocols.openai_completions": "OpenAI Completions (legacy)", + "protocols.openai_completions.d": "POST /v1/completions — legacy integrations.", + "protocols.openai_embeddings": "OpenAI Embeddings", + "protocols.openai_embeddings.d": "POST /v1/embeddings — RAG pipelines.", + "protocols.openai_models": "OpenAI Models", + "protocols.openai_models.d": "GET /v1/models — client auto-discovery.", + "protocols.anthropic_messages": "Anthropic Messages", + "protocols.anthropic_messages.d": "POST /v1/messages — Claude-native agents.", + "protocols.mcp": "MCP (Model Context Protocol)", + "protocols.mcp.d": "JSON-RPC / SSE — MCP-native orchestrators.", + "protocols.native_passthrough": "Native passthrough", + "protocols.native_passthrough.d": "POST /route — direct access to the routing decision.", + + // keys + "keys.title": "API keys", + "keys.subtitle": "Virtual gateway keys for your agents. Provider keys never leave the gateway.", + "keys.add": "New key", + "keys.empty": "No keys configured — the gateway is in open mode (no auth).", + "keys.openMode": "Open mode: any request is accepted (no key required).", + "keys.col.key": "Key", + "keys.col.account": "Account", + "keys.col.rate": "Rate / min", + "keys.col.models": "Allowed models", + "keys.form.title": "New API key", + "keys.form.account": "Account", + "keys.form.rate": "Rate limit / min", + "keys.form.allow": "Allowed models", + "keys.form.allowHint": "Leave empty to allow all models.", + "keys.form.custom": "Custom key (optional)", + "keys.form.customHint": "Leave empty to auto-generate sk-gw-…", + "keys.created": "Key created — copy it now, it won't be shown again:", + "keys.revoke": "Revoke", + "keys.revokeConfirm": "Revoke this key?", + "keys.allowAll": "all", + + // playground + "pg.title": "Playground", + "pg.subtitle": "Send a prompt through the live pipeline and inspect the routing decision.", + "pg.system": "System prompt", + "pg.systemPlaceholder": "optional system message", + "pg.prompt": "Prompt", + "pg.promptPlaceholder": "Ask something…", + "pg.mode": "Mode", + "pg.mode.auto": "Auto (route)", + "pg.mode.pinned": "Pinned model", + "pg.profile": "Profile", + "pg.model": "Model", + "pg.temp": "Temperature", + "pg.maxTokens": "Max tokens", + "pg.send": "Send", + "pg.sending": "Sending…", + "pg.answer": "Answer", + "pg.empty": "The answer and routing decision will appear here.", + "pg.decision": "Routing decision", + "pg.task": "Task", + "pg.tier": "Tier", + "pg.score": "Complexity", + "pg.selected": "Selected model", + "pg.source": "Route source", + "pg.cost": "Cost", + "pg.latency": "Latency", + "pg.tokens": "Tokens (in/out)", + "pg.failover": "Failover", + "pg.error": "Request failed", + + // settings + "settings.title": "Settings", + "settings.subtitle": "Gateway connection, routing input, reliability and observability.", + "settings.router": "Router connection", + "settings.router.url": "Router URL", + "settings.router.keyEnv": "Router key env name", + "settings.router.timeout": "Timeout (ms)", + "settings.router.verifyTls": "Verify TLS certificate", + "settings.router.taxonomy": "Taxonomy id", + "settings.route": "Routing input", + "settings.route.strategy": "Text strategy", + "settings.route.maxChars": "Max chars", + "settings.route.cacheTtl": "Cache TTL", + "settings.route.profile": "Default profile", + "settings.breaker": "Circuit breaker", + "settings.breaker.threshold": "Error threshold", + "settings.breaker.cooldown": "Cooldown", + "settings.log": "Logging", + "settings.log.level": "Log level", + "settings.log.bodies": "Log message bodies (privacy off)", + "settings.telemetry": "Telemetry", + "settings.telemetry.metrics": "Expose Prometheus /metrics", + "settings.cortiq": "Response metadata", + "settings.cortiq.echo": "Echo cortiq routing block in responses", + "settings.stats": "Statistics", + "settings.stats.enabled": "Record request statistics", + "settings.stats.file": "Stats file (JSONL)", + "settings.stats.retention": "Retention", + "settings.listen": "Listen address", + "settings.export": "Export config", + "settings.import": "Import config", + "settings.needsRestart": "Saved. Some changes (listen address) require a restart.", + + // toasts / misc + "toast.saved": "Changes saved", + "toast.deleted": "Deleted", + "toast.probing": "Probing…", + "toast.imported": "Config imported", +}; diff --git a/web/js/i18n/es.js b/web/js/i18n/es.js new file mode 100644 index 0000000..4b1a763 --- /dev/null +++ b/web/js/i18n/es.js @@ -0,0 +1,256 @@ +// Spanish — traducciones para la consola de administración de allaigate Gateway. +export default { + // brand / common + "brand.sub": "Gateway", + "common.loading": "Cargando…", + "common.save": "Guardar", + "common.saving": "Guardando…", + "common.cancel": "Cancelar", + "common.add": "Agregar", + "common.edit": "Editar", + "common.delete": "Eliminar", + "common.close": "Cerrar", + "common.test": "Probar", + "common.copy": "Copiar", + "common.copied": "Copiado", + "common.confirm": "Confirmar", + "common.none": "ninguno", + "common.saved": "Guardado", + "common.error": "Error", + "common.ok": "OK", + "common.refresh": "Actualizar", + "common.actions": "Acciones", + "common.optional": "opcional", + "common.search": "Buscar", + "common.all": "todos", + + // nav + "nav.dashboard": "Panel", + "nav.models": "Modelos", + "nav.routing": "Enrutamiento", + "nav.protocols": "Protocolos", + "nav.keys": "Claves API", + "nav.playground": "Playground", + "nav.settings": "Configuración", + "nav.foot": "Gateway · v{v}", + + // topbar / status + "status.router": "Router", + "status.gateway": "Gateway", + "status.online": "en línea", + "status.offline": "sin conexión", + "status.checking": "verificando…", + "theme.toggle": "Tema", + "logout": "Cerrar sesión", + + // login + "login.title": "allaigate Gateway", + "login.subtitle": "Ingresa el token de administrador para gestionar este gateway.", + "login.token": "Token de administrador", + "login.tokenPlaceholder": "pega el token de administrador", + "login.submit": "Abrir consola", + "login.hint": "El token se imprime en el log del gateway al iniciar, o se configura mediante [admin].token_env.", + "login.failed": "Token de administrador inválido.", + + // dashboard + "dash.title": "Panel", + "dash.subtitle": "Tráfico en vivo, costos y análisis de enrutamiento de tu pool de modelos.", + "dash.range": "Rango", + "dash.range.1h": "1h", + "dash.range.24h": "24h", + "dash.range.7d": "7d", + "dash.kpi.requests": "Solicitudes", + "dash.kpi.tokens": "Tokens", + "dash.kpi.cost": "Costo", + "dash.kpi.latency": "Latencia promedio", + "dash.kpi.success": "Tasa de éxito", + "dash.kpi.failovers": "Failovers", + "dash.series.title": "Solicitudes en el tiempo", + "dash.series.cost": "Costo en el tiempo", + "dash.series.empty": "Sin tráfico en este rango.", + "dash.breakdown.title": "Desglose", + "dash.groupby.model": "por modelo", + "dash.groupby.tier": "por nivel", + "dash.groupby.label": "por tarea", + "dash.groupby.account": "por cuenta", + "dash.recent.title": "Solicitudes recientes", + "dash.recent.empty": "Sin solicitudes registradas. Prueba el Playground.", + "dash.col.time": "Hora", + "dash.col.model": "Modelo", + "dash.col.tier": "Nivel", + "dash.col.task": "Tarea", + "dash.col.tokens": "Tokens", + "dash.col.cost": "Costo", + "dash.col.latency": "Latencia", + "dash.col.outcome": "Resultado", + "dash.col.requests": "Solicitudes", + "dash.col.errors": "Errores", + "dash.health.title": "Estado", + "dash.health.reachable": "accesible", + "dash.health.unreachable": "inaccesible", + + // models + "models.title": "Modelos", + "models.subtitle": "Tu pool de modelos — combina modelos locales económicos con APIs en la nube.", + "models.add": "Agregar modelo", + "models.empty": "Sin modelos aún. Agrega tu primer modelo para comenzar.", + "models.col.id": "ID", + "models.col.provider": "Proveedor", + "models.col.model": "Modelo", + "models.col.tier": "Nivel de costo", + "models.col.key": "Clave", + "models.col.caps": "Capacidades", + "models.col.price": "Precio (entrada/salida)", + "models.probe": "Sondear", + "models.probe.ok": "Accesible ({ms} ms)", + "models.probe.fail": "Error: {err}", + "models.form.addTitle": "Agregar modelo", + "models.form.editTitle": "Editar modelo", + "models.form.id": "ID", + "models.form.idHint": "ID único usado en enrutamiento, ej. local-qwen", + "models.form.provider": "Proveedor", + "models.form.baseUrl": "URL base", + "models.form.model": "Nombre del modelo", + "models.form.kind": "Tipo", + "models.form.costTier": "Nivel de costo", + "models.form.priceIn": "Precio entrada ($/1M)", + "models.form.priceOut": "Precio salida ($/1M)", + "models.form.apiKeyEnv": "Nombre de variable env para clave API", + "models.form.apiKeyEnvHint": "Nombre de la variable de entorno o secreto que contiene la clave del proveedor.", + "models.form.caps": "Capacidades", + "models.form.secret": "Valor secreto", + "models.form.secretStored": "almacenado", + "models.form.secretEnv": "desde env", + "models.form.secretMissing": "no configurado", + "models.form.secretPlaceholder": "establecer o reemplazar clave (solo escritura)", + "models.deleteConfirm": "¿Eliminar modelo \"{id}\"?", + + // routing + "routing.title": "Enrutamiento", + "routing.subtitle": "Asigna niveles de complejidad a una lista ordenada de modelos (prioridad = fallback).", + "routing.default": "Modelo predeterminado", + "routing.defaultHint": "Usado cuando el router no está disponible.", + "routing.tiers": "Niveles", + "routing.tierHint": "Arrastra los chips para reordenar; el primero es preferido, los demás son fallbacks.", + "routing.addModel": "+ agregar", + "routing.addTier": "Agregar nivel", + "routing.tierName": "Nombre del nivel", + "routing.policy": "Política", + "routing.policy.mode": "Modo", + "routing.policy.fixed": "Tabla fija", + "routing.policy.costAware": "Consciente del costo", + "routing.policy.maxCost": "Costo máx. por solicitud ($)", + "routing.policy.minClass": "Clase mínima por nivel", + "routing.empty": "Sin modelos disponibles — agrega modelos primero.", + + // protocols + "protocols.title": "Protocolos", + "protocols.subtitle": "Activa solo las APIs de entrada que necesitas. Los cambios se aplican en vivo.", + "protocols.implemented": "implementado", + "protocols.planned": "planificado", + "protocols.openai_chat": "OpenAI Chat Completions", + "protocols.openai_chat.d": "POST /v1/chat/completions — compatible con OpenAI SDK, LangChain, crewAI.", + "protocols.openai_completions": "OpenAI Completions (legacy)", + "protocols.openai_completions.d": "POST /v1/completions — integraciones heredadas.", + "protocols.openai_embeddings": "OpenAI Embeddings", + "protocols.openai_embeddings.d": "POST /v1/embeddings — pipelines RAG.", + "protocols.openai_models": "OpenAI Models", + "protocols.openai_models.d": "GET /v1/models — autodescubrimiento de clientes.", + "protocols.anthropic_messages": "Anthropic Messages", + "protocols.anthropic_messages.d": "POST /v1/messages — agentes nativos Claude.", + "protocols.mcp": "MCP (Model Context Protocol)", + "protocols.mcp.d": "JSON-RPC / SSE — orquestadores nativos MCP.", + "protocols.native_passthrough": "Passthrough nativo", + "protocols.native_passthrough.d": "POST /route — acceso directo a la decisión de enrutamiento.", + + // keys + "keys.title": "Claves API", + "keys.subtitle": "Claves de gateway virtuales para tus agentes. Las claves del proveedor nunca salen del gateway.", + "keys.add": "Nueva clave", + "keys.empty": "Sin claves configuradas — el gateway está en modo abierto (sin autenticación).", + "keys.openMode": "Modo abierto: cualquier solicitud es aceptada (no se requiere clave).", + "keys.col.key": "Clave", + "keys.col.account": "Cuenta", + "keys.col.rate": "Límite / min", + "keys.col.models": "Modelos permitidos", + "keys.form.title": "Nueva clave API", + "keys.form.account": "Cuenta", + "keys.form.rate": "Límite de tasa / min", + "keys.form.allow": "Modelos permitidos", + "keys.form.allowHint": "Deja vacío para permitir todos los modelos.", + "keys.form.custom": "Clave personalizada (opcional)", + "keys.form.customHint": "Deja vacío para generar automáticamente sk-gw-…", + "keys.created": "Clave creada — cópiala ahora, no se mostrará de nuevo:", + "keys.revoke": "Revocar", + "keys.revokeConfirm": "¿Revocar esta clave?", + "keys.allowAll": "todos", + + // playground + "pg.title": "Playground", + "pg.subtitle": "Envía un prompt por el pipeline en vivo e inspecciona la decisión de enrutamiento.", + "pg.system": "Prompt del sistema", + "pg.systemPlaceholder": "mensaje de sistema opcional", + "pg.prompt": "Prompt", + "pg.promptPlaceholder": "Escribe algo…", + "pg.mode": "Modo", + "pg.mode.auto": "Auto (enrutar)", + "pg.mode.pinned": "Modelo fijo", + "pg.profile": "Perfil", + "pg.model": "Modelo", + "pg.temp": "Temperatura", + "pg.maxTokens": "Tokens máx.", + "pg.send": "Enviar", + "pg.sending": "Enviando…", + "pg.answer": "Respuesta", + "pg.empty": "La respuesta y la decisión de enrutamiento aparecerán aquí.", + "pg.decision": "Decisión de enrutamiento", + "pg.task": "Tarea", + "pg.tier": "Nivel", + "pg.score": "Complejidad", + "pg.selected": "Modelo seleccionado", + "pg.source": "Fuente de ruta", + "pg.cost": "Costo", + "pg.latency": "Latencia", + "pg.tokens": "Tokens (entrada/salida)", + "pg.failover": "Failover", + "pg.error": "Solicitud fallida", + + // settings + "settings.title": "Configuración", + "settings.subtitle": "Conexión del gateway, entrada de enrutamiento, fiabilidad y observabilidad.", + "settings.router": "Conexión del router", + "settings.router.url": "URL del router", + "settings.router.keyEnv": "Nombre de variable env para clave del router", + "settings.router.timeout": "Tiempo de espera (ms)", + "settings.router.verifyTls": "Verificar certificado TLS", + "settings.router.taxonomy": "ID de taxonomía", + "settings.route": "Entrada de enrutamiento", + "settings.route.strategy": "Estrategia de texto", + "settings.route.maxChars": "Máx. caracteres", + "settings.route.cacheTtl": "TTL de caché", + "settings.route.profile": "Perfil predeterminado", + "settings.breaker": "Circuit breaker", + "settings.breaker.threshold": "Umbral de errores", + "settings.breaker.cooldown": "Cooldown", + "settings.log": "Registro", + "settings.log.level": "Nivel de log", + "settings.log.bodies": "Registrar cuerpos de mensajes (privacidad desactivada)", + "settings.telemetry": "Telemetría", + "settings.telemetry.metrics": "Exponer Prometheus /metrics", + "settings.cortiq": "Metadatos de respuesta", + "settings.cortiq.echo": "Incluir bloque de enrutamiento cortiq en respuestas", + "settings.stats": "Estadísticas", + "settings.stats.enabled": "Registrar estadísticas de solicitudes", + "settings.stats.file": "Archivo de estadísticas (JSONL)", + "settings.stats.retention": "Retención", + "settings.listen": "Dirección de escucha", + "settings.export": "Exportar configuración", + "settings.import": "Importar configuración", + "settings.needsRestart": "Guardado. Algunos cambios (dirección de escucha) requieren reinicio.", + + // toasts / misc + "toast.saved": "Cambios guardados", + "toast.deleted": "Eliminado", + "toast.probing": "Sondeando…", + "toast.imported": "Configuración importada", +}; diff --git a/web/js/i18n/fr.js b/web/js/i18n/fr.js new file mode 100644 index 0000000..e03b704 --- /dev/null +++ b/web/js/i18n/fr.js @@ -0,0 +1,256 @@ +// French (fr) — same keys as en.js; missing keys fall back to English. +export default { + // brand / common + "brand.sub": "Gateway", + "common.loading": "Chargement…", + "common.save": "Enregistrer", + "common.saving": "Enregistrement…", + "common.cancel": "Annuler", + "common.add": "Ajouter", + "common.edit": "Modifier", + "common.delete": "Supprimer", + "common.close": "Fermer", + "common.test": "Tester", + "common.copy": "Copier", + "common.copied": "Copié", + "common.confirm": "Confirmer", + "common.none": "aucun", + "common.saved": "Enregistré", + "common.error": "Erreur", + "common.ok": "OK", + "common.refresh": "Actualiser", + "common.actions": "Actions", + "common.optional": "optionnel", + "common.search": "Rechercher", + "common.all": "tous", + + // nav + "nav.dashboard": "Tableau de bord", + "nav.models": "Modèles", + "nav.routing": "Routage", + "nav.protocols": "Protocoles", + "nav.keys": "Clés API", + "nav.playground": "Playground", + "nav.settings": "Paramètres", + "nav.foot": "Gateway · v{v}", + + // topbar / status + "status.router": "Routeur", + "status.gateway": "Gateway", + "status.online": "en ligne", + "status.offline": "hors ligne", + "status.checking": "vérification…", + "theme.toggle": "Thème", + "logout": "Déconnexion", + + // login + "login.title": "allaigate Gateway", + "login.subtitle": "Saisissez le jeton administrateur pour gérer cette passerelle.", + "login.token": "Jeton admin", + "login.tokenPlaceholder": "coller le jeton admin", + "login.submit": "Ouvrir la console", + "login.hint": "Le jeton est affiché dans le log de la passerelle au démarrage, ou défini via [admin].token_env.", + "login.failed": "Jeton admin invalide.", + + // dashboard + "dash.title": "Tableau de bord", + "dash.subtitle": "Trafic en direct, coûts et analyses de routage pour votre pool de modèles.", + "dash.range": "Période", + "dash.range.1h": "1h", + "dash.range.24h": "24h", + "dash.range.7d": "7j", + "dash.kpi.requests": "Requêtes", + "dash.kpi.tokens": "Tokens", + "dash.kpi.cost": "Coût", + "dash.kpi.latency": "Latence moy.", + "dash.kpi.success": "Taux de succès", + "dash.kpi.failovers": "Basculements", + "dash.series.title": "Requêtes dans le temps", + "dash.series.cost": "Coûts dans le temps", + "dash.series.empty": "Aucun trafic sur cette période.", + "dash.breakdown.title": "Répartition", + "dash.groupby.model": "par modèle", + "dash.groupby.tier": "par niveau", + "dash.groupby.label": "par tâche", + "dash.groupby.account": "par compte", + "dash.recent.title": "Requêtes récentes", + "dash.recent.empty": "Aucune requête enregistrée. Essayez le Playground.", + "dash.col.time": "Heure", + "dash.col.model": "Modèle", + "dash.col.tier": "Niveau", + "dash.col.task": "Tâche", + "dash.col.tokens": "Tokens", + "dash.col.cost": "Coût", + "dash.col.latency": "Latence", + "dash.col.outcome": "Résultat", + "dash.col.requests": "Requêtes", + "dash.col.errors": "Erreurs", + "dash.health.title": "Santé", + "dash.health.reachable": "accessible", + "dash.health.unreachable": "inaccessible", + + // models + "models.title": "Modèles", + "models.subtitle": "Votre pool de modèles — combinez modèles locaux économiques et API cloud.", + "models.add": "Ajouter un modèle", + "models.empty": "Aucun modèle. Ajoutez votre premier modèle pour commencer.", + "models.col.id": "ID", + "models.col.provider": "Fournisseur", + "models.col.model": "Modèle", + "models.col.tier": "Niveau de coût", + "models.col.key": "Clé", + "models.col.caps": "Capacités", + "models.col.price": "Prix (entrée/sortie)", + "models.probe": "Sonder", + "models.probe.ok": "Accessible ({ms} ms)", + "models.probe.fail": "Échec : {err}", + "models.form.addTitle": "Ajouter un modèle", + "models.form.editTitle": "Modifier le modèle", + "models.form.id": "ID", + "models.form.idHint": "Identifiant unique utilisé dans le routage, ex. local-qwen", + "models.form.provider": "Fournisseur", + "models.form.baseUrl": "URL de base", + "models.form.model": "Nom du modèle", + "models.form.kind": "Type", + "models.form.costTier": "Niveau de coût", + "models.form.priceIn": "Prix entrée ($/1M)", + "models.form.priceOut": "Prix sortie ($/1M)", + "models.form.apiKeyEnv": "Nom de la var. d'env. pour la clé", + "models.form.apiKeyEnvHint": "Nom de la variable d'env. ou du secret contenant la clé de ce fournisseur.", + "models.form.caps": "Capacités", + "models.form.secret": "Valeur secrète", + "models.form.secretStored": "stocké", + "models.form.secretEnv": "depuis l'env.", + "models.form.secretMissing": "non défini", + "models.form.secretPlaceholder": "définir ou remplacer la clé (écriture seule)", + "models.deleteConfirm": "Supprimer le modèle \"{id}\" ?", + + // routing + "routing.title": "Routage", + "routing.subtitle": "Associez les niveaux de complexité à une liste ordonnée de modèles (priorité = repli).", + "routing.default": "Modèle par défaut", + "routing.defaultHint": "Utilisé lorsque le routeur est inaccessible.", + "routing.tiers": "Niveaux", + "routing.tierHint": "Glissez les puces pour réordonner ; le premier est préféré, les autres sont des replis.", + "routing.addModel": "+ ajouter", + "routing.addTier": "Ajouter un niveau", + "routing.tierName": "Nom du niveau", + "routing.policy": "Politique", + "routing.policy.mode": "Mode", + "routing.policy.fixed": "Table fixe", + "routing.policy.costAware": "Sensible au coût", + "routing.policy.maxCost": "Coût max par requête ($)", + "routing.policy.minClass": "Classe minimale par niveau", + "routing.empty": "Aucun modèle disponible — ajoutez des modèles d'abord.", + + // protocols + "protocols.title": "Protocoles", + "protocols.subtitle": "Activez uniquement les surfaces API entrantes nécessaires. Les bascules s'appliquent en direct.", + "protocols.implemented": "implémenté", + "protocols.planned": "planifié", + "protocols.openai_chat": "OpenAI Chat Completions", + "protocols.openai_chat.d": "POST /v1/chat/completions — compatible avec OpenAI SDK, LangChain, crewAI.", + "protocols.openai_completions": "OpenAI Completions (héritage)", + "protocols.openai_completions.d": "POST /v1/completions — intégrations héritées.", + "protocols.openai_embeddings": "OpenAI Embeddings", + "protocols.openai_embeddings.d": "POST /v1/embeddings — pipelines RAG.", + "protocols.openai_models": "OpenAI Models", + "protocols.openai_models.d": "GET /v1/models — découverte automatique des clients.", + "protocols.anthropic_messages": "Anthropic Messages", + "protocols.anthropic_messages.d": "POST /v1/messages — agents natifs Claude.", + "protocols.mcp": "MCP (Model Context Protocol)", + "protocols.mcp.d": "JSON-RPC / SSE — orchestrateurs natifs MCP.", + "protocols.native_passthrough": "Passage natif", + "protocols.native_passthrough.d": "POST /route — accès direct à la décision de routage.", + + // keys + "keys.title": "Clés API", + "keys.subtitle": "Clés de passerelle virtuelles pour vos agents. Les clés fournisseurs ne quittent jamais la passerelle.", + "keys.add": "Nouvelle clé", + "keys.empty": "Aucune clé configurée — la passerelle est en mode ouvert (sans auth).", + "keys.openMode": "Mode ouvert : toute requête est acceptée (aucune clé requise).", + "keys.col.key": "Clé", + "keys.col.account": "Compte", + "keys.col.rate": "Débit / min", + "keys.col.models": "Modèles autorisés", + "keys.form.title": "Nouvelle clé API", + "keys.form.account": "Compte", + "keys.form.rate": "Limite de débit / min", + "keys.form.allow": "Modèles autorisés", + "keys.form.allowHint": "Laisser vide pour autoriser tous les modèles.", + "keys.form.custom": "Clé personnalisée (optionnel)", + "keys.form.customHint": "Laisser vide pour générer automatiquement sk-gw-…", + "keys.created": "Clé créée — copiez-la maintenant, elle ne sera plus affichée :", + "keys.revoke": "Révoquer", + "keys.revokeConfirm": "Révoquer cette clé ?", + "keys.allowAll": "tous", + + // playground + "pg.title": "Playground", + "pg.subtitle": "Envoyez une invite via le pipeline en direct et inspectez la décision de routage.", + "pg.system": "Invite système", + "pg.systemPlaceholder": "message système optionnel", + "pg.prompt": "Invite", + "pg.promptPlaceholder": "Posez une question…", + "pg.mode": "Mode", + "pg.mode.auto": "Auto (routage)", + "pg.mode.pinned": "Modèle épinglé", + "pg.profile": "Profil", + "pg.model": "Modèle", + "pg.temp": "Température", + "pg.maxTokens": "Tokens max", + "pg.send": "Envoyer", + "pg.sending": "Envoi…", + "pg.answer": "Réponse", + "pg.empty": "La réponse et la décision de routage s'afficheront ici.", + "pg.decision": "Décision de routage", + "pg.task": "Tâche", + "pg.tier": "Niveau", + "pg.score": "Complexité", + "pg.selected": "Modèle sélectionné", + "pg.source": "Source du routage", + "pg.cost": "Coût", + "pg.latency": "Latence", + "pg.tokens": "Tokens (entrée/sortie)", + "pg.failover": "Basculement", + "pg.error": "Requête échouée", + + // settings + "settings.title": "Paramètres", + "settings.subtitle": "Connexion passerelle, entrée de routage, fiabilité et observabilité.", + "settings.router": "Connexion routeur", + "settings.router.url": "URL du routeur", + "settings.router.keyEnv": "Nom de l'env. pour la clé du routeur", + "settings.router.timeout": "Délai d'expiration (ms)", + "settings.router.verifyTls": "Vérifier le certificat TLS", + "settings.router.taxonomy": "ID de taxonomie", + "settings.route": "Entrée de routage", + "settings.route.strategy": "Stratégie de texte", + "settings.route.maxChars": "Caractères max", + "settings.route.cacheTtl": "TTL du cache", + "settings.route.profile": "Profil par défaut", + "settings.breaker": "Disjoncteur", + "settings.breaker.threshold": "Seuil d'erreur", + "settings.breaker.cooldown": "Temporisation", + "settings.log": "Journalisation", + "settings.log.level": "Niveau de log", + "settings.log.bodies": "Journaliser les corps de messages (confidentialité désactivée)", + "settings.telemetry": "Télémétrie", + "settings.telemetry.metrics": "Exposer Prometheus /metrics", + "settings.cortiq": "Métadonnées de réponse", + "settings.cortiq.echo": "Inclure le bloc de routage cortiq dans les réponses", + "settings.stats": "Statistiques", + "settings.stats.enabled": "Enregistrer les statistiques de requêtes", + "settings.stats.file": "Fichier de stats (JSONL)", + "settings.stats.retention": "Rétention", + "settings.listen": "Adresse d'écoute", + "settings.export": "Exporter la config", + "settings.import": "Importer la config", + "settings.needsRestart": "Enregistré. Certains changements (adresse d'écoute) nécessitent un redémarrage.", + + // toasts / misc + "toast.saved": "Modifications enregistrées", + "toast.deleted": "Supprimé", + "toast.probing": "Sondage…", + "toast.imported": "Config importée", +}; diff --git a/web/js/i18n/ru.js b/web/js/i18n/ru.js new file mode 100644 index 0000000..7467bcb --- /dev/null +++ b/web/js/i18n/ru.js @@ -0,0 +1,256 @@ +// Russian — ru. Keys must match en.js exactly; missing keys fall back to English. +export default { + // brand / common + "brand.sub": "Шлюз", + "common.loading": "Загрузка…", + "common.save": "Сохранить", + "common.saving": "Сохранение…", + "common.cancel": "Отмена", + "common.add": "Добавить", + "common.edit": "Изменить", + "common.delete": "Удалить", + "common.close": "Закрыть", + "common.test": "Тест", + "common.copy": "Копировать", + "common.copied": "Скопировано", + "common.confirm": "Подтвердить", + "common.none": "нет", + "common.saved": "Сохранено", + "common.error": "Ошибка", + "common.ok": "OK", + "common.refresh": "Обновить", + "common.actions": "Действия", + "common.optional": "необязательно", + "common.search": "Поиск", + "common.all": "все", + + // nav + "nav.dashboard": "Дашборд", + "nav.models": "Модели", + "nav.routing": "Роутинг", + "nav.protocols": "Протоколы", + "nav.keys": "API-ключи", + "nav.playground": "Playground", + "nav.settings": "Настройки", + "nav.foot": "Шлюз · v{v}", + + // topbar / status + "status.router": "Роутер", + "status.gateway": "Шлюз", + "status.online": "в сети", + "status.offline": "недоступен", + "status.checking": "проверка…", + "theme.toggle": "Тема", + "logout": "Выйти", + + // login + "login.title": "allaigate Gateway", + "login.subtitle": "Введите токен администратора для управления этим шлюзом.", + "login.token": "Токен администратора", + "login.tokenPlaceholder": "вставьте токен", + "login.submit": "Войти в консоль", + "login.hint": "Токен печатается в логе шлюза при запуске или задаётся через [admin].token_env.", + "login.failed": "Неверный токен администратора.", + + // dashboard + "dash.title": "Дашборд", + "dash.subtitle": "Трафик в реальном времени, расходы и аналитика роутинга по пулу моделей.", + "dash.range": "Период", + "dash.range.1h": "1ч", + "dash.range.24h": "24ч", + "dash.range.7d": "7д", + "dash.kpi.requests": "Запросы", + "dash.kpi.tokens": "Токены", + "dash.kpi.cost": "Стоимость", + "dash.kpi.latency": "Ср. задержка", + "dash.kpi.success": "Успешность", + "dash.kpi.failovers": "Переключения", + "dash.series.title": "Запросы по времени", + "dash.series.cost": "Расходы по времени", + "dash.series.empty": "Трафика за этот период нет.", + "dash.breakdown.title": "Разбивка", + "dash.groupby.model": "по модели", + "dash.groupby.tier": "по уровню", + "dash.groupby.label": "по задаче", + "dash.groupby.account": "по аккаунту", + "dash.recent.title": "Последние запросы", + "dash.recent.empty": "Запросов ещё нет. Попробуйте Playground.", + "dash.col.time": "Время", + "dash.col.model": "Модель", + "dash.col.tier": "Уровень", + "dash.col.task": "Задача", + "dash.col.tokens": "Токены", + "dash.col.cost": "Стоимость", + "dash.col.latency": "Задержка", + "dash.col.outcome": "Результат", + "dash.col.requests": "Запросы", + "dash.col.errors": "Ошибки", + "dash.health.title": "Состояние", + "dash.health.reachable": "доступен", + "dash.health.unreachable": "недоступен", + + // models + "models.title": "Модели", + "models.subtitle": "Пул моделей — сочетайте дешёвые локальные модели с облачными API.", + "models.add": "Добавить модель", + "models.empty": "Моделей нет. Добавьте первую модель.", + "models.col.id": "ID", + "models.col.provider": "Провайдер", + "models.col.model": "Модель", + "models.col.tier": "Уровень цены", + "models.col.key": "Ключ", + "models.col.caps": "Возможности", + "models.col.price": "Цена (вх/исх)", + "models.probe": "Проверить", + "models.probe.ok": "Доступна ({ms} мс)", + "models.probe.fail": "Ошибка: {err}", + "models.form.addTitle": "Добавить модель", + "models.form.editTitle": "Редактировать модель", + "models.form.id": "ID", + "models.form.idHint": "Уникальный ID для роутинга, например local-qwen", + "models.form.provider": "Провайдер", + "models.form.baseUrl": "Base URL", + "models.form.model": "Имя модели", + "models.form.kind": "Тип", + "models.form.costTier": "Уровень цены", + "models.form.priceIn": "Цена вх. ($/1M)", + "models.form.priceOut": "Цена исх. ($/1M)", + "models.form.apiKeyEnv": "Имя env-переменной с ключом", + "models.form.apiKeyEnvHint": "Имя переменной окружения или секрета с ключом провайдера.", + "models.form.caps": "Возможности", + "models.form.secret": "Значение секрета", + "models.form.secretStored": "сохранён", + "models.form.secretEnv": "из env", + "models.form.secretMissing": "не задан", + "models.form.secretPlaceholder": "задать или заменить ключ (только запись)", + "models.deleteConfirm": "Удалить модель \"{id}\"?", + + // routing + "routing.title": "Роутинг", + "routing.subtitle": "Сопоставьте уровни сложности с упорядоченным списком моделей (приоритет = fallback).", + "routing.default": "Модель по умолчанию", + "routing.defaultHint": "Используется, если роутер недоступен.", + "routing.tiers": "Уровни", + "routing.tierHint": "Перетащите чипы для изменения порядка; первый — предпочтительный, остальные — резервные.", + "routing.addModel": "+ добавить", + "routing.addTier": "Добавить уровень", + "routing.tierName": "Название уровня", + "routing.policy": "Политика", + "routing.policy.mode": "Режим", + "routing.policy.fixed": "Фиксированная таблица", + "routing.policy.costAware": "С учётом стоимости", + "routing.policy.maxCost": "Макс. стоимость запроса ($)", + "routing.policy.minClass": "Мин. класс на уровень", + "routing.empty": "Моделей нет — сначала добавьте модели.", + + // protocols + "protocols.title": "Протоколы", + "protocols.subtitle": "Включайте только нужные входящие API. Переключатели применяются мгновенно.", + "protocols.implemented": "реализован", + "protocols.planned": "планируется", + "protocols.openai_chat": "OpenAI Chat Completions", + "protocols.openai_chat.d": "POST /v1/chat/completions — работает с OpenAI SDK, LangChain, crewAI.", + "protocols.openai_completions": "OpenAI Completions (устаревший)", + "protocols.openai_completions.d": "POST /v1/completions — устаревшие интеграции.", + "protocols.openai_embeddings": "OpenAI Embeddings", + "protocols.openai_embeddings.d": "POST /v1/embeddings — RAG-пайплайны.", + "protocols.openai_models": "OpenAI Models", + "protocols.openai_models.d": "GET /v1/models — автообнаружение клиентами.", + "protocols.anthropic_messages": "Anthropic Messages", + "protocols.anthropic_messages.d": "POST /v1/messages — Claude-нативные агенты.", + "protocols.mcp": "MCP (Model Context Protocol)", + "protocols.mcp.d": "JSON-RPC / SSE — MCP-нативные оркестраторы.", + "protocols.native_passthrough": "Нативный проброс", + "protocols.native_passthrough.d": "POST /route — прямой доступ к решению роутера.", + + // keys + "keys.title": "API-ключи", + "keys.subtitle": "Виртуальные ключи шлюза для агентов. Ключи провайдеров не покидают шлюз.", + "keys.add": "Новый ключ", + "keys.empty": "Ключей нет — шлюз в открытом режиме (без аутентификации).", + "keys.openMode": "Открытый режим: любой запрос принимается (ключ не нужен).", + "keys.col.key": "Ключ", + "keys.col.account": "Аккаунт", + "keys.col.rate": "Лимит / мин", + "keys.col.models": "Разрешённые модели", + "keys.form.title": "Новый API-ключ", + "keys.form.account": "Аккаунт", + "keys.form.rate": "Лимит запросов / мин", + "keys.form.allow": "Разрешённые модели", + "keys.form.allowHint": "Оставьте пустым, чтобы разрешить все модели.", + "keys.form.custom": "Произвольный ключ (необязательно)", + "keys.form.customHint": "Оставьте пустым для автогенерации sk-gw-…", + "keys.created": "Ключ создан — скопируйте его сейчас, он больше не отобразится:", + "keys.revoke": "Отозвать", + "keys.revokeConfirm": "Отозвать этот ключ?", + "keys.allowAll": "все", + + // playground + "pg.title": "Playground", + "pg.subtitle": "Отправьте запрос через активный пайплайн и изучите решение роутера.", + "pg.system": "Системный промпт", + "pg.systemPlaceholder": "необязательное системное сообщение", + "pg.prompt": "Промпт", + "pg.promptPlaceholder": "Задайте вопрос…", + "pg.mode": "Режим", + "pg.mode.auto": "Авто (роутинг)", + "pg.mode.pinned": "Фиксированная модель", + "pg.profile": "Профиль", + "pg.model": "Модель", + "pg.temp": "Температура", + "pg.maxTokens": "Макс. токены", + "pg.send": "Отправить", + "pg.sending": "Отправка…", + "pg.answer": "Ответ", + "pg.empty": "Ответ и решение роутера появятся здесь.", + "pg.decision": "Решение роутера", + "pg.task": "Задача", + "pg.tier": "Уровень", + "pg.score": "Сложность", + "pg.selected": "Выбранная модель", + "pg.source": "Источник маршрута", + "pg.cost": "Стоимость", + "pg.latency": "Задержка", + "pg.tokens": "Токены (вх/исх)", + "pg.failover": "Failover", + "pg.error": "Ошибка запроса", + + // settings + "settings.title": "Настройки", + "settings.subtitle": "Подключение к шлюзу, входные данные роутинга, надёжность и наблюдаемость.", + "settings.router": "Подключение к роутеру", + "settings.router.url": "URL роутера", + "settings.router.keyEnv": "Имя env-переменной с ключом роутера", + "settings.router.timeout": "Таймаут (мс)", + "settings.router.verifyTls": "Проверять TLS-сертификат", + "settings.router.taxonomy": "ID таксономии", + "settings.route": "Входные данные роутинга", + "settings.route.strategy": "Стратегия текста", + "settings.route.maxChars": "Макс. символов", + "settings.route.cacheTtl": "TTL кэша", + "settings.route.profile": "Профиль по умолчанию", + "settings.breaker": "Автоматический выключатель", + "settings.breaker.threshold": "Порог ошибок", + "settings.breaker.cooldown": "Время восстановления", + "settings.log": "Логирование", + "settings.log.level": "Уровень логов", + "settings.log.bodies": "Логировать тела сообщений (приватность отключена)", + "settings.telemetry": "Телеметрия", + "settings.telemetry.metrics": "Включить Prometheus /metrics", + "settings.cortiq": "Метаданные ответа", + "settings.cortiq.echo": "Включать блок роутинга cortiq в ответы", + "settings.stats": "Статистика", + "settings.stats.enabled": "Записывать статистику запросов", + "settings.stats.file": "Файл статистики (JSONL)", + "settings.stats.retention": "Срок хранения", + "settings.listen": "Адрес прослушивания", + "settings.export": "Экспорт конфигурации", + "settings.import": "Импорт конфигурации", + "settings.needsRestart": "Сохранено. Некоторые изменения (адрес прослушивания) требуют перезапуска.", + + // toasts / misc + "toast.saved": "Изменения сохранены", + "toast.deleted": "Удалено", + "toast.probing": "Проверка…", + "toast.imported": "Конфигурация импортирована", +}; diff --git a/web/js/i18n/tr.js b/web/js/i18n/tr.js new file mode 100644 index 0000000..a07c17e --- /dev/null +++ b/web/js/i18n/tr.js @@ -0,0 +1,256 @@ +// Turkish — tam çeviri; eksik anahtarlar İngilizce'ye geri döner. +export default { + // brand / common + "brand.sub": "Gateway", + "common.loading": "Yükleniyor…", + "common.save": "Kaydet", + "common.saving": "Kaydediliyor…", + "common.cancel": "İptal", + "common.add": "Ekle", + "common.edit": "Düzenle", + "common.delete": "Sil", + "common.close": "Kapat", + "common.test": "Test", + "common.copy": "Kopyala", + "common.copied": "Kopyalandı", + "common.confirm": "Onayla", + "common.none": "yok", + "common.saved": "Kaydedildi", + "common.error": "Hata", + "common.ok": "Tamam", + "common.refresh": "Yenile", + "common.actions": "İşlemler", + "common.optional": "isteğe bağlı", + "common.search": "Ara", + "common.all": "tümü", + + // nav + "nav.dashboard": "Pano", + "nav.models": "Modeller", + "nav.routing": "Yönlendirme", + "nav.protocols": "Protokoller", + "nav.keys": "API anahtarları", + "nav.playground": "Oyun alanı", + "nav.settings": "Ayarlar", + "nav.foot": "Gateway · v{v}", + + // topbar / status + "status.router": "Yönlendirici", + "status.gateway": "Gateway", + "status.online": "çevrimiçi", + "status.offline": "çevrimdışı", + "status.checking": "kontrol ediliyor…", + "theme.toggle": "Tema", + "logout": "Çıkış yap", + + // login + "login.title": "allaigate Gateway", + "login.subtitle": "Bu gateway'i yönetmek için yönetici token'ını girin.", + "login.token": "Yönetici token'ı", + "login.tokenPlaceholder": "yönetici token'ını yapıştırın", + "login.submit": "Konsolu aç", + "login.hint": "Token, başlangıçta gateway günlüğüne yazdırılır veya [admin].token_env ile ayarlanır.", + "login.failed": "Geçersiz yönetici token'ı.", + + // dashboard + "dash.title": "Pano", + "dash.subtitle": "Model havuzunuz için canlı trafik, maliyet ve yönlendirme analitiği.", + "dash.range": "Aralık", + "dash.range.1h": "1s", + "dash.range.24h": "24s", + "dash.range.7d": "7g", + "dash.kpi.requests": "İstekler", + "dash.kpi.tokens": "Token'lar", + "dash.kpi.cost": "Maliyet", + "dash.kpi.latency": "Ort. gecikme", + "dash.kpi.success": "Başarı oranı", + "dash.kpi.failovers": "Yedeklemeler", + "dash.series.title": "Zamana göre istekler", + "dash.series.cost": "Zamana göre maliyet", + "dash.series.empty": "Bu aralıkta henüz trafik yok.", + "dash.breakdown.title": "Dağılım", + "dash.groupby.model": "modele göre", + "dash.groupby.tier": "kademeye göre", + "dash.groupby.label": "göreve göre", + "dash.groupby.account": "hesaba göre", + "dash.recent.title": "Son istekler", + "dash.recent.empty": "Henüz kayıtlı istek yok. Oyun alanını deneyin.", + "dash.col.time": "Zaman", + "dash.col.model": "Model", + "dash.col.tier": "Kademe", + "dash.col.task": "Görev", + "dash.col.tokens": "Token'lar", + "dash.col.cost": "Maliyet", + "dash.col.latency": "Gecikme", + "dash.col.outcome": "Sonuç", + "dash.col.requests": "İstekler", + "dash.col.errors": "Hatalar", + "dash.health.title": "Sağlık", + "dash.health.reachable": "erişilebilir", + "dash.health.unreachable": "erişilemiyor", + + // models + "models.title": "Modeller", + "models.subtitle": "Model havuzunuz — ucuz yerel modelleri bulut API'leriyle karıştırın.", + "models.add": "Model ekle", + "models.empty": "Henüz model yok. Başlamak için ilk modelinizi ekleyin.", + "models.col.id": "ID", + "models.col.provider": "Sağlayıcı", + "models.col.model": "Model", + "models.col.tier": "Maliyet kademesi", + "models.col.key": "Anahtar", + "models.col.caps": "Yetenekler", + "models.col.price": "Fiyat (giriş/çıkış)", + "models.probe": "Sına", + "models.probe.ok": "Erişilebilir ({ms} ms)", + "models.probe.fail": "Başarısız: {err}", + "models.form.addTitle": "Model ekle", + "models.form.editTitle": "Modeli düzenle", + "models.form.id": "ID", + "models.form.idHint": "Yönlendirmede kullanılan benzersiz id, örn. local-qwen", + "models.form.provider": "Sağlayıcı", + "models.form.baseUrl": "Temel URL", + "models.form.model": "Model adı", + "models.form.kind": "Tür", + "models.form.costTier": "Maliyet kademesi", + "models.form.priceIn": "Giriş fiyatı ($/1M)", + "models.form.priceOut": "Çıkış fiyatı ($/1M)", + "models.form.apiKeyEnv": "API anahtarı ortam değişkeni adı", + "models.form.apiKeyEnvHint": "Bu sağlayıcının anahtarını tutan ortam değişkeni / saklı gizli adı.", + "models.form.caps": "Yetenekler", + "models.form.secret": "Gizli değer", + "models.form.secretStored": "saklandı", + "models.form.secretEnv": "ortamdan", + "models.form.secretMissing": "ayarlanmadı", + "models.form.secretPlaceholder": "anahtarı ayarla veya değiştir (yalnızca yazma)", + "models.deleteConfirm": "\"{id}\" modelini sil?", + + // routing + "routing.title": "Yönlendirme", + "routing.subtitle": "Karmaşıklık kademelerini sıralı model listesiyle eşleştirin (öncelik = yedek).", + "routing.default": "Varsayılan model", + "routing.defaultHint": "Yönlendirici erişilemez olduğunda kullanılır.", + "routing.tiers": "Kademeler", + "routing.tierHint": "Sıralamak için çipleri sürükleyin; birincisi tercih edilir, diğerleri yedektir.", + "routing.addModel": "+ ekle", + "routing.addTier": "Kademe ekle", + "routing.tierName": "Kademe adı", + "routing.policy": "İlke", + "routing.policy.mode": "Mod", + "routing.policy.fixed": "Sabit tablo", + "routing.policy.costAware": "Maliyet bilinçli", + "routing.policy.maxCost": "İstek başına maks. maliyet ($)", + "routing.policy.minClass": "Kademe başına minimum sınıf", + "routing.empty": "Kullanılabilir model yok — önce model ekleyin.", + + // protocols + "protocols.title": "Protokoller", + "protocols.subtitle": "Yalnızca ihtiyaç duyduğunuz gelen API yüzeylerini etkinleştirin. Geçişler anında uygulanır.", + "protocols.implemented": "uygulandı", + "protocols.planned": "planlandı", + "protocols.openai_chat": "OpenAI Chat Completions", + "protocols.openai_chat.d": "POST /v1/chat/completions — OpenAI SDK, LangChain, crewAI ile çalışır.", + "protocols.openai_completions": "OpenAI Completions (eski)", + "protocols.openai_completions.d": "POST /v1/completions — eski entegrasyonlar.", + "protocols.openai_embeddings": "OpenAI Embeddings", + "protocols.openai_embeddings.d": "POST /v1/embeddings — RAG ardışık düzenleri.", + "protocols.openai_models": "OpenAI Models", + "protocols.openai_models.d": "GET /v1/models — istemci otomatik keşfi.", + "protocols.anthropic_messages": "Anthropic Messages", + "protocols.anthropic_messages.d": "POST /v1/messages — Claude yerel ajanları.", + "protocols.mcp": "MCP (Model Context Protocol)", + "protocols.mcp.d": "JSON-RPC / SSE — MCP yerel orkestratörler.", + "protocols.native_passthrough": "Yerel geçiş", + "protocols.native_passthrough.d": "POST /route — yönlendirme kararına doğrudan erişim.", + + // keys + "keys.title": "API anahtarları", + "keys.subtitle": "Ajanlarınız için sanal gateway anahtarları. Sağlayıcı anahtarları gateway'den hiç çıkmaz.", + "keys.add": "Yeni anahtar", + "keys.empty": "Anahtar yapılandırılmadı — gateway açık modda (kimlik doğrulama yok).", + "keys.openMode": "Açık mod: tüm istekler kabul edilir (anahtar gerekmez).", + "keys.col.key": "Anahtar", + "keys.col.account": "Hesap", + "keys.col.rate": "Oran / dak", + "keys.col.models": "İzin verilen modeller", + "keys.form.title": "Yeni API anahtarı", + "keys.form.account": "Hesap", + "keys.form.rate": "Oran sınırı / dak", + "keys.form.allow": "İzin verilen modeller", + "keys.form.allowHint": "Tüm modellere izin vermek için boş bırakın.", + "keys.form.custom": "Özel anahtar (isteğe bağlı)", + "keys.form.customHint": "sk-gw-… otomatik oluşturmak için boş bırakın.", + "keys.created": "Anahtar oluşturuldu — şimdi kopyalayın, bir daha gösterilmeyecek:", + "keys.revoke": "İptal et", + "keys.revokeConfirm": "Bu anahtarı iptal et?", + "keys.allowAll": "tümü", + + // playground + "pg.title": "Oyun alanı", + "pg.subtitle": "Canlı ardışık düzen üzerinden istem gönderin ve yönlendirme kararını inceleyin.", + "pg.system": "Sistem istemi", + "pg.systemPlaceholder": "isteğe bağlı sistem mesajı", + "pg.prompt": "İstem", + "pg.promptPlaceholder": "Bir şey sorun…", + "pg.mode": "Mod", + "pg.mode.auto": "Otomatik (yönlendir)", + "pg.mode.pinned": "Sabitlenmiş model", + "pg.profile": "Profil", + "pg.model": "Model", + "pg.temp": "Sıcaklık", + "pg.maxTokens": "Maks. token", + "pg.send": "Gönder", + "pg.sending": "Gönderiliyor…", + "pg.answer": "Yanıt", + "pg.empty": "Yanıt ve yönlendirme kararı burada görünecek.", + "pg.decision": "Yönlendirme kararı", + "pg.task": "Görev", + "pg.tier": "Kademe", + "pg.score": "Karmaşıklık", + "pg.selected": "Seçilen model", + "pg.source": "Rota kaynağı", + "pg.cost": "Maliyet", + "pg.latency": "Gecikme", + "pg.tokens": "Token'lar (giriş/çıkış)", + "pg.failover": "Yedekleme", + "pg.error": "İstek başarısız", + + // settings + "settings.title": "Ayarlar", + "settings.subtitle": "Gateway bağlantısı, yönlendirme girişi, güvenilirlik ve gözlemlenebilirlik.", + "settings.router": "Yönlendirici bağlantısı", + "settings.router.url": "Yönlendirici URL'si", + "settings.router.keyEnv": "Yönlendirici anahtarı ortam değişkeni adı", + "settings.router.timeout": "Zaman aşımı (ms)", + "settings.router.verifyTls": "TLS sertifikasını doğrula", + "settings.router.taxonomy": "Taksonomi id", + "settings.route": "Yönlendirme girişi", + "settings.route.strategy": "Metin stratejisi", + "settings.route.maxChars": "Maks. karakter", + "settings.route.cacheTtl": "Önbellek TTL", + "settings.route.profile": "Varsayılan profil", + "settings.breaker": "Devre kesici", + "settings.breaker.threshold": "Hata eşiği", + "settings.breaker.cooldown": "Bekleme süresi", + "settings.log": "Günlükleme", + "settings.log.level": "Günlük seviyesi", + "settings.log.bodies": "Mesaj gövdelerini günlükle (gizlilik kapalı)", + "settings.telemetry": "Telemetri", + "settings.telemetry.metrics": "Prometheus /metrics'i aç", + "settings.cortiq": "Yanıt meta verisi", + "settings.cortiq.echo": "Yanıtlarda cortiq yönlendirme bloğunu yansıt", + "settings.stats": "İstatistikler", + "settings.stats.enabled": "İstek istatistiklerini kaydet", + "settings.stats.file": "İstatistik dosyası (JSONL)", + "settings.stats.retention": "Saklama süresi", + "settings.listen": "Dinleme adresi", + "settings.export": "Yapılandırmayı dışa aktar", + "settings.import": "Yapılandırmayı içe aktar", + "settings.needsRestart": "Kaydedildi. Bazı değişiklikler (dinleme adresi) yeniden başlatma gerektirir.", + + // toasts / misc + "toast.saved": "Değişiklikler kaydedildi", + "toast.deleted": "Silindi", + "toast.probing": "Sınanıyor…", + "toast.imported": "Yapılandırma içe aktarıldı", +}; diff --git a/web/js/i18n/zh.js b/web/js/i18n/zh.js new file mode 100644 index 0000000..a249db7 --- /dev/null +++ b/web/js/i18n/zh.js @@ -0,0 +1,256 @@ +// 简体中文 — Simplified Chinese translation. Keys must match en.js exactly. +export default { + // brand / common + "brand.sub": "网关", + "common.loading": "加载中…", + "common.save": "保存", + "common.saving": "保存中…", + "common.cancel": "取消", + "common.add": "添加", + "common.edit": "编辑", + "common.delete": "删除", + "common.close": "关闭", + "common.test": "测试", + "common.copy": "复制", + "common.copied": "已复制", + "common.confirm": "确认", + "common.none": "无", + "common.saved": "已保存", + "common.error": "错误", + "common.ok": "确定", + "common.refresh": "刷新", + "common.actions": "操作", + "common.optional": "可选", + "common.search": "搜索", + "common.all": "全部", + + // nav + "nav.dashboard": "仪表盘", + "nav.models": "模型", + "nav.routing": "路由", + "nav.protocols": "协议", + "nav.keys": "API 密钥", + "nav.playground": "沙盒", + "nav.settings": "设置", + "nav.foot": "网关 · v{v}", + + // topbar / status + "status.router": "路由器", + "status.gateway": "网关", + "status.online": "在线", + "status.offline": "离线", + "status.checking": "检测中…", + "theme.toggle": "主题", + "logout": "退出", + + // login + "login.title": "allaigate Gateway", + "login.subtitle": "输入管理员令牌以管理此网关。", + "login.token": "管理员令牌", + "login.tokenPlaceholder": "粘贴管理员令牌", + "login.submit": "进入控制台", + "login.hint": "令牌将在网关启动日志中打印,或通过 [admin].token_env 设置。", + "login.failed": "无效的管理员令牌。", + + // dashboard + "dash.title": "仪表盘", + "dash.subtitle": "模型池的实时流量、费用与路由分析。", + "dash.range": "时间范围", + "dash.range.1h": "1小时", + "dash.range.24h": "24小时", + "dash.range.7d": "7天", + "dash.kpi.requests": "请求数", + "dash.kpi.tokens": "Token 数", + "dash.kpi.cost": "费用", + "dash.kpi.latency": "平均延迟", + "dash.kpi.success": "成功率", + "dash.kpi.failovers": "故障转移", + "dash.series.title": "请求趋势", + "dash.series.cost": "费用趋势", + "dash.series.empty": "此时间段内暂无流量。", + "dash.breakdown.title": "明细", + "dash.groupby.model": "按模型", + "dash.groupby.tier": "按层级", + "dash.groupby.label": "按任务", + "dash.groupby.account": "按账号", + "dash.recent.title": "最近请求", + "dash.recent.empty": "暂无请求记录,请前往沙盒测试。", + "dash.col.time": "时间", + "dash.col.model": "模型", + "dash.col.tier": "层级", + "dash.col.task": "任务", + "dash.col.tokens": "Token", + "dash.col.cost": "费用", + "dash.col.latency": "延迟", + "dash.col.outcome": "结果", + "dash.col.requests": "请求数", + "dash.col.errors": "错误数", + "dash.health.title": "健康状态", + "dash.health.reachable": "可达", + "dash.health.unreachable": "不可达", + + // models + "models.title": "模型", + "models.subtitle": "模型池——本地低成本模型与云端 API 混合部署。", + "models.add": "添加模型", + "models.empty": "暂无模型,请添加第一个模型。", + "models.col.id": "ID", + "models.col.provider": "提供商", + "models.col.model": "模型", + "models.col.tier": "费用层级", + "models.col.key": "密钥", + "models.col.caps": "能力", + "models.col.price": "价格(输入/输出)", + "models.probe": "探测", + "models.probe.ok": "可达({ms} ms)", + "models.probe.fail": "失败:{err}", + "models.form.addTitle": "添加模型", + "models.form.editTitle": "编辑模型", + "models.form.id": "ID", + "models.form.idHint": "路由中使用的唯一 ID,例如 local-qwen", + "models.form.provider": "提供商", + "models.form.baseUrl": "Base URL", + "models.form.model": "模型名称", + "models.form.kind": "类型", + "models.form.costTier": "费用层级", + "models.form.priceIn": "输入价格($/1M)", + "models.form.priceOut": "输出价格($/1M)", + "models.form.apiKeyEnv": "API 密钥环境变量名", + "models.form.apiKeyEnvHint": "持有该提供商密钥的环境变量或存储机密名称。", + "models.form.caps": "能力", + "models.form.secret": "密钥值", + "models.form.secretStored": "已存储", + "models.form.secretEnv": "来自环境变量", + "models.form.secretMissing": "未设置", + "models.form.secretPlaceholder": "设置或替换密钥(只写)", + "models.deleteConfirm": "删除模型 \"{id}\"?", + + // routing + "routing.title": "路由", + "routing.subtitle": "将复杂度层级映射到有序模型列表(优先级 = 回退顺序)。", + "routing.default": "默认模型", + "routing.defaultHint": "路由器不可达时使用。", + "routing.tiers": "层级", + "routing.tierHint": "拖动标签重新排序;第一个为首选,其余为回退。", + "routing.addModel": "+ 添加", + "routing.addTier": "添加层级", + "routing.tierName": "层级名称", + "routing.policy": "策略", + "routing.policy.mode": "模式", + "routing.policy.fixed": "固定表", + "routing.policy.costAware": "成本感知", + "routing.policy.maxCost": "单请求最大费用($)", + "routing.policy.minClass": "每层最低等级", + "routing.empty": "暂无可用模型,请先添加模型。", + + // protocols + "protocols.title": "协议", + "protocols.subtitle": "仅启用所需的入站 API 接口,切换立即生效。", + "protocols.implemented": "已实现", + "protocols.planned": "计划中", + "protocols.openai_chat": "OpenAI Chat Completions", + "protocols.openai_chat.d": "POST /v1/chat/completions — 兼容 OpenAI SDK、LangChain、crewAI。", + "protocols.openai_completions": "OpenAI Completions(旧版)", + "protocols.openai_completions.d": "POST /v1/completions — 旧版集成。", + "protocols.openai_embeddings": "OpenAI Embeddings", + "protocols.openai_embeddings.d": "POST /v1/embeddings — RAG 管道。", + "protocols.openai_models": "OpenAI Models", + "protocols.openai_models.d": "GET /v1/models — 客户端自动发现。", + "protocols.anthropic_messages": "Anthropic Messages", + "protocols.anthropic_messages.d": "POST /v1/messages — Claude 原生智能体。", + "protocols.mcp": "MCP(模型上下文协议)", + "protocols.mcp.d": "JSON-RPC / SSE — MCP 原生编排器。", + "protocols.native_passthrough": "原生透传", + "protocols.native_passthrough.d": "POST /route — 直接访问路由决策。", + + // keys + "keys.title": "API 密钥", + "keys.subtitle": "为您的智能体提供虚拟网关密钥,提供商密钥不离开网关。", + "keys.add": "新建密钥", + "keys.empty": "未配置密钥——网关处于开放模式(无需认证)。", + "keys.openMode": "开放模式:接受所有请求(无需密钥)。", + "keys.col.key": "密钥", + "keys.col.account": "账号", + "keys.col.rate": "速率/分钟", + "keys.col.models": "允许模型", + "keys.form.title": "新建 API 密钥", + "keys.form.account": "账号", + "keys.form.rate": "速率限制/分钟", + "keys.form.allow": "允许模型", + "keys.form.allowHint": "留空表示允许所有模型。", + "keys.form.custom": "自定义密钥(可选)", + "keys.form.customHint": "留空将自动生成 sk-gw-…", + "keys.created": "密钥已创建——请立即复制,之后将不再显示:", + "keys.revoke": "吊销", + "keys.revokeConfirm": "确认吊销此密钥?", + "keys.allowAll": "全部", + + // playground + "pg.title": "沙盒", + "pg.subtitle": "通过实时管道发送提示并查看路由决策。", + "pg.system": "系统提示", + "pg.systemPlaceholder": "可选系统消息", + "pg.prompt": "提示", + "pg.promptPlaceholder": "请输入问题…", + "pg.mode": "模式", + "pg.mode.auto": "自动(路由)", + "pg.mode.pinned": "固定模型", + "pg.profile": "配置文件", + "pg.model": "模型", + "pg.temp": "温度", + "pg.maxTokens": "最大 Token 数", + "pg.send": "发送", + "pg.sending": "发送中…", + "pg.answer": "回答", + "pg.empty": "回答和路由决策将在此显示。", + "pg.decision": "路由决策", + "pg.task": "任务", + "pg.tier": "层级", + "pg.score": "复杂度", + "pg.selected": "已选模型", + "pg.source": "路由来源", + "pg.cost": "费用", + "pg.latency": "延迟", + "pg.tokens": "Token(输入/输出)", + "pg.failover": "故障转移", + "pg.error": "请求失败", + + // settings + "settings.title": "设置", + "settings.subtitle": "网关连接、路由输入、可靠性与可观测性。", + "settings.router": "路由器连接", + "settings.router.url": "路由器 URL", + "settings.router.keyEnv": "路由器密钥环境变量名", + "settings.router.timeout": "超时(ms)", + "settings.router.verifyTls": "验证 TLS 证书", + "settings.router.taxonomy": "分类体系 ID", + "settings.route": "路由输入", + "settings.route.strategy": "文本策略", + "settings.route.maxChars": "最大字符数", + "settings.route.cacheTtl": "缓存 TTL", + "settings.route.profile": "默认配置文件", + "settings.breaker": "熔断器", + "settings.breaker.threshold": "错误阈值", + "settings.breaker.cooldown": "冷却时间", + "settings.log": "日志", + "settings.log.level": "日志级别", + "settings.log.bodies": "记录消息体(隐私关闭)", + "settings.telemetry": "遥测", + "settings.telemetry.metrics": "暴露 Prometheus /metrics", + "settings.cortiq": "响应元数据", + "settings.cortiq.echo": "在响应中回显 cortiq 路由块", + "settings.stats": "统计", + "settings.stats.enabled": "记录请求统计", + "settings.stats.file": "统计文件(JSONL)", + "settings.stats.retention": "保留期", + "settings.listen": "监听地址", + "settings.export": "导出配置", + "settings.import": "导入配置", + "settings.needsRestart": "已保存。部分更改(监听地址)需要重启生效。", + + // toasts / misc + "toast.saved": "更改已保存", + "toast.deleted": "已删除", + "toast.probing": "探测中…", + "toast.imported": "配置已导入", +}; diff --git a/web/js/ui.js b/web/js/ui.js new file mode 100644 index 0000000..b3592b0 --- /dev/null +++ b/web/js/ui.js @@ -0,0 +1,103 @@ +// Tiny DOM helpers — no framework. `h` builds elements; `mount` swaps children. +import { t } from "./i18n.js"; + +export function h(tag, attrs = {}, ...children) { + const el = document.createElement(tag); + for (const [k, v] of Object.entries(attrs || {})) { + if (v == null || v === false) continue; + if (k === "class") el.className = v; + else if (k === "html") el.innerHTML = v; + else if (k === "dataset") Object.assign(el.dataset, v); + else if (k.startsWith("on") && typeof v === "function") el.addEventListener(k.slice(2).toLowerCase(), v); + else if (v === true) el.setAttribute(k, ""); + else el.setAttribute(k, v); + } + for (const c of children.flat()) { + if (c == null || c === false) continue; + el.appendChild(typeof c === "object" ? c : document.createTextNode(String(c))); + } + return el; +} + +export function clear(node) { + while (node && node.firstChild) node.removeChild(node.firstChild); +} + +export function mount(node, ...children) { + clear(node); + for (const c of children.flat()) if (c != null && c !== false) node.appendChild(c); + return node; +} + +export function toast(msg, kind = "info", ms = 3200) { + const box = document.getElementById("toasts"); + if (!box) return; + const el = h("div", { class: `toast ${kind}` }, msg); + box.appendChild(el); + setTimeout(() => { + el.style.opacity = "0"; + el.style.transition = "opacity .2s"; + setTimeout(() => el.remove(), 220); + }, ms); +} + +// Modal dialog. `body` is a DOM node; `onSave` returns a Promise; returns nothing. +export function modal(title, body, onSave, saveLabel) { + const backdrop = h("div", { class: "modal-backdrop" }); + const close = () => backdrop.remove(); + backdrop.addEventListener("click", (e) => { + if (e.target === backdrop) close(); + }); + const saveBtn = h("button", { class: "btn primary" }, saveLabel || t("common.save")); + saveBtn.addEventListener("click", async () => { + saveBtn.disabled = true; + try { + const keep = await onSave(); + if (keep !== false) close(); + } finally { + saveBtn.disabled = false; + } + }); + const card = h( + "div", + { class: "modal" }, + h("h3", {}, title), + body, + h( + "div", + { class: "modal-foot" }, + h("button", { class: "btn ghost", onClick: close }, t("common.cancel")), + onSave ? saveBtn : null + ) + ); + backdrop.appendChild(card); + document.body.appendChild(backdrop); + return { close }; +} + +export function confirmDialog(message) { + return Promise.resolve(window.confirm(message)); +} + +// number formatting +export function money(n) { + if (n == null) return "—"; + if (n === 0) return "$0"; + if (Math.abs(n) < 0.01) return "$" + n.toFixed(6); + return "$" + n.toFixed(4); +} +export function ms(n) { + return n == null ? "—" : `${Math.round(Number(n))} ms`; +} +export function num(n) { + if (n == null) return "—"; + return Number(n).toLocaleString(); +} +export function pct(n) { + if (n == null) return "—"; + return (n * 100).toFixed(1) + "%"; +} +export function timeAgo(unixSecs) { + const d = new Date(unixSecs * 1000); + return d.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit" }); +} diff --git a/web/js/views/dashboard.js b/web/js/views/dashboard.js new file mode 100644 index 0000000..50c14ce --- /dev/null +++ b/web/js/views/dashboard.js @@ -0,0 +1,218 @@ +// Dashboard — KPIs, time-series charts, breakdown, recent requests, health. +import { h, mount, money, num, ms, pct, timeAgo } from "../ui.js"; +import { t } from "../i18n.js"; +import { api } from "../api.js"; +import { lineChart, barList } from "../charts.js"; + +const RANGES = ["1h", "24h", "7d"]; +const GROUPS = ["model", "tier", "label", "account"]; + +function kpi(big, lbl) { + return h("div", { class: "kpi" }, h("div", { class: "big" }, big), h("div", { class: "lbl" }, lbl)); +} + +function seg(options, current, onPick, labelFn) { + return h( + "div", + { class: "seg" }, + ...options.map((o) => + h("button", { class: o === current ? "active" : "", onClick: () => onPick(o) }, labelFn ? labelFn(o) : o) + ) + ); +} + +export async function renderDashboard() { + let range = "24h"; + let groupby = "model"; + const root = h("div"); + + async function load() { + const rangeSecs = range; + let stats, recent, health; + try { + [stats, recent, health] = await Promise.all([ + api.stats(rangeSecs, groupby), + api.requests(40, 0), + api.health().catch(() => null), + ]); + } catch (e) { + mount(root, h("div", { class: "callout" }, String(e.message || e))); + return; + } + const tot = stats.totals || {}; + const series = stats.series || []; + const breakdown = (stats.breakdown || []).map((b) => ({ key: b.key || t("common.none"), value: b.requests })); + + mount( + root, + h( + "div", + { class: "page-head" }, + h( + "div", + { class: "flex" }, + h("div", { class: "grow" }, h("h2", {}, t("dash.title")), h("p", {}, t("dash.subtitle"))), + seg(RANGES, range, (r) => { + range = r; + load(); + }, (r) => t("dash.range." + r)) + ) + ), + + // KPIs + h( + "div", + { class: "kpis" }, + kpi(num(tot.requests), t("dash.kpi.requests")), + kpi(num(tot.total_tokens), t("dash.kpi.tokens")), + kpi(money(tot.cost_usd), t("dash.kpi.cost")), + kpi(ms(tot.avg_latency_ms), t("dash.kpi.latency")), + kpi(pct(tot.success_rate), t("dash.kpi.success")), + kpi(num(tot.failovers), t("dash.kpi.failovers")) + ), + + h( + "div", + { class: "grid cols-2" }, + h( + "div", + { class: "card" }, + h("div", { class: "card-head" }, h("h3", {}, t("dash.series.title"))), + series.length < 2 ? h("div", { class: "empty" }, t("dash.series.empty")) : lineChart(series, "requests") + ), + h( + "div", + { class: "card" }, + h("div", { class: "card-head" }, h("h3", {}, t("dash.series.cost"))), + series.length < 2 ? h("div", { class: "empty" }, t("dash.series.empty")) : lineChart(series, "cost_usd") + ) + ), + + // breakdown + h( + "div", + { class: "card" }, + h( + "div", + { class: "card-head" }, + h("h3", {}, t("dash.breakdown.title")), + h( + "div", + { class: "right" }, + seg(GROUPS, groupby, (g) => { + groupby = g; + load(); + }, (g) => t("dash.groupby." + g)) + ) + ), + barList(breakdown, num) + ), + + // recent + h( + "div", + { class: "card" }, + h("div", { class: "card-head" }, h("h3", {}, t("dash.recent.title"))), + recentTable(recent.requests || []) + ), + + health ? healthCard(health) : null + ); + } + + await load(); + return root; +} + +function recentTable(rows) { + if (!rows.length) return h("div", { class: "empty" }, t("dash.recent.empty")); + return h( + "div", + { class: "table-wrap" }, + h( + "table", + {}, + h( + "thead", + {}, + h( + "tr", + {}, + h("th", {}, t("dash.col.time")), + h("th", {}, t("dash.col.model")), + h("th", {}, t("dash.col.tier")), + h("th", {}, t("dash.col.task")), + h("th", {}, t("dash.col.tokens")), + h("th", {}, t("dash.col.cost")), + h("th", {}, t("dash.col.latency")), + h("th", {}, t("dash.col.outcome")) + ) + ), + h( + "tbody", + {}, + ...rows.map((r) => + h( + "tr", + {}, + 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.tier ? h("span", { class: "badge tier-" + r.tier }, r.tier) : "—"), + h("td", {}, r.task_label || "—"), + h("td", { class: "mono" }, `${r.prompt_tokens}/${r.completion_tokens}`), + h("td", { class: "mono" }, money(r.cost_usd)), + h("td", { class: "mono" }, ms(r.latency_ms)), + h("td", {}, h("span", { class: "badge " + (r.outcome === "ok" ? "ok" : "error") }, r.outcome)) + ) + ) + ) + ) + ); +} + +function healthCard(hh) { + return h( + "div", + { class: "card" }, + h("div", { class: "card-head" }, h("h3", {}, t("dash.health.title"))), + h( + "div", + { class: "flex wrap", style: "margin-bottom:12px" }, + h( + "span", + { class: "badge " + (hh.router?.reachable ? "ok" : "bad"), title: hh.router?.url || "" }, + t("status.router") + ": " + (hh.router?.reachable ? t("dash.health.reachable") : t("dash.health.unreachable")) + ) + ), + h( + "div", + { class: "table-wrap" }, + h( + "table", + {}, + h("thead", {}, h("tr", {}, h("th", {}, t("models.col.id")), h("th", {}, t("models.col.provider")), h("th", {}, t("models.col.model")), h("th", {}, t("models.col.key")))), + h( + "tbody", + {}, + ...(hh.models || []).map((m) => + h( + "tr", + {}, + h("td", { class: "mono" }, m.id), + h("td", {}, m.provider), + h("td", { class: "mono" }, m.model), + h("td", {}, h("span", { class: "badge " + keyBadge(m.key_source) }, m.key_source)) + ) + ) + ) + ) + ) + ); +} + +function keyBadge(src) { + if (src === "store") return "store"; + if (src === "env") return "env"; + if (src === "missing") return "bad"; + return ""; +} diff --git a/web/js/views/keys.js b/web/js/views/keys.js new file mode 100644 index 0000000..8e83f25 --- /dev/null +++ b/web/js/views/keys.js @@ -0,0 +1,128 @@ +// API keys — list, create (with copy-once), revoke. +import { h, mount, modal, toast, confirmDialog } from "../ui.js"; +import { t } from "../i18n.js"; +import { api } from "../api.js"; + +export async function renderKeys() { + const modelsData = await api.listModels(); + const ids = (modelsData.models || []).map((m) => m.id); + const root = h("div"); + + function openCreate(reload) { + const accountIn = h("input", { placeholder: "team-a" }); + const rateIn = h("input", { type: "number", value: 600 }); + const customIn = h("input", { placeholder: "sk-gw-…" }); + const allowInputs = ids.map((id) => ({ id, cb: h("input", { type: "checkbox" }) })); + const body = h( + "div", + {}, + h("label", { class: "field" }, h("span", {}, t("keys.form.account")), accountIn), + h("label", { class: "field" }, h("span", {}, t("keys.form.rate")), rateIn), + h( + "label", + { class: "field" }, + h("span", {}, t("keys.form.allow")), + h("div", { class: "flex wrap" }, ...allowInputs.map(({ id, cb }) => h("label", { class: "check" }, cb, id))), + h("div", { class: "hint" }, t("keys.form.allowHint")) + ), + h("label", { class: "field" }, h("span", {}, t("keys.form.custom")), customIn, h("div", { class: "hint" }, t("keys.form.customHint"))) + ); + modal(t("keys.form.title"), body, async () => { + try { + const r = await api.createKey({ + key: customIn.value.trim(), + account: accountIn.value.trim() || "default", + rate_per_min: parseInt(rateIn.value) || 0, + allow_models: allowInputs.filter(({ cb }) => cb.checked).map(({ id }) => id), + }); + reload(); + showCreated(r.key); + } catch (e) { + toast(String(e.message || e), "bad"); + return false; + } + }, t("common.add")); + } + + function showCreated(key) { + const input = h("input", { value: key, readonly: true, class: "mono" }); + const copyBtn = h("button", { class: "btn", onClick: () => { input.select(); navigator.clipboard?.writeText(key); toast(t("common.copied"), "good"); } }, t("common.copy")); + modal(t("common.ok"), h("div", {}, h("p", {}, t("keys.created")), h("div", { class: "flex" }, input, copyBtn)), null); + } + + async function reload() { + const data = await api.listKeys(); + const keys = data.keys || []; + mount( + root, + h( + "div", + { class: "page-head" }, + h( + "div", + { class: "flex" }, + h("div", { class: "grow" }, h("h2", {}, t("keys.title")), h("p", {}, t("keys.subtitle"))), + h("button", { class: "btn primary", onClick: () => openCreate(reload) }, "+ " + t("keys.add")) + ) + ), + data.open_mode ? h("div", { class: "callout info" }, t("keys.openMode")) : null, + keys.length === 0 + ? h("div", { class: "card" }, h("div", { class: "empty" }, t("keys.empty"))) + : h( + "div", + { class: "card" }, + h( + "div", + { class: "table-wrap" }, + h( + "table", + {}, + h( + "thead", + {}, + h("tr", {}, h("th", {}, t("keys.col.key")), h("th", {}, t("keys.col.account")), h("th", {}, t("keys.col.rate")), h("th", {}, t("keys.col.models")), h("th", { class: "right-align" }, t("common.actions"))) + ), + h( + "tbody", + {}, + ...keys.map((k) => + h( + "tr", + {}, + h("td", { class: "mono" }, k.key_masked), + h("td", {}, k.account), + h("td", { class: "mono" }, k.rate_per_min || "—"), + h("td", {}, (k.allow_models && k.allow_models.length) ? k.allow_models.join(", ") : h("span", { class: "muted" }, t("keys.allowAll"))), + h( + "td", + { class: "right-align" }, + h( + "button", + { + class: "btn sm danger", + onClick: async () => { + if (!(await confirmDialog(t("keys.revokeConfirm")))) return; + try { + await api.deleteKey(k.key); + toast(t("toast.deleted"), "good"); + reload(); + } catch (e) { + toast(String(e.message || e), "bad"); + } + }, + }, + t("keys.revoke") + ) + ) + ) + ) + ) + ) + ) + ) + ); + } + + await reload(); + return root; +} diff --git a/web/js/views/login.js b/web/js/views/login.js new file mode 100644 index 0000000..e8ffd82 --- /dev/null +++ b/web/js/views/login.js @@ -0,0 +1,40 @@ +// Login screen — admin token entry. Shown when there is no token or on 401. +import { h } from "../ui.js"; +import { t } from "../i18n.js"; +import { setToken } from "../api.js"; + +export function renderLogin(onOk) { + const input = h("input", { + type: "password", + placeholder: t("login.tokenPlaceholder"), + autofocus: true, + }); + const submit = () => { + const val = input.value.trim(); + if (!val) return; + setToken(val); + onOk(); + }; + input.addEventListener("keydown", (e) => { + if (e.key === "Enter") submit(); + }); + return h( + "div", + { class: "login-wrap" }, + h( + "div", + { class: "login-card" }, + h( + "div", + { class: "brand" }, + h("b", { style: "font-size:20px" }, "allaigate"), + h("span", { class: "sub" }, t("brand.sub")) + ), + h("h2", {}, t("login.title")), + h("p", { class: "sub" }, t("login.subtitle")), + h("label", { class: "field" }, h("span", {}, t("login.token")), input), + h("button", { class: "btn primary", style: "width:100%", onClick: submit }, t("login.submit")), + h("p", { class: "hint", style: "margin-top:16px" }, t("login.hint")) + ) + ); +} diff --git a/web/js/views/models.js b/web/js/views/models.js new file mode 100644 index 0000000..9f3ff68 --- /dev/null +++ b/web/js/views/models.js @@ -0,0 +1,206 @@ +// Models — pool table with add/edit modal, probe, and per-model secret entry. +import { h, mount, modal, toast, confirmDialog, money } from "../ui.js"; +import { t } from "../i18n.js"; +import { api } from "../api.js"; +import { appState } from "../app.js"; + +function field(label, control, hint) { + return h("label", { class: "field" }, h("span", {}, label), control, hint ? h("div", { class: "hint" }, hint) : null); +} +function opt(v, label, sel) { + return h("option", { value: v, selected: sel ? true : null }, label || v); +} + +function keyBadge(src) { + const map = { store: "store", env: "env", missing: "bad", none: "" }; + return h("span", { class: "badge " + (map[src] ?? "") }, src); +} + +function modelForm(meta, existing) { + const m = existing || { provider: "openai", kind: "chat", cost_tier: "cheap", caps: [], price_in: 0, price_out: 0 }; + const idIn = h("input", { value: m.id || "", placeholder: "local-qwen", disabled: existing ? true : null }); + const providerSel = h("select", {}, ...(meta.providers || ["openai"]).map((p) => opt(p, p, p === m.provider))); + const baseUrlIn = h("input", { value: m.base_url || "", placeholder: "http://localhost:8000/v1" }); + const modelIn = h("input", { value: m.model || "", placeholder: "qwen2.5-7b-instruct" }); + const kindSel = h("select", {}, ...(meta.kinds || ["chat"]).map((k) => opt(k, k, k === m.kind))); + const tierSel = h("select", {}, ...(meta.cost_tiers || ["cheap"]).map((c) => opt(c, c, c === m.cost_tier))); + const priceInIn = h("input", { type: "number", step: "0.01", value: m.price_in ?? 0 }); + const priceOutIn = h("input", { type: "number", step: "0.01", value: m.price_out ?? 0 }); + const keyEnvIn = h("input", { value: m.api_key_env || "", placeholder: "OPENAI_API_KEY" }); + const secretIn = h("input", { type: "password", placeholder: t("models.form.secretPlaceholder") }); + const capInputs = (meta.caps || ["tools", "vision"]).map((c) => { + const cb = h("input", { type: "checkbox", checked: (m.caps || []).includes(c) ? true : null }); + return { c, cb }; + }); + + const node = h( + "div", + {}, + h("div", { class: "row" }, field(t("models.form.id"), idIn, existing ? null : t("models.form.idHint")), field(t("models.form.provider"), providerSel)), + field(t("models.form.baseUrl"), baseUrlIn), + field(t("models.form.model"), modelIn), + h("div", { class: "row" }, field(t("models.form.kind"), kindSel), field(t("models.form.costTier"), tierSel)), + h("div", { class: "row" }, field(t("models.form.priceIn"), priceInIn), field(t("models.form.priceOut"), priceOutIn)), + field(t("models.form.caps"), h("div", { class: "flex wrap" }, ...capInputs.map(({ c, cb }) => h("label", { class: "check" }, cb, c)))), + field(t("models.form.apiKeyEnv"), keyEnvIn, t("models.form.apiKeyEnvHint")), + field(t("models.form.secret"), secretIn) + ); + + const getValue = () => ({ + model: { + id: existing ? m.id : idIn.value.trim(), + provider: providerSel.value, + base_url: baseUrlIn.value.trim(), + model: modelIn.value.trim(), + kind: kindSel.value, + cost_tier: tierSel.value, + price_in: parseFloat(priceInIn.value) || 0, + price_out: parseFloat(priceOutIn.value) || 0, + api_key_env: keyEnvIn.value.trim() || null, + caps: capInputs.filter(({ cb }) => cb.checked).map(({ c }) => c), + }, + secret: secretIn.value, + keyEnv: keyEnvIn.value.trim(), + }); + + return { node, getValue }; +} + +async function openModal(meta, existing, reload) { + const { node, getValue } = modelForm(meta, existing); + modal(existing ? t("models.form.editTitle") : t("models.form.addTitle"), node, async () => { + const { model, secret, keyEnv } = getValue(); + if (!model.id) { + toast(t("models.form.id") + "?", "bad"); + return false; + } + // strip null api_key_env so serde keeps it optional + if (!model.api_key_env) delete model.api_key_env; + try { + if (existing) await api.updateModel(existing.id, model); + else await api.createModel(model); + if (secret && keyEnv) await api.setSecret(keyEnv, secret); + toast(t("toast.saved"), "good"); + reload(); + } catch (e) { + toast(String(e.message || e), "bad"); + return false; + } + }); +} + +export async function renderModels() { + const meta = appState.meta || (await api.meta()); + const root = h("div"); + + async function reload() { + const data = await api.listModels(); + const models = data.models || []; + mount( + root, + h( + "div", + { class: "page-head" }, + h( + "div", + { class: "flex" }, + h("div", { class: "grow" }, h("h2", {}, t("models.title")), h("p", {}, t("models.subtitle"))), + h("button", { class: "btn primary", onClick: () => openModal(meta, null, reload) }, "+ " + t("models.add")) + ) + ), + models.length === 0 + ? h("div", { class: "card" }, h("div", { class: "empty" }, t("models.empty"))) + : h( + "div", + { class: "card" }, + h( + "div", + { class: "table-wrap" }, + h( + "table", + {}, + h( + "thead", + {}, + h( + "tr", + {}, + h("th", {}, t("models.col.id")), + h("th", {}, t("models.col.provider")), + h("th", {}, t("models.col.model")), + h("th", {}, t("models.col.tier")), + h("th", {}, t("models.col.key")), + h("th", {}, t("models.col.caps")), + h("th", {}, t("models.col.price")), + h("th", { class: "right-align" }, t("common.actions")) + ) + ), + h( + "tbody", + {}, + ...models.map((m) => row(m, meta, reload)) + ) + ) + ) + ) + ); + } + + await reload(); + return root; +} + +function row(m, meta, reload) { + const probeBtn = h("button", { class: "btn sm ghost" }, t("models.probe")); + probeBtn.addEventListener("click", async () => { + probeBtn.disabled = true; + probeBtn.textContent = "…"; + try { + const r = await api.probeModel(m.id); + if (r.ok) toast(t("models.probe.ok", { ms: r.latency_ms }), "good"); + else toast(t("models.probe.fail", { err: r.error || "" }), "bad"); + } catch (e) { + toast(String(e.message || e), "bad"); + } + probeBtn.disabled = false; + probeBtn.textContent = t("models.probe"); + }); + return h( + "tr", + {}, + h("td", { class: "mono" }, m.id), + h("td", {}, m.provider), + h("td", { class: "mono" }, m.model), + h("td", {}, h("span", { class: "badge " + (m.cost_tier || "") }, m.cost_tier || "—")), + h("td", {}, keyBadge(m.key_source || (m.api_key_env ? "missing" : "none"))), + h("td", {}, (m.caps || []).length ? h("div", { class: "flex wrap" }, ...m.caps.map((c) => h("span", { class: "badge" }, c))) : "—"), + h("td", { class: "mono" }, `${m.price_in || 0}/${m.price_out || 0}`), + h( + "td", + { class: "right-align" }, + h( + "div", + { class: "flex", style: "justify-content:flex-end" }, + probeBtn, + h("button", { class: "btn sm ghost", onClick: () => openModal(meta, m, reload) }, t("common.edit")), + h( + "button", + { + class: "btn sm danger", + onClick: async () => { + if (!(await confirmDialog(t("models.deleteConfirm", { id: m.id })))) return; + try { + await api.deleteModel(m.id); + toast(t("toast.deleted"), "good"); + reload(); + } catch (e) { + toast(String(e.message || e), "bad"); + } + }, + }, + t("common.delete") + ) + ) + ) + ); +} diff --git a/web/js/views/playground.js b/web/js/views/playground.js new file mode 100644 index 0000000..bfb198c --- /dev/null +++ b/web/js/views/playground.js @@ -0,0 +1,137 @@ +// Playground — send a prompt through the live pipeline, inspect routing decision. +import { h, mount, money, ms, num } from "../ui.js"; +import { t } from "../i18n.js"; +import { api } from "../api.js"; +import { appState } from "../app.js"; + +export async function renderPlayground() { + const meta = appState.meta || (await api.meta()); + const modelsData = await api.listModels(); + const ids = (modelsData.models || []).map((m) => m.id); + + let mode = "auto"; + const root = h("div"); + + const sysIn = h("textarea", { placeholder: t("pg.systemPlaceholder"), rows: 2 }); + const promptIn = h("textarea", { placeholder: t("pg.promptPlaceholder"), rows: 5 }); + const tempIn = h("input", { type: "number", step: "0.1", value: 0.7 }); + const maxTokIn = h("input", { type: "number", value: 512 }); + const profileSel = h("select", {}, ...(meta.profiles || []).map((p) => h("option", { value: p }, p))); + const modelSel = h("select", {}, ...ids.map((id) => h("option", { value: id }, id))); + + const modeSeg = h( + "div", + { class: "seg" }, + h("button", { class: "active", onClick: (e) => setMode("auto", e) }, t("pg.mode.auto")), + h("button", { onClick: (e) => setMode("pinned", e) }, t("pg.mode.pinned")) + ); + function buildModeExtra() { + return h( + "label", + { class: "field" }, + h("span", {}, mode === "auto" ? t("pg.profile") : t("pg.model")), + mode === "auto" ? profileSel : modelSel + ); + } + let modeExtra = buildModeExtra(); + function setMode(m, e) { + mode = m; + modeSeg.querySelectorAll("button").forEach((b) => b.classList.remove("active")); + e.target.classList.add("active"); + const next = buildModeExtra(); + modeExtra.replaceWith(next); + modeExtra = next; + } + + const out = h("div", { class: "answer" }, h("div", { class: "empty" }, t("pg.empty"))); + const decision = h("div", { class: "card routecard" }, h("div", { class: "card-head" }, h("h3", {}, t("pg.decision"))), h("div", { class: "empty" }, "—")); + + const sendBtn = h("button", { class: "btn primary" }, t("pg.send")); + sendBtn.addEventListener("click", async () => { + const prompt = promptIn.value.trim(); + if (!prompt) return; + const messages = []; + if (sysIn.value.trim()) messages.push({ role: "system", content: sysIn.value.trim() }); + messages.push({ role: "user", content: prompt }); + let model = "cortiq-auto"; + if (mode === "auto") { + if (profileSel.value) model = "cortiq-auto:" + profileSel.value; + } else { + model = modelSel.value; + } + sendBtn.disabled = true; + sendBtn.textContent = t("pg.sending"); + mount(out, h("div", { class: "flex" }, h("span", { class: "spinner" }), " ", t("pg.sending"))); + try { + const r = await api.test({ + model, + messages, + temperature: parseFloat(tempIn.value), + max_tokens: parseInt(maxTokIn.value) || null, + }); + if (r.ok) { + mount(out, r.answer || h("span", { class: "muted" }, "—")); + renderDecision(r); + } else { + mount(out, h("div", { class: "callout" }, h("b", {}, t("pg.error") + ": "), r.error || "")); + mount(decision, h("div", { class: "card-head" }, h("h3", {}, t("pg.decision"))), h("div", { class: "empty" }, "—")); + } + } catch (e) { + mount(out, h("div", { class: "callout" }, String(e.message || e))); + } + sendBtn.disabled = false; + sendBtn.textContent = t("pg.send"); + }); + + function kv(k, v) { + return h("div", { class: "kv" }, h("span", { class: "k" }, k), h("span", { class: "v" }, v)); + } + function renderDecision(r) { + const c = r.cortiq || {}; + const score = c.complexity?.score ?? 0; + mount( + decision, + h("div", { class: "card-head" }, h("h3", {}, t("pg.decision"))), + kv(t("pg.task"), c.task_label || "—"), + kv(t("pg.tier"), c.complexity?.tier ? h("span", { class: "badge tier-" + c.complexity.tier }, c.complexity.tier) : "—"), + h( + "div", + { class: "kv", style: "display:block" }, + h("div", { class: "flex" }, h("span", { class: "k grow" }, t("pg.score")), h("span", { class: "v" }, score.toFixed(2))), + h("div", { class: "scorebar" }, h("i", { style: `width:${Math.min(100, score * 100)}%` })) + ), + kv(t("pg.selected"), h("span", { class: "mono" }, c.selected_model || "—")), + kv(t("pg.source"), c.route_source || "—"), + kv(t("pg.tokens"), `${r.usage?.prompt_tokens ?? 0}/${r.usage?.completion_tokens ?? 0}`), + kv(t("pg.cost"), money(c.cost_usd)), + kv(t("pg.latency"), ms(r.latency_ms)), + kv(t("pg.failover"), c.failover ? "yes" : "no") + ); + } + + mount( + root, + h("div", { class: "page-head" }, h("h2", {}, t("pg.title")), h("p", {}, t("pg.subtitle"))), + h( + "div", + { class: "pg" }, + h( + "div", + {}, + h( + "div", + { class: "card" }, + h("label", { class: "field" }, h("span", {}, t("pg.system")), sysIn), + h("label", { class: "field" }, h("span", {}, t("pg.prompt")), promptIn), + h("label", { class: "field" }, h("span", {}, t("pg.mode")), modeSeg), + modeExtra, + h("div", { class: "row" }, h("label", { class: "field" }, h("span", {}, t("pg.temp")), tempIn), h("label", { class: "field" }, h("span", {}, t("pg.maxTokens")), maxTokIn)), + h("div", { class: "flex", style: "justify-content:flex-end" }, sendBtn) + ), + h("div", { class: "card" }, h("div", { class: "card-head" }, h("h3", {}, t("pg.answer"))), out) + ), + decision + ) + ); + return root; +} diff --git a/web/js/views/protocols.js b/web/js/views/protocols.js new file mode 100644 index 0000000..7e94608 --- /dev/null +++ b/web/js/views/protocols.js @@ -0,0 +1,67 @@ +// Protocols — live toggles for inbound API surfaces. +import { h, mount, toast } from "../ui.js"; +import { t } from "../i18n.js"; +import { api } from "../api.js"; +import { appState } from "../app.js"; + +const ORDER = [ + "openai_chat", + "openai_completions", + "openai_embeddings", + "openai_models", + "anthropic_messages", + "mcp", + "native_passthrough", +]; + +export async function renderProtocols() { + const meta = appState.meta || (await api.meta()); + const impl = meta.protocols_impl || {}; + const state = await api.getProtocols(); + const root = h("div"); + + async function save() { + try { + await api.putProtocols(state); + toast(t("toast.saved"), "good"); + } catch (e) { + toast(String(e.message || e), "bad"); + } + } + + function row(key) { + const implemented = !!impl[key]; + const input = h("input", { + type: "checkbox", + checked: state[key] ? true : null, + disabled: implemented ? null : true, + onChange: (e) => { + state[key] = e.target.checked; + save(); + }, + }); + return h( + "div", + { class: "togglerow" }, + h( + "div", + { class: "meta" }, + h( + "div", + { class: "name" }, + t("protocols." + key), + h("span", { class: "badge " + (implemented ? "ok" : "") }, implemented ? t("protocols.implemented") : t("protocols.planned")) + ), + h("div", { class: "desc" }, t("protocols." + key + ".d")) + ), + h("label", { class: "switch" }, input, h("span", { class: "slider" })) + ); + } + + mount( + root, + h("div", { class: "page-head" }, h("h2", {}, t("protocols.title")), h("p", {}, t("protocols.subtitle"))), + h("div", { class: "card" }, ...ORDER.map(row)) + ); + return root; +} diff --git a/web/js/views/routing.js b/web/js/views/routing.js new file mode 100644 index 0000000..8dd2a0e --- /dev/null +++ b/web/js/views/routing.js @@ -0,0 +1,158 @@ +// Routing — tier editor (ordered model chips), default model, and policy. +import { h, mount, toast } from "../ui.js"; +import { t } from "../i18n.js"; +import { api } from "../api.js"; +import { appState } from "../app.js"; + +export async function renderRouting() { + const meta = appState.meta || (await api.meta()); + const [routing, modelsData] = await Promise.all([api.getRouting(), api.listModels()]); + const ids = (modelsData.models || []).map((m) => m.id); + + // local editable state — ensure standard tiers exist for a friendly editor + const tiers = Object.assign({ low: [], medium: [], high: [] }, routing.tiers || {}); + const st = { + tiers, + default: routing.default || ids[0] || "", + policy: routing.policy || { mode: "fixed_table", min_class: {} }, + }; + + const root = h("div"); + + function moveChip(tier, i, dir) { + const arr = st.tiers[tier]; + const ni = i + dir; + if (ni < 0 || ni >= arr.length) return; + [arr[i], arr[ni]] = [arr[ni], arr[i]]; + render(); + } + function removeChip(tier, i) { + st.tiers[tier].splice(i, 1); + render(); + } + function addChip(tier, id) { + if (id && !st.tiers[tier].includes(id)) st.tiers[tier].push(id); + render(); + } + + function tierRow(tier) { + const arr = st.tiers[tier]; + const avail = ids.filter((id) => !arr.includes(id)); + const addSel = h( + "select", + { + style: "width:auto", + onChange: (e) => { + addChip(tier, e.target.value); + }, + }, + h("option", { value: "" }, t("routing.addModel")), + ...avail.map((id) => h("option", { value: id }, id)) + ); + return h( + "div", + { class: "tierrow" }, + h("div", { class: "tname" }, h("span", { class: "badge tier-" + tier }, tier)), + h( + "div", + { class: "chips" }, + ...arr.map((id, i) => + h( + "div", + { class: "chip" }, + h("span", { class: "ord" }, i + 1), + id, + h("span", { class: "arrow", title: "←", onClick: () => moveChip(tier, i, -1) }, "◄"), + h("span", { class: "arrow", title: "→", onClick: () => moveChip(tier, i, 1) }, "►"), + h("span", { class: "x", onClick: () => removeChip(tier, i) }, "×") + ) + ), + avail.length ? addSel : null + ) + ); + } + + function policyCard() { + const modeSel = h( + "select", + { onChange: (e) => { st.policy.mode = e.target.value; render(); } }, + h("option", { value: "fixed_table", selected: st.policy.mode === "fixed_table" }, t("routing.policy.fixed")), + h("option", { value: "cost_aware", selected: st.policy.mode === "cost_aware" }, t("routing.policy.costAware")) + ); + const children = [ + h("label", { class: "field" }, h("span", {}, t("routing.policy.mode")), modeSel), + ]; + if (st.policy.mode === "cost_aware") { + const maxIn = h("input", { + type: "number", + step: "0.01", + value: st.policy.max_cost_usd_per_request ?? "", + placeholder: "0.50", + onChange: (e) => { st.policy.max_cost_usd_per_request = e.target.value === "" ? null : parseFloat(e.target.value); }, + }); + children.push(h("label", { class: "field" }, h("span", {}, t("routing.policy.maxCost")), maxIn)); + st.policy.min_class = st.policy.min_class || {}; + const rows = Object.keys(st.tiers).map((tier) => { + const sel = h( + "select", + { onChange: (e) => { st.policy.min_class[tier] = e.target.value; } }, + h("option", { value: "" }, "—"), + ...(meta.cost_tiers || []).map((c) => h("option", { value: c, selected: st.policy.min_class[tier] === c }, c)) + ); + return h("label", { class: "field" }, h("span", {}, t("routing.policy.minClass") + " · " + tier), sel); + }); + children.push(h("div", { class: "row" }, ...rows)); + } + return h("div", { class: "card" }, h("div", { class: "card-head" }, h("h3", {}, t("routing.policy"))), ...children); + } + + function render() { + const defSel = h( + "select", + { onChange: (e) => { st.default = e.target.value; } }, + ...ids.map((id) => h("option", { value: id, selected: id === st.default }, id)) + ); + const saveBtn = h("button", { class: "btn primary" }, t("common.save")); + saveBtn.addEventListener("click", async () => { + saveBtn.disabled = true; + try { + await api.putRouting({ tiers: st.tiers, default: st.default, policy: st.policy }); + toast(t("toast.saved"), "good"); + } catch (e) { + toast(String(e.message || e), "bad"); + } + saveBtn.disabled = false; + }); + + mount( + root, + h( + "div", + { class: "page-head" }, + h( + "div", + { class: "flex" }, + h("div", { class: "grow" }, h("h2", {}, t("routing.title")), h("p", {}, t("routing.subtitle"))), + saveBtn + ) + ), + ids.length === 0 ? h("div", { class: "callout" }, t("routing.empty")) : null, + h( + "div", + { class: "card" }, + h("div", { class: "card-head" }, h("h3", {}, t("routing.tiers")), h("span", { class: "card-head sub" }, t("routing.tierHint"))), + ...Object.keys(st.tiers).map(tierRow) + ), + h( + "div", + { class: "card" }, + h("div", { class: "card-head" }, h("h3", {}, t("routing.default"))), + h("label", { class: "field" }, h("span", {}, t("routing.defaultHint")), defSel) + ), + policyCard() + ); + } + + render(); + return root; +} diff --git a/web/js/views/settings.js b/web/js/views/settings.js new file mode 100644 index 0000000..d0a5cc0 --- /dev/null +++ b/web/js/views/settings.js @@ -0,0 +1,191 @@ +// Settings — router/route/breaker/log/telemetry/stats + export/import config. +import { h, mount, toast } from "../ui.js"; +import { t } from "../i18n.js"; +import { api } from "../api.js"; +import { appState } from "../app.js"; + +function field(label, control, hint) { + return h("label", { class: "field" }, h("span", {}, label), control, hint ? h("div", { class: "hint" }, hint) : null); +} +function check(label, checked) { + const cb = h("input", { type: "checkbox", checked: checked ? true : null }); + return { node: h("label", { class: "check" }, cb, label), cb }; +} + +export async function renderSettings() { + const meta = appState.meta || (await api.meta()); + const s = await api.getSettings(); + const root = h("div"); + + const listenIn = h("input", { value: s.listen || "" }); + // router + const rUrl = h("input", { value: s.router?.url || "" }); + const rKeyEnv = h("input", { value: s.router?.api_key_env || "", placeholder: "CORTIQ_ROUTER_KEY" }); + const rTimeout = h("input", { type: "number", value: s.router?.timeout_ms ?? 800 }); + const rTax = h("input", { value: s.router?.taxonomy_id || "" }); + const rVerify = check(t("settings.router.verifyTls"), s.router?.verify_tls); + // route + const strategySel = h("select", {}, ...(meta.text_strategies || []).map((x) => h("option", { value: x, selected: x === s.route?.text_strategy }, x))); + const maxChars = h("input", { type: "number", value: s.route?.max_chars ?? 4000 }); + const cacheTtl = h("input", { value: s.route?.cache_ttl || "60s" }); + const profileSel = h("select", {}, ...(meta.profiles || []).map((x) => h("option", { value: x, selected: x === s.route?.profile }, x))); + // breaker + const brThresh = h("input", { type: "number", value: s.breaker?.threshold ?? 5 }); + const brCool = h("input", { value: s.breaker?.cooldown || "30s" }); + // log + const logSel = h("select", {}, ...["error", "warn", "info", "debug", "trace"].map((x) => h("option", { value: x, selected: x === s.log?.level }, x))); + const logBodies = check(t("settings.log.bodies"), s.log?.bodies); + // telemetry / cortiq + const metricsCb = check(t("settings.telemetry.metrics"), s.telemetry?.metrics); + const echoCb = check(t("settings.cortiq.echo"), s.cortiq?.echo); + // stats + const statsEnabled = check(t("settings.stats.enabled"), s.stats?.enabled); + const statsFile = h("input", { value: s.stats?.file || "" }); + const statsRet = h("input", { value: s.stats?.retention || "7d" }); + + const saveBtn = h("button", { class: "btn primary" }, t("common.save")); + saveBtn.addEventListener("click", async () => { + saveBtn.disabled = true; + const patch = { + listen: listenIn.value.trim(), + router: { + url: rUrl.value.trim(), + api_key_env: rKeyEnv.value.trim() || null, + timeout_ms: parseInt(rTimeout.value) || 800, + verify_tls: rVerify.cb.checked, + taxonomy_id: rTax.value.trim() || null, + }, + route: { + text_strategy: strategySel.value, + max_chars: parseInt(maxChars.value) || 4000, + cache_ttl: cacheTtl.value.trim() || "60s", + profile: profileSel.value, + }, + breaker: { threshold: parseInt(brThresh.value) || 5, cooldown: brCool.value.trim() || "30s" }, + log: { level: logSel.value, bodies: logBodies.cb.checked }, + telemetry: { metrics: metricsCb.cb.checked, otlp_endpoint_env: s.telemetry?.otlp_endpoint_env || null }, + cortiq: { echo: echoCb.cb.checked }, + stats: { + enabled: statsEnabled.cb.checked, + file: statsFile.value.trim(), + retention: statsRet.value.trim() || "7d", + ring_size: s.stats?.ring_size ?? 500, + }, + }; + // serde: drop null optionals + if (!patch.router.api_key_env) delete patch.router.api_key_env; + if (!patch.router.taxonomy_id) delete patch.router.taxonomy_id; + if (!patch.telemetry.otlp_endpoint_env) delete patch.telemetry.otlp_endpoint_env; + try { + const r = await api.putSettings(patch); + toast(r.needs_restart ? t("settings.needsRestart") : t("toast.saved"), r.needs_restart ? "warn" : "good"); + } catch (e) { + toast(String(e.message || e), "bad"); + } + saveBtn.disabled = false; + }); + + async function exportConfig() { + const cfg = await api.getConfig(); + const blob = new Blob([JSON.stringify(cfg, null, 2)], { type: "application/json" }); + const url = URL.createObjectURL(blob); + const a = h("a", { href: url, download: "gateway-config.json" }); + document.body.appendChild(a); + a.click(); + a.remove(); + URL.revokeObjectURL(url); + } + const fileIn = h("input", { type: "file", accept: ".json,application/json", style: "display:none" }); + fileIn.addEventListener("change", async () => { + const f = fileIn.files[0]; + if (!f) return; + try { + const cfg = JSON.parse(await f.text()); + await api.putConfig(cfg); + toast(t("toast.imported"), "good"); + } catch (e) { + toast(String(e.message || e), "bad"); + } + fileIn.value = ""; + }); + + mount( + root, + h( + "div", + { class: "page-head" }, + h( + "div", + { class: "flex" }, + h("div", { class: "grow" }, h("h2", {}, t("settings.title")), h("p", {}, t("settings.subtitle"))), + saveBtn + ) + ), + h( + "div", + { class: "grid cols-2" }, + h( + "div", + { class: "card" }, + h("div", { class: "card-head" }, h("h3", {}, t("settings.router"))), + field(t("settings.router.url"), rUrl), + field(t("settings.router.keyEnv"), rKeyEnv), + h("div", { class: "row" }, field(t("settings.router.timeout"), rTimeout), field(t("settings.router.taxonomy"), rTax)), + rVerify.node + ), + h( + "div", + { class: "card" }, + h("div", { class: "card-head" }, h("h3", {}, t("settings.route"))), + field(t("settings.route.strategy"), strategySel), + h("div", { class: "row" }, field(t("settings.route.maxChars"), maxChars), field(t("settings.route.cacheTtl"), cacheTtl)), + field(t("settings.route.profile"), profileSel) + ), + h( + "div", + { class: "card" }, + h("div", { class: "card-head" }, h("h3", {}, t("settings.breaker"))), + h("div", { class: "row" }, field(t("settings.breaker.threshold"), brThresh), field(t("settings.breaker.cooldown"), brCool)) + ), + h( + "div", + { class: "card" }, + h("div", { class: "card-head" }, h("h3", {}, t("settings.log"))), + field(t("settings.log.level"), logSel), + logBodies.node + ), + h( + "div", + { class: "card" }, + h("div", { class: "card-head" }, h("h3", {}, t("settings.telemetry"))), + metricsCb.node, + h("div", { class: "divider" }), + h("div", { class: "card-head" }, h("h3", {}, t("settings.cortiq"))), + echoCb.node + ), + h( + "div", + { class: "card" }, + h("div", { class: "card-head" }, h("h3", {}, t("settings.stats"))), + statsEnabled.node, + field(t("settings.stats.file"), statsFile), + field(t("settings.stats.retention"), statsRet) + ) + ), + h( + "div", + { class: "card" }, + h("div", { class: "card-head" }, h("h3", {}, t("settings.listen"))), + field(t("settings.listen"), listenIn), + h("div", { class: "divider" }), + h( + "div", + { class: "flex wrap" }, + h("button", { class: "btn", onClick: exportConfig }, t("settings.export")), + h("button", { class: "btn", onClick: () => fileIn.click() }, t("settings.import")), + fileIn + ) + ) + ); + return root; +}