Skip to content

feat(api): return every connection's snapshot under providers[] in om-usage json - #11192

Merged
diegosouzapw merged 3 commits into
release/v3.8.50from
feat/usage-command-json-array
Aug 23, 2026
Merged

diegosouzapw merged 3 commits into
release/v3.8.50from
feat/usage-command-json-array

Conversation

@diegosouzapw

Copy link
Copy Markdown
Owner

Closes #11191. Stacked on #11190 (the ?format=json base) — merge that one first, then retarget
this to release/v3.8.50.

Gap

buildUsageCommandJson returned a single provider snapshot via selectUsageSnapshot — fine for
a terminal, wrong for a panel. A tenant with Codex + Claude + OpenCode connections saw one of
them, which is the "Codex and Claude are not visible" half of OmniCopilot #8.

Change

The collector already gathered every connection's snapshot; the single-pick was a presentation
choice. The JSON form now returns the full UsageSnapshot[] under providers[] alongside the
selected provider (kept for terminal compatibility). Text form untouched.

Tests

usage-command-json-format.test.ts gains a two-connection case: providers[] carries both
claude and codex, provider stays one of them. 5/5.

⚠️ base-red inherited: #9985

GET /api/usage/om-usage already let any key read its own usage — personal
daily/weekly USD limits and the provider quota snapshot — but only as
text/plain, which a UI cannot parse safely. OmniCopilot issue #8 asks exactly
for this surface.

Adds ?format=json, returning the ApiKeyUsageLimitStatus + UsageSnapshot the
text is rendered from. Text and JSON share the same collectors
(collectUsageSnapshots, getApiKeyUsageLimitStatus), so the two can never
disagree about a number. The response is a discriminated union: a key without
allowUsageCommand (403) or an invalid key (401) returns
{ allowed:false, error:{message} }, distinct from allowed:true with empty
sections — the state a panel must render as "nothing learned yet", not a
refusal. Text form unchanged; without ?format the contract is untouched.

The endpoint was previously missing from API_REFERENCE.md; it now has a
section documenting both forms, the allowUsageCommand gate, and the
self-service auth model (caller's own key, not requireManagementAuth).

Regression guards in tests/unit/usage-command-json-format.test.ts (4 tests:
json shape, text default preserved, structured 403, sanitized 401 with no
stack trace). Existing internal-usage-command suite still 12/12.
…-usage json

Closes #11191. buildUsageCommandJson picked a single snapshot via selectUsageSnapshot, so a panel could only ever show one provider. The collector already had them all — the single-pick is a presentation choice for a terminal. The JSON form now also returns the full UsageSnapshot[] alongside the selected provider, so a UI can render Codex / Claude / OpenCode side by side. The text form is untouched.
@diegosouzapw
diegosouzapw force-pushed the feat/usage-command-json-array branch from febeaa6 to 9b8d9db Compare August 23, 2026 01:24
@diegosouzapw
diegosouzapw merged commit 3ef54fc into release/v3.8.50 Aug 23, 2026
16 of 22 checks passed
@diegosouzapw
diegosouzapw deleted the feat/usage-command-json-array branch August 23, 2026 01:41
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…-usage json (diegosouzapw#11192)

* feat(api): structured ?format=json for the self-service usage endpoint

GET /api/usage/om-usage already let any key read its own usage — personal
daily/weekly USD limits and the provider quota snapshot — but only as
text/plain, which a UI cannot parse safely. OmniCopilot issue diegosouzapw#8 asks exactly
for this surface.

Adds ?format=json, returning the ApiKeyUsageLimitStatus + UsageSnapshot the
text is rendered from. Text and JSON share the same collectors
(collectUsageSnapshots, getApiKeyUsageLimitStatus), so the two can never
disagree about a number. The response is a discriminated union: a key without
allowUsageCommand (403) or an invalid key (401) returns
{ allowed:false, error:{message} }, distinct from allowed:true with empty
sections — the state a panel must render as "nothing learned yet", not a
refusal. Text form unchanged; without ?format the contract is untouched.

The endpoint was previously missing from API_REFERENCE.md; it now has a
section documenting both forms, the allowUsageCommand gate, and the
self-service auth model (caller's own key, not requireManagementAuth).

Regression guards in tests/unit/usage-command-json-format.test.ts (4 tests:
json shape, text default preserved, structured 403, sanitized 401 with no
stack trace). Existing internal-usage-command suite still 12/12.

* chore(changelog): correct the fragment to the real PR number (diegosouzapw#11190)

* feat(api): return every connection's snapshot under providers[] in om-usage json

Closes diegosouzapw#11191. buildUsageCommandJson picked a single snapshot via selectUsageSnapshot, so a panel could only ever show one provider. The collector already had them all — the single-pick is a presentation choice for a terminal. The JSON form now also returns the full UsageSnapshot[] alongside the selected provider, so a UI can render Codex / Claude / OpenCode side by side. The text form is untouched.

---------

Co-authored-by: Xiangzhe <bakryun0718@proton.me>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(api): per-connection usage view for /api/usage/om-usage

2 participants