Skip to content

Releases: kimnt93/gorouter

v0.2.6

Choose a tag to compare

@kimnt93 kimnt93 released this 09 Oct 06:40

Full Changelog: v0.2.4...v0.2.6

v0.2.5

Choose a tag to compare

@kimnt93 kimnt93 released this 24 Sep 03:08
  • update router ring loop
  • add select account to apply (use account)

Full Changelog: v0.2.4...v0.2.5

v0.2.4

Choose a tag to compare

@kimnt93 kimnt93 released this 23 Sep 06:52

Full Changelog: v0.2.3...v0.2.4

v0.2.3

Choose a tag to compare

@kimnt93 kimnt93 released this 17 Sep 07:24

Changes

  • OAuth maintenance for idle connected accounts now coordinates token refresh
    across replicas (Redis) or locally and shares a lock with request-time
    refresh. Grok Build has a weekly credit usage bar.
  • Added an imported-key Windsurf / Devin Desktop connection with a logo,
    mock-tested native chat/stream translation. It is neither Devin CLI (ACP)
    nor browser OAuth; no background token renewal is promised for imported keys.
  • Added a master-only Updates dashboard page and
    GET /admin/updates/check. Checking is explicit and reads GitHub's latest
    release metadata; released GHCR builds embed their version. The router
    does not control the Docker daemon or replace containers: operators
    pull a pinned image and recreate their existing deployment without dropping
    volumes. GitHub release metadata can appear before the GHCR image is ready.

Full Changelog: v0.2.2...v0.2.3

v0.2.2

Choose a tag to compare

@kimnt93 kimnt93 released this 14 Sep 11:22

GoRouter v0.2.2 — Accounting reports and canonical-key reads

Status: development preview (0.2.2-dev), not a completed accounting release.
Date: 2026-09-14. These notes cover the implemented read-side changes since
v0.2.1. The broader accounting v0.2.2 requirements remain partially implemented;
see remaining gates and design decisions.

The runtime capability endpoint identifies this source as 0.2.2-dev. No v0.2.2
tag, GitHub release, published image or deployment is implied by these notes.
Do not infer accounting guarantees from the version string alone.

Added

  • GET /admin/capabilities: selected backend and explicit accounting/query
    capability flags, with no secrets or request content.
  • GET /admin/usage/report: combined totals, independent agent/model/user
    grouping, and hour/day/week/month series from one bounded SQL aggregate.
    Authorization and filtering occur before aggregation. Query count does not
    grow with the number of selected agents.
  • GET /admin/usage/summary?breakdown=none: one totals aggregate, preserving the
    existing response fields with empty by_model and by_key objects. Omitted
    breakdown retains the v0.2.1 default breakdowns.
  • GET /admin/users/{id}/api-key: canonical-key metadata for the owner or
    unrestricted master with keys:manage. Returns key_id, owner_id,
    enabled, scopes and an opaque public-metadata revision. No plaintext,
    hash, ciphertext or key prefix is returned. Organization administration does
    not authorize inspection of another user's personal key.
  • Dashboard Analysis → Accounting report: searchable multi-agent selection,
    manual stable/deleted agent IDs, conversation filtering, agent/model/user
    stacked charts and grouped totals. Legacy activity/health is a separate mode.
  • Typed Go/TypeScript contracts, generated Swagger, and a checked-in
    synthetic report fixture.

Changed

  • Canonical authentication delegates selection to backend queries instead of
    materializing every user's keys in the service. Selection still includes
    disabled keys and prefers personal context, then creation time and ID.
    PostgreSQL and SQLite have targeted lookup indexes. ClickHouse currently uses
    server-side filtering over current configuration records with FINAL; its
    physical lookup optimization remains outstanding.
  • SQLite recent/detail/report/summary/weekly queries no longer call the
    ledger-wide all() loader. Statistics do not fetch encrypted content.
    Legacy health/activity computations read SQL-filtered metadata only.
  • SQLite timestamp ordering uses fixed-width UTC sort values, preserving
    nanoseconds and avoiding variable-length RFC3339 fractional ordering errors.
  • Multi-select query values are normalized, deduplicated and sorted. Existing
    OR-within/AND-between semantics and the 100-value selection bound remain.

