更新日志
Every user-visible change to Kaeso, including @logicplanes/kaeso-ui and @logicplanes/kaeso-tokens. Versions follow Semantic Versioning.
Unreleased
0.1.0 - 2026-10-16
The first release of Kaeso, the open-source AI gateway you run yourself: the gateway, KPP, the console, the UI library and the documentation, from one repository under one version.
Added
Model API
- OpenAI- and Anthropic-compatible endpoints under
/v1:chat/completions,responsesandresponses/input_tokens,embeddings,messagesandmessages/count_tokens, andmodelsandmodels/{id}in both formats, with streaming. Every request is translated through KPP, so each generation format reaches every chat model in the project's catalogue, whatever its provider. - OpenAI and Anthropic as providers, OpenAI through Responses by default; pooled HTTP clients with rustls and HTTP/2; connect, total, first-byte and stream-idle timeouts, with a per-model timeout for the total and first-byte limits; cancellation of the provider request when the app goes away.
- Errors in the app's own format, no retries and no passthrough;
kaeso-request-idon every response, andkaeso-modelandkaeso-provideronce the model is known, errors included. - Keepalive frames on long streams, readable reasoning across formats, and reasoning kept between tool calls for OpenAI Chat apps on other providers.
- Tool results nested more than four levels deep are refused with an error that says so, instead of being translated.
- Usage for streams that end early, estimated and marked as such, and honest outcomes for streams that fail after their headers were sent.
Catalogue, keys and limits
- A per-project model catalogue filled from a shipped models.dev snapshot, synced every 24 hours, with overrides, custom models, bulk adds and aliases.
- Provider keys owned by the organization: several per provider, one default, assignment to projects, envelope encryption with AES-256-GCM under a rotatable master key ring, write-only.
- API keys per project for members and service accounts, with expiry, inference and platform access, disabling and archiving; organization platform keys; expiry warnings.
- Model access and limits on projects, members and keys: request and token rates, token and spend budgets per day, month or in total, hard or soft, with alerts for budgets; counts up to 10^12 and spend budgets up to 1,000,000,000 USD.
- Hard budgets are never skipped: when a project's limits can't be loaded, the request is refused with 503, and budget counters that may be wrong after a failed update are dropped and rebuilt from PostgreSQL before the next request they limit.
- Exact decimal prices and amounts, which the Platform API accepts only as decimal strings or whole numbers, as documented; costs at the prices of request time; usage by day, week, month, model, key, member and project.
Request logs
- One metadata row per model request and, when the organization and project allow it, the request and the full reply in ClickHouse, batched and bounded; retention per organization; filters, export as JSON Lines or CSV in which cells that a spreadsheet would read as formulas are neutralised, deletion by time range and a storage overview.
Platform API
- Everything the console does, under
/platform/v1, described by a generated OpenAPI document: organizations, members, invitations, projects, service accounts, keys, provider keys, models, limits, usage, logs, the audit log, security settings and instance administration. - Fine-grained rights with built-in and custom roles (rights); every organization and project endpoint checks exactly one right, and a right is granted and removed together with the rights it needs.
- Revisions for catalogue models and limits:
ETagon reads and changes, andIf-Matchon changes and deletions, answered with 412 when the entry changed since, as the OpenAPI document declares. - A 503 that names the cause while PostgreSQL, ClickHouse or Valkey can't be reached, and normal answers again as soon as it is back, without a restart.
- One naming and one shape throughout: single sign-on is
ssoin instance settings and in the sign-in methods, and every list, the roles of an organization included, answers with the same envelope ofdata,has_moreandnext_cursor. - Audit logs for the instance, each organization and each project, and an export of the organization's log.
- Streamed Playground requests to a project's models as the signed-in member.
Accounts and sign-in
- First-start setup, email and password with TOTP and recovery codes, sign-in links, password resets, single sign-on through each organization's OIDC provider with email domains in Unicode or ASCII form, and sign-up by instance setting with allowed email domains.
- HttpOnly session cookies, session lists, recent sign-in for sensitive actions, required two-factor authentication and single sign-on per organization, and throttled sign-in attempts, each counted before it is checked and per /64 for IPv6 clients.
- Changing the password, resetting it or changing the email address retires older sign-in links, reset links and two-factor challenges; changing the password or two-factor authentication keeps the session's original sign-in time and method.
- Identity providers must use https; plain http is accepted only for providers on private addresses.
- Pictures of people, organizations and projects; the user's own account, language and notifications, email changes with confirmation, leaving an organization and deleting the account; ownership transfer of an organization.
- Instance administration: users (invite, deactivate, reset two-factor authentication, end sessions, make instance admin), organizations, settings, model sources with a manual sync, system status and the instance audit log; organization deletion with a grace period during which the organization stays readable.
- Emails for every account, security, organization and alert event, in English, German and Simplified Chinese.
Console
- The web console for a Kaeso install, built with React 19 and TanStack Router and Query, drawn only with
@logicplanes/kaeso-ui, and talking to the gateway through a client generated from the Platform API document. - First-run setup, sign-in with a password, a sign-in link, an authenticator code or single sign-on, sign-up where the install allows it, password resets and invitations.
- The organization overview with usage by project and the providers page; the project overview: requests, tokens, cost and errors over a period, charts by day, week or month, a breakdown by model, key or member, limits and recent errors.
- API keys with expiry, access, models and limits and their one-time reveal; the model catalogue with capabilities, prices, aliases and overrides; members, service accounts and roles with their rights; limits and budgets at every level. Edits to models and limits send their revision, and an edit that comes after someone else's says so and loads the current version.
- Request logs in a dense table with filters, a live mode, an inspector for each request and its content, and exports as JSON Lines or CSV.
- The Playground: one prompt to several models side by side, streamed, with their parameters.
- Settings for the account (profile, password and two-factor authentication, sessions, own API keys, memberships, notifications, appearance and language), the organization (general with deletion and restore, members with invitations and roles, security and single sign-on, platform keys, logging and retention, audit log) and the instance (users, organizations, settings, model sources, system status, audit log).
- The command palette and keyboard shortcuts throughout, and a toast while the gateway can't be reached.
- Every word in English, German and Simplified Chinese, following the account's language or the browser's; light and dark themes; phone and desktop layouts; a visible label and an accessible name for every control, a Skip to content link, and lists that work from the keyboard.
KPP
kaeso-kppon crates.io, for Rust 1.85 and later: canonical, stateless types for generation, token counting, embeddings and model listings, with messages of ordered blocks, tools, output formats, reasoning and sampling settings, usage with the provider's raw usage, andKppError; stream events with one block lifecycle; model listings paged the same way for every format; origin-boundExtras, raw unknown blocks and opaque reasoning, so data KPP does not model is kept and replayed only to its own format;validate()andrequired_capabilities(); a public API that can grow without breaking callers.kaeso-codecson crates.io, for Rust 1.88 and later: sans-IO codecs for Anthropic Messages (with token counting), OpenAI Chat Completions, OpenAI Responses (with input token counting) and OpenAI Embeddings, covering requests, responses, server-sent event streams, errors and model listings.- Lossless same-format round trips for every fixture, including exact spellings of
null, defaults and stream chunking. check()refuses everything a target cannot express with anUnsupportederror that names the feature, before anything is sent; errors for coding tools' pre-release fields say which setting to change.- Cross-format rules: a scoped allowlist of fields that may be dropped, origin-bound file ids and reasoning, reasoning settings mapped by a fixed effort and budget table, and reasoning that travels with the conversation and comes back to its provider unchanged.
- Each crate's README opens with an example that runs as a doctest and links to the reference at docs.kaeso.app.
dispatchselects every codec function by format at run time;sseparses and writes event streams incrementally;testingcompares JSON and event streams structurally for round-trip tests in other crates.
UI library
@logicplanes/kaeso-tokenson npm: every design value of Kaeso, from the pure white and pure black canvases, a tint-free grey ramp, status and chart colours and the type scale to sizes, radii, elevation, control material and motion; as CSS variables, a Tailwind CSS v4 theme in which only token values exist, TypeScript constants and JSON; with contrast tested for every text role, status colour and chart colour in both modes.@logicplanes/kaeso-uion npm: 73 component entry points on Base UI and Tailwind CSS v4, from the app frame, sidebar, buttons and inputs to menus, dialogs, tables, settings groups, code blocks, Markdown and a command palette, with popups, such as the sidebar menus and date pickers, that load their code in the background once the page is idle, so the first press opens them at once; charts drawn as React SVG; Kaeso's own composites for models, providers, keys, status codes and the Playground.- Keyboard access throughout: a Skip to content link in every app frame, dialogs that open on their first field or their safe action,
LayerDialogmoving focus into the layer it shows and Back returning it to the row or button that opened the layer (lower layers keep their state and scroll position, and ⌘/Ctrl+Enter keeps submitting), andListas a WAI-ARIA grid with one tab stop, where the arrows orjandkmove, Space orxselects, Shift extends, Enter opens and the right arrow reaches a row's actions. @logicplanes/kaeso-ui/i18nwith every library text in English, German and Simplified Chinese,@logicplanes/kaeso-ui/formatfor numbers, money, tokens and dates (compact token counts keep three significant digits in every language, and amounts too small to show read as less than the smallest one, such as "< $0.000001"), and@logicplanes/kaeso-ui/themefor light, dark and system themes without a flash on load.- Inter and Geist Mono included, one entry point per component, and rules for coding agents shipped in the package:
AGENTS.md, the design foundations and a generated registry of every component, prop and variant. - The showcase at ui.kaeso.app: every component with a live demo and its props, in light and dark, with every page built in English, German and Simplified Chinese at its own address.
Documentation
- docs.kaeso.app in English, German and Simplified Chinese: getting started, self-hosting, the console, the model API, the Platform API and errors, concepts such as the request flow, format translation and rights, and development of Kaeso itself.
- Pages are Markdown files with links between files checked at build time, GitHub's heading anchors and alerts, images from the pages' own folder, raw HTML kept as text, and only http, https and mailto links out.
- Search with ⌘K or Ctrl+K, the console's frame and themes, an HTML file per page and language with canonical addresses and alternates, a 404 page per language and a sitemap, for any static host.
- Bundle budgets of 216 kB for the frame and 24 kB for each page's content.
Self-hosting
- One binary,
kaeso:serve,migrate,master-key generateandrewrap,setup-link,user reset-2fa,healthcheck, which probes the configured listen address, andopenapi. - Configuration through
KAESO_*variables or a TOML file, with secrets from files, validated at startup (configuration):server.header_read_timeout(default 30s), which closes connections that are slow to send headers or sit idle, trusted proxies, limits on request bodies and on provider responses, a throttle on failed API key lookups per client address, and email over SMTP or only logged. - Several gateway instances behind one proxy, sharing PostgreSQL, ClickHouse and Valkey.
- One initial schema of nine PostgreSQL and two ClickHouse migrations, run at startup under a lock; migrations only move forward.
/healthz,/readyz, Prometheus metrics on a separate port, includingkaeso_usage_rows_dropped_totalfor usage rows PostgreSQL refuses for good, and structured JSON logs.- A graceful shutdown that finishes requests in progress, writes the last usage and request logs and sends queued emails.
- Non-root images for linux/amd64 and linux/arm64, with provenance and a software bill of materials:
ghcr.io/logicplanes/kaeso-gatewayon a distroless base, andghcr.io/logicplanes/kaeso-console, served by Caddy with a strict content security policy. - A one-file Docker Compose package with Caddy, PostgreSQL, ClickHouse and Valkey, attached to every release with an example configuration file (self-hosting). It asks for a password for each store,
POSTGRES_PASSWORD,POSTGRES_SUPERUSER_PASSWORD,CLICKHOUSE_PASSWORDandVALKEY_PASSWORD, and forKAESO_DOMAIN. - A hardened package: the gateway signs in to PostgreSQL as an application role that is not a superuser, ClickHouse's user can't manage users and grants, Valkey requires a password, containers can't gain privileges and run without Linux capabilities (Caddy keeps only the right to bind ports 80 and 443, the gateway has a read-only file system), third-party images are pinned by version and digest, and Caddy sends
Strict-Transport-Security.
Quality
- Unit and integration tests against real PostgreSQL, ClickHouse and Valkey, with line coverage gates for the gateway and KPP and coverage thresholds for the UI library, the tokens, the console and the documentation site.
- The official
openaiandanthropicPython SDKs against KPP's encoders, against the gateway with a mock provider built from KPP's fixtures, and against a fresh install of the Compose package. - A fixture corpus with provenance for every format, a cross-format golden matrix, property tests, fuzz targets for every decoder and benchmarks.
- Playwright suites for the console against a stack of its own, and for the documentation site and the showcase with accessibility checks in both themes.
- KPP's crates checked and tested with the oldest Rust version they declare, and the examples in their READMEs run as doctests.
- Dependency audits, MIT-compatible licences checked for every dependency and every shipped bundle, and a check that the code has no comments.
Release
- A Release workflow that runs only from
prod: it prepares the version changes and the changelog without write access to the repository, lets only jobs that run nothing but git push the release commit and the tag, syncs the release commit back todev, and pins every action by commit SHA.