Add usage commands, a vendor-neutral usage format and a knowledge base

This commit is contained in:
Ian Gulliver
2026-10-19 15:08:57 -07:00
parent 912225cbd1
commit 8a395d4d6e
17 changed files with 1010 additions and 403 deletions
+58 -2
View File
@@ -1045,6 +1045,31 @@ paths:
application/json:
schema: { $ref: "#/components/schemas/Status" }
/api/admin/usage-commands:
get:
operationId: getUsageCommands
responses:
"200":
description: Each vendor's usage command.
content:
application/json:
schema: { $ref: "#/components/schemas/UsageCommands" }
put:
operationId: updateUsageCommands
description: Sets each vendor's usage command and reads every vendor's usage again.
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/UsageCommands" }
responses:
"200":
description: The saved commands.
content:
application/json:
schema: { $ref: "#/components/schemas/UsageCommands" }
"400": { $ref: "#/components/responses/Error" }
/api/admin/permissions:
post:
operationId: checkPermissions
@@ -1823,8 +1848,8 @@ components:
items: { $ref: "#/components/schemas/TurnRef" }
rate_limits:
type: object
description: The latest rate-limit status each vendor reported, keyed by vendor.
additionalProperties: { type: object }
description: Each vendor's latest usage, keyed by vendor, from its usage command or, without one, what the vendor itself reported.
additionalProperties: { $ref: "#/components/schemas/Usage" }
started_at: { type: string, format: date-time }
db_bytes: { type: integer, format: int64 }
last_event_seq: { type: integer, format: int64 }
@@ -1836,6 +1861,37 @@ components:
description: Each running app that holds its /api/clients/connect WebSocket, oldest connection first.
items: { $ref: "#/components/schemas/ConnectedClient" }
Usage:
type: object
required: [updated_at, windows]
properties:
updated_at: { type: string, format: date-time, description: When the numbers were current. }
rejected: { type: string, description: "Why the vendor is refusing work, such as a usage cap or depleted credits; absent while it isn't. A window at its limit also counts as rejected." }
windows:
type: array
description: Independent meters, in the order to show them.
items: { $ref: "#/components/schemas/UsageWindow" }
UsageWindow:
type: object
required: [label, used, unit]
properties:
label: { type: string, description: Short name for the meter. }
used: { type: number, format: double, description: Amount used, in unit. }
limit: { type: number, format: double, description: The window's limit, in unit; absent for a bare count. }
unit: { type: string, description: "usd, tokens, requests or percent; selects formatting." }
resets_at: { type: string, format: date-time, description: When the meter resets. }
window_seconds: { type: integer, format: int64, description: The window's length, when known, for the pace bar. }
UsageCommands:
type: object
description: The shell command that reports each vendor's usage, keyed by vendor; empty uses what the vendor itself reports.
required: [claude, codex, antigravity]
properties:
claude: { type: string }
codex: { type: string }
antigravity: { type: string }
ConnectedClient:
type: object
required: [id, login, host, commit, connected_at]