Usage

Use the same canonical user key used for inference. Agent, conversation, run,
parent-run, trace and client-request IDs remain correlation—not authentication,
not a payer selector, and not inference idempotency. Supply tracking headers on
Chat Completions, Responses or Messages as documented in
usage tracking. Metadata tracking does not require content
capture; leave ENABLE_STORE_COMPLETIONS=false unless explicitly needed.

The examples below are read-only. Authenticate with a Router user key carrying
usage:read (or an authorized management session); the metadata endpoint also
requires keys:manage. Organization-wide reports require authorized organization
administration. An ordinary member's organization report stays self-scoped.
The same schemas are available through /docs.

1. Check capabilities before using accounting APIs

GET /admin/capabilities

For the complete production repository wiring in this development preview:

{
  "version": "0.2.2-dev",
  "capabilities": {
    "usage_report": "gorouter-usage-report-v1",
    "user_weekly_usage": "gorouter-user-usage-v1",
    "totals_only": true,
    "canonical_key_metadata": true,
    "durable_acceptance": false,
    "usage_receipts": false,
    "member_allocations": false,
    "atomic_credit_counters": false
  }
}

This fragment omits the actual response's backend and measurement fields.
Require the individual features your application needs. In particular, a report
capability is not evidence that durable receipts or admission counters exist.

2. Read lightweight conversation totals

GET /admin/usage/summary?range=all&agent_id=client-a/alpha&conversation_id=conv_1&breakdown=none

This retains legacy completion-time semantics and all-authorized selection.
For explicit personal scope and accounting-time semantics, use the new report:

GET /admin/usage/report?scope=personal&range=30d&agent_id=client-a/alpha&conversation_id=conv_1

3. Query multiple agents and a stacked chart together

GET /admin/usage/report?scope=all_owned&range=30d&agent_id=client-a/alpha,client-a/beta&group_by=agent&series_by=agent&bucket=day

all_owned includes only the caller's own personal and sponsored activity. Use
personal to exclude organization-charged activity. Repeating agent_id is
also supported. Omitted selections mean all authorized values; unknown or
foreign matching filters cannot broaden access. Use stable client-namespaced
IDs to avoid collisions between applications using the same user key.

4. Inspect organization-charged usage by member

GET /admin/usage/report?scope=organization&organization_id=org_1&range=30d&group_by=user&series_by=user&bucket=day

Only the selected organization's charged events are visible to its admin, not
members' unrelated personal usage or credentials. Existing View As context
continues to narrow authority.

5. Set exact UTC bounds or inspect canonical-key metadata

GET /admin/usage/report?scope=personal&since=2026-09-01T00:00:00Z&until=2026-09-03T00:00:00Z&time_basis=accounting&group_by=model&series_by=model&bucket=day
GET /admin/users/usr_1/api-key

Report bounds are half-open [since, until). Explicit bounds replace the
corresponding preset bounds. The default is range=24h and
time_basis=accounting; completion is available explicitly. Weeks use UTC
WEEK_START; months use calendar boundaries, not folded weekly buckets.
The key metadata revision fingerprints the returned public fields; it is not
an authentication watermark and need not change when only the secret rotates.

