From 209c9e7fbbc1f6ca1d05b030562bcf5477ad9df0 Mon Sep 17 00:00:00 2001 From: Yurii Kostiuk Date: Sat, 26 Sep 2026 22:27:27 +0100 Subject: [PATCH] chore(release): prepare TokenFuse v1.2.0 Co-Authored-By: Claude Opus 5.5 --- Cargo.lock | 2 +- crates/tokenfuse/Cargo.toml | 2 +- docs/releases/v1.2.0.md | 51 +++++++++++++++++++++++++++++++++++++ sdk/js/package.json | 2 +- sdk/python/pyproject.toml | 2 +- 5 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 docs/releases/v1.2.0.md diff --git a/Cargo.lock b/Cargo.lock index d581411..b4ffabf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5696,7 +5696,7 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokenfuse" -version = "1.1.1" +version = "1.2.0" [[package]] name = "tokenfuse-cloud" diff --git a/crates/tokenfuse/Cargo.toml b/crates/tokenfuse/Cargo.toml index 0c15f30..411c5a7 100644 --- a/crates/tokenfuse/Cargo.toml +++ b/crates/tokenfuse/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tokenfuse" -version = "1.1.1" +version = "1.2.0" edition.workspace = true license.workspace = true repository.workspace = true diff --git a/docs/releases/v1.2.0.md b/docs/releases/v1.2.0.md new file mode 100644 index 0000000..2de2762 --- /dev/null +++ b/docs/releases/v1.2.0.md @@ -0,0 +1,51 @@ +# TokenFuse 1.2.0 + +This release lets one Cloud serve gateways at several sites and tell them +apart. Until now a record pushed to `/v1/ingest` carried no gateway identity, +so two sites' spend mixed into one pile and a site that stopped pushing was +invisible (#296). The Cloud now names the site from the key the gateway +pushed with, never from anything in the request, and a site's key no longer +has to be an org admin key. The gateway binary does not change. The frozen +names in `compat/1.0.json` do not change; this release adds names, which is +why it is a minor. The umbrella crate and both client SDKs move to 1.2.0 with +no client behavior change. + +## Added + +- **A key can be bound to a site (#333, invariant 65).** The Cloud key spec + grows an optional fourth segment: `key:org[:role[:site]]`. Every record a + bound key pushes is attributed to that site by the Cloud itself; an unbound + key's records land under `unnamed`. A site name is lowercase letters, + digits, `.`, `_` and `-`, starting with a letter or digit, at most 63 + characters; an entry with an invalid site authenticates nobody. +- **A narrower role for a site: `ingest`.** An `ingest` key may push + telemetry and read (including the four polls a gateway makes: units, + budgets, unit budgets, kills), and is refused with 403 on every other + mutation (kill, budgets, unit budgets, incident ack, findings, pairing). + The recommended form for a site's key is `secret:org:ingest:site-name`. + Until now pushing telemetry needed an `admin` key, which can also kill + runs and set budgets for the whole organization. +- **`GET /v1/gateways`**: per site, spend, calls, tool calls, number of + pushes, first push and last push. `last_push_millis` is the Cloud's own + clock, so a gateway's clock cannot make a quiet site look alive; an empty + push counts as a heartbeat. Runs carry the site they were pushed from + (`RunAgg.site`). +- **Dashboard**: a Gateways card (site, spend, last push, a "silent" label + after five minutes without a push) and a Site column on Runs. + +## Upgrade + +Nothing to change for a single-site deployment: an existing key keeps +working exactly as before and its gateway appears as `unnamed`. To name a +site, give its gateway a key of the form `secret:org:ingest:site-name` in +`TOKENFUSE_CLOUD_KEYS` and set that secret as the gateway's +`TOKENFUSE_CLOUD_KEY`. The Cloud's snapshot gains a `gateways` field; an older +snapshot loads with no sites and fills from the next push. + +## Not in this release, said plainly + +- A site that goes silent is visible on `/v1/gateways` and on the dashboard, + and raises no incident or agent-event yet. +- A stolen site key can still push as that site: the key names the site, the + gateway process is not authenticated cryptographically. +- Many sites pushing concurrently under load was not measured. diff --git a/sdk/js/package.json b/sdk/js/package.json index 37ca036..17d81db 100644 --- a/sdk/js/package.json +++ b/sdk/js/package.json @@ -1,6 +1,6 @@ { "name": "tokenfuse", - "version": "1.1.1", + "version": "1.2.0", "description": "JavaScript/TypeScript client helpers for TokenFuse — runtime cost control for AI agents.", "keywords": ["llm", "agents", "finops", "budget", "tokenfuse"], "license": "Apache-2.0", diff --git a/sdk/python/pyproject.toml b/sdk/python/pyproject.toml index 6ec5e8a..cd37ceb 100644 --- a/sdk/python/pyproject.toml +++ b/sdk/python/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "tokenfuse-sdk" -version = "1.1.1" +version = "1.2.0" description = "Python SDK for TokenFuse — runtime cost control for AI agents (import as `tokenfuse`)." readme = "README.md" requires-python = ">=3.9"