Interpret cost and coverage correctly

  • Report token totals add four disjoint components:
    input_tokens + cache_read_tokens + cache_write_tokens + output_tokens.
    Reasoning subsets are not added again.
  • Provider cache-read ratio is
    cache_read_tokens / (input_tokens + cache_read_tokens); zero denominator
    means undefined. Router response-cache hits are separate. Replayed token
    metadata is excluded from new report incurred-token totals, while legacy
    summary behavior remains compatible.
  • Missing prices retain the existing Free/zero policy. Stored cost is
    historical Router-priced USD, not a provider invoice; old events are not
    repriced by the report.
  • Reports currently say coverage.state=unknown and
    freshness.state=stored_only. as_of is query observation time, not a durable
    acceptance watermark. Unknown measurement is counted explicitly. Empty or
    zero-shaped results do not prove that all inference was free or settled.
  • Reports are uncached and must not be used as reservation authority. A report
    GET followed by inference is not an atomic credit check.

Report limits: five × 366 days, 100 groups and series IDs, 2,000 time buckets,
20,000 joint aggregate/potential series cells and 16 MiB encoded output. Limit
violations return 400 usage_report_limit; service failures return 503
usage_unavailable. No rows are silently truncated. Narrow the query rather
than treating errors as zero.

See the full report usage contract for details.

Upgrade and rollback

Exactly one durable backend remains selected per process; no dual-write or
fallback store is introduced.

Backend Additive migration Operational impact
PostgreSQL 0031_canonical_key_lookup.sql Canonical owner/order index; existing transactional runner, not concurrent index creation. Plan a write-lock window proportional to key count.
SQLite 004_usage_read_projections.sql Virtual hot fields, fixed-precision time projections and three indexes. Index creation scans retained records; JSON and content remain intact.
ClickHouse None for this read slice Existing schema supports reporting; time-first usage and FINAL configuration reads remain.

Do not rewrite applied migrations. PostgreSQL's duplicate-0023 repair remains
in 0028; history, money, IDs and correlation are retained without guessed
owner backfills. SQLite's projections assume existing Go-written UTC records;
validate/normalize foreign offset-formatted imports before cutover.

Back up the selected store and schedule normal startup migrations through the
owner's upgrade workflow. Large-scale migration duration, index size and write
cost are not measured. v0.2.1 rollback can leave the additive columns/indexes
installed; first disable consumer use of the new endpoints. No production
migration or deployment was performed for this source change.

Verification and known limitations

  • Shared populated contracts ran against real disposable PostgreSQL 17,
    ClickHouse 25.8 + Redis 7.4, and file/WAL SQLite.
  • Live-enabled Go suite: 675 tests/subtests passed with two explicitly
    excluded baseline failures, both also re...
Read more

v0.2.1

Choose a tag to compare

@kimnt93 kimnt93 released this 14 Sep 08:32

GoRouter v0.2.1 — User access, organization models and tracking

User-first aliases and assignment limits (final contract)

  • One canonical key per user; agent IDs are request correlation, not principals.
  • One-to-one unique aliases: org/<org>/<alias> and <username>/<alias>.
  • A personal alias replaces its source in listings; both remain callable by the
    owner. Recipients can call only their assigned public aliases.
  • Groups are bulk-assignment packages only: no group entries in /v1/models,
    no group inference route and no shared group spending limit.
  • Per-recipient, per-model weekly limits: 0 = unlimited (default).
    Different users can have different limits on the same model.
  • Recipients may add a separate personal cap, never override their assigner's cap.
  • Org admins and personal model owners can grant/revoke access without creating
    additional user keys. Dashboard includes organization assignment packages,
    personal aliases/sharing and self-limit controls.
  • Serialized alias/source uniqueness and durable assignment budget reservations
    across PostgreSQL, ClickHouse/Redis and local SQLite.

See user model access and REST examples. The earlier
callable-group draft was replaced before deployment to the target server.

Added

  • X-GoRouter-Trace-Id → persisted trace_id on inference usage records.
  • Query filters for parent run and trace IDs, alongside agent, user, logical
    request, run, and session/conversation IDs.
  • CSV and repeated-parameter multi-selection with OR within each filter and AND
    across filters; omitted selections mean all authorized values.
  • Tracking headers documented in Swagger for Chat Completions, Responses, and
    Messages, streaming and non-streaming.
  • X-GoRouter-Request-Id response header exposes the accepted/generated logical
    request ID. Missing trace/run/conversation IDs are not fabricated.
  • Integration guide: Usage tracking API.

Fixed

  • PostgreSQL workload migration could be skipped because two migrations used
    version 0023. A later idempotent repair migration installs missing columns.
  • PostgreSQL's empty/nil agent-filter predicate could exclude records; batch
    agent filters could select unbound records. All backends now share filter
    semantics with independent authorization constraints.
  • ClickHouse usage cursor comparisons now preserve subsecond precision, avoiding
    skipped records at tied timestamps.
  • Trace and existing attribution metadata are returned consistently by usage
    list/detail paths, including PostgreSQL legacy recent helpers.
  • Workload-bound keys cannot broaden queries to other workload namespaces.
    Organization and user View As context constrain aggregation and detail reads.
  • Tracking header strings are owned by the request's accounting state so Fiber
    buffer reuse cannot corrupt delayed streaming/queued records.

Upgrade

Apply new migrations through the normal selected-backend startup process:
PostgreSQL 0028/0029; ClickHouse 009. SQLite stores trace IDs in its existing
JSON ledger payload and requires no new column. No extra tracking flag or
prompt/completion capture is required. Existing API paths and weekly capability
marker stay compatible; see the guide for exact defaults and query examples.

Scope and limitations

This release adds tracking and filtering, not an exactly-once accounting engine
or strict agent budgets. Existing persistence/in-flight/failed-attempt accounting
limitations remain; a successful chat is not a durable accounting receipt.
The weekly endpoint now uses user/org authority; general authorized multi-agent
queries also use summary, activity, and recent APIs.

Verification and delivery

  • go test ./... and go vet ./...: passed.
  • Race tests: handlers, usage service, entities, SQLite repositories passed.
  • Shared tracking/query contract and full repository suites passed against
    disposable PostgreSQL 17, ClickHouse 25.8, and real temporary SQLite.
    No tests were skipped in the targeted PostgreSQL/ClickHouse repository runs.
  • Inference tests cover all three protocol endpoints, stream/non-stream, bound
    and unbound callers, cache hits, retries, failed streams, header isolation,
    generated IDs, invalid IDs, and unchanged authenticated agent/user identity.
  • Filter tests cover OR/AND selection, omitted filters, all seven requested
    dimensions, user/organization/workload isolation, weekly filters and outage,
    half-open windows, tied/subsecond cursor timestamps, and legacy metadata.
  • Frontend tests: 15 files, 50 tests passed; embedded SPA regenerated.
  • Swagger generation/drift and git diff --check: passed.

No production migration, real-provider quota, multi-replica HA test, release
publication, push, or deployment is included in this source change. The two
isolated test database containers were removed after verification; existing
application/database containers and their volumes were not modified.

Continued v0.2.1 user-model verification

  • User-first personal/group inference, grants/revocation, duplicate-key rejection,
    per-agent correlation, and no agent-ID quota bypass: unit/integration tested.
  • Concurrent budget and primary-key contracts: SQLite/PostgreSQL/ClickHouse.
  • Two ClickHouse repository instances sharing real Redis: serialized admission
    and Redis outage fail-closed behavior tested.
  • Desktop Chrome 1440×900: organization models/limits modal, displayed shared and
    per-user limits, revocation request, no horizontal overflow or JS errors.
  • Frontend: 17 files / 52 tests. Go/vet/race and Swagger checks run for this update.

Final one-to-one alias clarification — verification

  • /v1/models lists assigned aliases and unrenamed personal sources, never
    package names. Own raw and aliased names both work; grantees cannot use raw
    private sources or republish received aliases.
  • All three inference protocols tested streaming/non-streaming with assignment
    limits, zero/unlimited, self caps, revocation, and agent-ID changes.
  • Shared backend tests cover concurrent alias/source uniqueness, globally
    conflicting public names, separate user budgets, and adding a limit after
    unlimited spend. PostgreSQL, ClickHouse and SQLite suites passed.
  • Final frontend: 17 test files, 52 tests; regenerated SPA and Swagger.
  • Desktop browser smoke verified the assignment-package display and revoke API.

Full Changelog: v0.2.0...v0.2.1

v0.2.0

Choose a tag to compare

@kimnt93 kimnt93 released this 10 Sep 12:52

GoRouter v0.2.0 — Authoritative workload usage accounting

Overview

Adds application-neutral, authoritative Router accounting for services, agents,
workspaces, automation workers, and other workloads. GoRouter records request,
token, cache, cost, owner, workload, conversation, run, and provider-attempt
attribution without requiring prompt or completion storage.

Highlights

  • Immutable API-key workload binding with application, optional environment,
    workspace, and agent identities.

  • Dedicated request correlation headers for conversation, run, parent run, and
    logical request IDs.

  • New authoritative current-week endpoint:

    GET /admin/usage/workloads/weekly
  • Capability marker: gorouter-workload-usage-v1.

  • Weekly windows follow configured WEEK_START and use an exclusive period end.

  • Separate accounting for input, output, provider cache-read, provider
    cache-write, and GoRouter response-cache use.

  • Synchronous durable handoff and idempotent persistence for workload-bound
    accounting events.

  • Workload, agent, conversation, run, provider, credential, and logical-request
    filters on usage queries.

  • PostgreSQL, ClickHouse, and SQLite schema support.

  • General integration reference: docs/workload-usage-contract.md.

Compatibility and security

  • Existing unbound API keys remain compatible and explicitly unattributed.
  • Inference callers cannot assign or mutate their workload authority.
  • Rotation retains workload identity and deletion does not remove history.
  • Existing user and organization authorization applies before aggregation.
  • No keys, tokens, prompts, completions, or raw upstream failures are exposed.

Limitations

  • Weekly usage is suitable for soft admission decisions, not strict concurrent
    per-workload budget enforcement.
  • Provider invoice totals can remain unknown when an upstream does not report
    usage after failure.
  • Legacy unbound records retain the existing asynchronous queue behavior.
  • Live PostgreSQL/ClickHouse and multi-replica HA suites require configured test
    environments and were not executed for the source implementation.

Verification

  • go test ./... passed.
  • go vet ./... passed.
  • Frontend tests passed: 15 files, 49 tests.
  • Frontend build passed.
  • Swagger generation/drift and git diff --check passed.

Upgrade notes

  • Run the new workload-usage migrations before enabling workload-bound keys.
  • Update clients from the earlier draft /admin/usage/agents/weekly route to
    /admin/usage/workloads/weekly.
  • Negotiate the final gorouter-workload-usage-v1 capability marker.
  • Existing unbound keys require no migration and continue to work normally.

Delivery status

  • Target release: v0.2.0.
  • Source implementation: complete.
  • Unit and SQLite integration coverage: complete.
  • Release publication and deployment: pending.

Full Changelog: v0.1.1...v0.2.0

v0.1.1

Choose a tag to compare

@kimnt93 kimnt93 released this 10 Sep 10:13

Full Changelog: v0.1.0...v0.1.1

v0.1.0

Choose a tag to compare

@kimnt93 kimnt93 released this 08 Sep 08:42

Full Changelog: v0.0.22...v0.1.0

v0.0.22

Choose a tag to compare

@kimnt93 kimnt93 released this 08 Sep 06:57

v0.0.22 — Stream routing reliability

  • Prevent transient accepted-stream failures from banning all Codex credentials.
  • Continue advancing the distributed account checkpoint after a failed partial stream.
  • Retry failures that happen before output using the configured per-account retry budget.
  • Avoid replaying requests after output or tool activity has reached the client.
  • Fix intermittent 503 no healthy credentials available errors after repeated stream failures.

Full Changelog: v0.0.21...v0.0.22