docs: add budget override API reference and OpenAPI spec - #5736
Conversation
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe documentation adds virtual-key budget override concepts, API contracts, authenticated PUT and DELETE operations, lifecycle rules, validation behavior, reset-cycle handling, and governance UI guidance. ChangesVirtual-key budget overrides
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 oasdiff (1.26.0)docs/openapi/openapi.yamlError: failed to load base spec from "/tmp/coderabbit-oasdiff-base.Nh7U21": encountered disallowed external reference: "./paths/inference/async.yaml#/components/parameters/AsyncJobId" Comment |
Merge activity
|
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (1)
docs/features/governance/virtual-keys.mdx (1)
529-565: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider adding a cycles-mode response example.
The response example (Lines 552-565) reflects only the
forever-mode call. It omits the cycle-tracking fields acycles-mode grant would return, such asoverride_cycles_remainingandoverride_cycles_total. Add a short response example for thecyclescall (Lines 532-539) so readers see those fields without needing to open the API Reference.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/features/governance/virtual-keys.mdx` around lines 529 - 565, Add a concise JSON response example immediately after the cycles-mode curl request, showing the cycle grant response fields including override_mode set to cycles, override_cycles_remaining, and override_cycles_total. Keep the existing forever-mode request and response example unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/openapi/openapi.json`:
- Around line 82481-82505: Update BudgetOverrideRequest in
docs/openapi/schemas/management/governance.yaml with exclusiveMinimum: 0 for
amount and OpenAPI 3.1 conditional schemas requiring positive cycles for mode
"cycles" and omitted-or-zero cycles for mode "forever"; regenerate
docs/openapi/openapi.json at both listed ranges. Update Budget to represent
inactive mode as override_mode: "", require zero inactive override values while
omitting only override_anchor_reset, and enforce positive active amounts plus
valid finite-cycle fields; remove omitempty from inactive response fields when
needed to serialize their zero values.
- Around line 45035-45186: Update the bundled OpenAPI schemas
`BudgetOverrideRequest` and `Budget` to match the governance contract: require
`amount` to be strictly positive, enforce `cycles` validation conditionally when
the override mode is `cycles`, and include the inactive empty-string mode plus
the zero-value lifecycle state in `Budget`. Preserve the existing operation
definitions and references.
In `@docs/openapi/paths/management/governance.yaml`:
- Around line 268-320: Update BudgetOverrideRequest in both OpenAPI schema
sources to require a positive finite amount and enforce mode-dependent cycles:
cycles mode must use a positive count, while forever permits cycles 0; remove
the unconditional minimum that rejects this case. Update Budget to require
inactive override fields to be zero, omit the anchor when inactive, and enforce
override_cycles_total >= override_cycles_remaining, keeping the JSON definition
synchronized with the YAML schema.
In `@docs/openapi/schemas/management/governance.yaml`:
- Around line 33-55: The governance schema must document inactive overrides as
zero-valued rather than omitted, with an empty override mode and only
override_anchor_reset omitted. Update the property descriptions and enum/model
definitions around override_amount, override_mode, override_cycles_remaining,
and override_cycles_total, ensuring the inactive empty mode is accepted
consistently with config.schema.json while retaining the existing active-mode
values.
- Around line 167-183: Update BudgetOverrideRequest so amount uses
exclusiveMinimum: 0, and replace the global cycles minimum with mode-dependent
oneOf or if/then constraints: require cycles with minimum 1 for mode cycles,
while omitting cycles for mode forever. Apply the same schema changes to
docs/openapi/openapi.json.
---
Nitpick comments:
In `@docs/features/governance/virtual-keys.mdx`:
- Around line 529-565: Add a concise JSON response example immediately after the
cycles-mode curl request, showing the cycle grant response fields including
override_mode set to cycles, override_cycles_remaining, and
override_cycles_total. Keep the existing forever-mode request and response
example unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 722bf00a-35bb-4a89-9203-90d60645ca34
📒 Files selected for processing (6)
docs/features/governance/budget-and-limits.mdxdocs/features/governance/virtual-keys.mdxdocs/openapi/openapi.jsondocs/openapi/openapi.yamldocs/openapi/paths/management/governance.yamldocs/openapi/schemas/management/governance.yaml
| "/api/governance/virtual-keys/{vk_id}/budgets/{budget_id}/override": { | ||
| "put": { | ||
| "operationId": "updateVirtualKeyBudgetOverride", | ||
| "summary": "Set virtual key budget override", | ||
| "description": "Sets or replaces the spending override on one of a virtual key's budgets. The override is additive —\nwhile it is active the budget is enforced against `max_limit + override_amount` — and it leaves the\nbudget's base limit, current usage, and reset schedule untouched.\n\nUse `mode: cycles` with a `cycles` count to grant extra spend for a finite number of reset windows\n(the current window counts as the first), or `mode: forever` to keep the override until it is deleted.\nA finite grant is anchored to the budget's current reset window, so every node in a cluster derives the\nsame number of remaining cycles and a config reload cannot resurrect a spent one.\n", | ||
| "tags": [ | ||
| "Governance" | ||
| ], | ||
| "parameters": [ | ||
| { | ||
| "name": "vk_id", | ||
| "in": "path", | ||
| "required": true, | ||
| "description": "Virtual key ID", | ||
| "schema": { | ||
| "type": "string" | ||
| } | ||
| }, | ||
| { | ||
| "name": "budget_id", | ||
| "in": "path", | ||
| "required": true, | ||
| "description": "ID of a budget owned by the virtual key", | ||
| "schema": { | ||
| "type": "string" | ||
| } | ||
| } | ||
| ], | ||
| "requestBody": { | ||
| "required": true, | ||
| "content": { | ||
| "application/json": { | ||
| "schema": { | ||
| "$ref": "#/components/schemas/BudgetOverrideRequest" | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| "security": [ | ||
| { | ||
| "ManagementBearerAuth": [] | ||
| } | ||
| ], | ||
| "responses": { | ||
| "200": { | ||
| "description": "Budget override applied successfully", | ||
| "content": { | ||
| "application/json": { | ||
| "schema": { | ||
| "$ref": "#/components/schemas/BudgetOverrideResponse" | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| "400": { | ||
| "description": "Bad request", | ||
| "content": { | ||
| "application/json": { | ||
| "schema": { | ||
| "$ref": "#/components/schemas/BifrostError" | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| "404": { | ||
| "description": "Virtual key or budget not found", | ||
| "content": { | ||
| "application/json": { | ||
| "schema": { | ||
| "$ref": "#/components/schemas/BifrostError" | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| "500": { | ||
| "description": "Internal server error", | ||
| "content": { | ||
| "application/json": { | ||
| "schema": { | ||
| "$ref": "#/components/schemas/BifrostError" | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| "delete": { | ||
| "operationId": "deleteVirtualKeyBudgetOverride", | ||
| "summary": "Remove virtual key budget override", | ||
| "description": "Removes any active override from the budget, so it is enforced against its base `max_limit` again.\nThe budget's current usage and reset schedule are unchanged, and the removal is permanent — a cleared\ngrant cannot be re-derived. Safe to call on a budget that has no override.\n", | ||
| "tags": [ | ||
| "Governance" | ||
| ], | ||
| "parameters": [ | ||
| { | ||
| "name": "vk_id", | ||
| "in": "path", | ||
| "required": true, | ||
| "description": "Virtual key ID", | ||
| "schema": { | ||
| "type": "string" | ||
| } | ||
| }, | ||
| { | ||
| "name": "budget_id", | ||
| "in": "path", | ||
| "required": true, | ||
| "description": "ID of a budget owned by the virtual key", | ||
| "schema": { | ||
| "type": "string" | ||
| } | ||
| } | ||
| ], | ||
| "security": [ | ||
| { | ||
| "ManagementBearerAuth": [] | ||
| } | ||
| ], | ||
| "responses": { | ||
| "200": { | ||
| "description": "Budget override removed successfully", | ||
| "content": { | ||
| "application/json": { | ||
| "schema": { | ||
| "$ref": "#/components/schemas/BudgetOverrideResponse" | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| "404": { | ||
| "description": "Virtual key or budget not found", | ||
| "content": { | ||
| "application/json": { | ||
| "schema": { | ||
| "$ref": "#/components/schemas/BifrostError" | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| "500": { | ||
| "description": "Internal server error", | ||
| "content": { | ||
| "application/json": { | ||
| "schema": { | ||
| "$ref": "#/components/schemas/BifrostError" | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| }, |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
jq -e '
.paths["/api/governance/virtual-keys/{vk_id}/budgets/{budget_id}/override"]
| {put, delete}
' docs/openapi/openapi.json
jq -e '
.components.schemas
| {Budget, BudgetOverrideRequest, BudgetOverrideResponse}
' docs/openapi/openapi.json
rg -n -C 16 \
'virtual-keys/\{vk_id\}/budgets/\{budget_id\}/override|BudgetOverride(Request|Response)|override_(amount|mode|cycles_remaining|cycles_total|anchor_reset)' \
docs/openapi/openapi.yaml \
docs/openapi/paths/management/governance.yaml \
docs/openapi/schemas/management/governance.yamlRepository: maximhq/bifrost
Length of output: 33738
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- OpenAPI version ---'
sed -n '1,35p' docs/openapi/openapi.yaml
jq -r '.openapi // .swagger' docs/openapi/openapi.json
printf '%s\n' '--- Source path definition ---'
sed -n '268,362p' docs/openapi/paths/management/governance.yaml
printf '%s\n' '--- Source schema definitions ---'
sed -n '1,75p' docs/openapi/schemas/management/governance.yaml
sed -n '157,197p' docs/openapi/schemas/management/governance.yaml
printf '%s\n' '--- Bundled path and schemas ---'
jq '.paths["/api/governance/virtual-keys/{vk_id}/budgets/{budget_id}/override"]' docs/openapi/openapi.json
jq '.components.schemas.Budget, .components.schemas.BudgetOverrideRequest, .components.schemas.BudgetOverrideResponse' docs/openapi/openapi.jsonRepository: maximhq/bifrost
Length of output: 17692
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- Governance budget override contract ---'
rg -n -C 12 \
'override_(amount|mode|cycles_remaining|cycles_total|anchor_reset)|BudgetOverride|budget override|mode.*empty|empty.*mode' \
transports/config.schema.json \
--glob '!docs/openapi/openapi.json'
printf '%s\n' '--- Implementation references ---'
rg -n -C 10 \
'override_(amount|mode|cycles_remaining|cycles_total|anchor_reset)|BudgetOverride(Request|Response)|updateVirtualKeyBudgetOverride|deleteVirtualKeyBudgetOverride' \
--glob '!node_modules' \
--glob '!dist' \
--glob '!build' \
--glob '!docs/openapi/openapi.json' \
.
printf '%s\n' '--- Governance documentation navigation ---'
rg -n -C 8 \
'governance|openapi/openapi.json|API Reference' \
docs/docs.json docs \
--glob '!docs/openapi/openapi.json'Repository: maximhq/bifrost
Length of output: 50374
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- Config schema matches ---'
rg -n -C 18 \
'override_(amount|mode|cycles_remaining|cycles_total|anchor_reset)|BudgetOverride|budget override|mode.*empty|empty.*mode' \
transports/config.schema.json
printf '%s\n' '--- Matching implementation files ---'
rg -l \
'override_(amount|mode|cycles_remaining|cycles_total|anchor_reset)|BudgetOverride(Request|Response)|updateVirtualKeyBudgetOverride|deleteVirtualKeyBudgetOverride' \
. \
--glob '!docs/**' \
--glob '!node_modules/**' \
--glob '!dist/**' \
--glob '!build/**' \
--glob '!*.sum' \
| head -80
printf '%s\n' '--- Navigation and API reference entries ---'
rg -n -C 10 \
'OSS Governance|governance|openapi/openapi.json|API Reference' \
docs/docs.jsonRepository: maximhq/bifrost
Length of output: 22082
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- Handler override logic ---'
rg -n -C 16 \
'override_(amount|mode|cycles_remaining|cycles_total|anchor_reset)|BudgetOverride(Request|Response)|updateVirtualKeyBudgetOverride|deleteVirtualKeyBudgetOverride' \
transports/bifrost-http/handlers/governance.go
printf '%s\n' '--- Budget persistence and model logic ---'
rg -n -C 12 \
'override_(amount|mode|cycles_remaining|cycles_total|anchor_reset)' \
framework/configstore/tables/budget.go \
framework/configstore/rdb.go \
framework/configstore/migrations.go \
plugins/governance/store.go
printf '%s\n' '--- Tests for override state and validation ---'
rg -n -C 12 \
'override_(amount|mode|cycles_remaining|cycles_total|anchor_reset)|mode.*empty|empty.*mode|amount.*0|cycles' \
transports/bifrost-http/handlers/governance_test.go \
framework/configstore/migrations_test.goRepository: maximhq/bifrost
Length of output: 50371
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
import json
with open("docs/openapi/openapi.json", encoding="utf-8") as f:
api = json.load(f)
with open("transports/config.schema.json", encoding="utf-8") as f:
config = json.load(f)
path = api["paths"]["/api/governance/virtual-keys/{vk_id}/budgets/{budget_id}/override"]
request = api["components"]["schemas"]["BudgetOverrideRequest"]
budget = api["components"]["schemas"]["Budget"]
config_budget = config["$defs"]["budget_line"]
print("openapi:", api["openapi"])
print("put.operationId:", path["put"]["operationId"])
print("delete.operationId:", path["delete"]["operationId"])
print("put.security:", path["put"]["security"])
print("delete.security:", path["delete"]["security"])
print("request.amount.constraints:",
{k: request["properties"]["amount"].get(k)
for k in ("minimum", "exclusiveMinimum", "maximum", "exclusiveMaximum")})
print("request.cycles.minimum:", request["properties"]["cycles"].get("minimum"))
print("request.has_conditional_keywords:",
any(k in request for k in ("if", "then", "else", "oneOf", "anyOf", "allOf")))
print("budget.override_mode.enum:", budget["properties"]["override_mode"].get("enum"))
print("config.override_mode.enum:", config_budget["properties"]["override_mode"].get("enum"))
print("config.inactive_rules:", config_budget["allOf"][0])
print("config.cycles_rules:", config_budget["allOf"][1])
print("config.forever_rules:", config_budget["allOf"][2])
PYRepository: maximhq/bifrost
Length of output: 690
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
import json
with open("transports/config.schema.json", encoding="utf-8") as f:
config = json.load(f)
def walk(value, path=()):
if isinstance(value, dict):
if "override_mode" in value:
print("definition:", ".".join(path))
print(json.dumps(value, indent=2))
for key, child in value.items():
walk(child, path + (str(key),))
elif isinstance(value, list):
for index, child in enumerate(value):
walk(child, path + (str(index),))
walk(config)
PYRepository: maximhq/bifrost
Length of output: 3490
Align the bundled budget override schemas with the governance contract.
BudgetOverrideRequest lacks a positive amount constraint and conditional cycles validation. Budget omits the inactive "" mode and zero-value lifecycle state. Add the OpenAPI 3.1 constraints and lifecycle states. The bundled operations match the source specifications.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/openapi/openapi.json` around lines 45035 - 45186, Update the bundled
OpenAPI schemas `BudgetOverrideRequest` and `Budget` to match the governance
contract: require `amount` to be strictly positive, enforce `cycles` validation
conditionally when the override mode is `cycles`, and include the inactive
empty-string mode plus the zero-value lifecycle state in `Budget`. Preserve the
existing operation definitions and references.
Source: Learnings
| "BudgetOverrideRequest": { | ||
| "type": "object", | ||
| "description": "Replaces the active override on one budget. The override is additive: it does not change the\nbudget's `max_limit`, `current_usage`, or reset schedule. Sending this request against a budget\nthat already has an override replaces that override entirely.\n", | ||
| "required": [ | ||
| "amount", | ||
| "mode" | ||
| ], | ||
| "properties": { | ||
| "amount": { | ||
| "type": "number", | ||
| "description": "Additional spend in dollars added on top of `max_limit` while the override is active. Must be greater than 0 and finite." | ||
| }, | ||
| "mode": { | ||
| "type": "string", | ||
| "description": "`cycles` keeps the override active for `cycles` reset windows starting with the current one.\n`forever` keeps it active until it is removed with a DELETE.\n", | ||
| "enum": [ | ||
| "cycles", | ||
| "forever" | ||
| ] | ||
| }, | ||
| "cycles": { | ||
| "type": "integer", | ||
| "description": "Number of reset windows the override stays active for, counting the current window as the first.\nRequired and must be greater than 0 when `mode` is `cycles`; must be omitted or 0 when `mode` is `forever`.\n", | ||
| "minimum": 1 | ||
| } |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -e
printf '%s\n' '--- repository status and changed-file summary ---'
git status --short
git diff --stat
printf '%s\n' '--- candidate files ---'
git ls-files | rg '(^|/)(openapi\.json|config\.schema\.json|docs\.json)$|governance|budget'
printf '%s\n' '--- OpenAPI version and target schemas ---'
rg -n -C 3 '"openapi"|"BudgetOverrideRequest"|"override_amount"|"override_mode"|"override_cycles_remaining"|"override_cycles_total"|"override_anchor_reset"' docs/openapi/openapi.json
printf '%s\n' '--- source/schema references ---'
rg -n -C 3 'BudgetOverrideRequest|override_cycles_remaining|override_cycles_total|override_anchor_reset|override_mode|override_amount|mode.*empty|empty.*mode' . -g '!docs/openapi/openapi.json' -g '!node_modules' -g '!dist' -g '!build'Repository: maximhq/bifrost
Length of output: 50372
🏁 Script executed:
#!/bin/bash
set -e
log=/tmp/coderabbit-shell-logs/shell-output-4qMj78
printf '%s\n' '--- status and diff summary ---'
sed -n '1,80p' "$log"
printf '%s\n' '--- exact budget override references outside generated OpenAPI ---'
rg -n -C 4 'BudgetOverride|override_cycles_remaining|override_cycles_total|override_anchor_reset|override_mode|override_amount' \
--glob '!docs/openapi/openapi.json' \
--glob '!ui/**' \
--glob '!core/providers/**' \
--glob '!vendor/**' \
.
printf '%s\n' '--- OpenAPI header and target schema ranges ---'
sed -n '1,25p' docs/openapi/openapi.json
sed -n '82250,82335p' docs/openapi/openapi.json
sed -n '82455,82535p' docs/openapi/openapi.jsonRepository: maximhq/bifrost
Length of output: 50374
🏁 Script executed:
#!/bin/bash
set -e
printf '%s\n' '--- OpenAPI document version ---'
sed -n '1,18p' docs/openapi/openapi.json
printf '%s\n' '--- source OpenAPI Budget schema ---'
sed -n '1,125p' docs/openapi/schemas/management/governance.yaml
printf '%s\n' '--- source OpenAPI override request schema ---'
sed -n '125,205p' docs/openapi/schemas/management/governance.yaml
printf '%s\n' '--- budget model and lifecycle methods ---'
rg -n -C 8 'type BudgetOverrideMode|BudgetOverrideMode|func \(.*\) SetOverride|func \(.*\) ClearOverride|HasActiveOverride|OverrideCycles' framework/configstore/tables/budget.go
printf '%s\n' '--- handler validation and request flow ---'
sed -n '1569,1638p' transports/bifrost-http/handlers/governance.go
printf '%s\n' '--- relevant docs navigation entry ---'
rg -n -C 4 'OSS Governance|governance|openapi/openapi.json' docs/docs.jsonRepository: maximhq/bifrost
Length of output: 25592
🏁 Script executed:
#!/bin/bash
set -e
python3 - <<'PY'
import json
from pathlib import Path
doc = json.loads(Path("docs/openapi/openapi.json").read_text())
schemas = doc["components"]["schemas"]
for name in ("Budget", "BudgetOverrideRequest"):
schema = schemas[name]
print(f"--- {name} ---")
print("required:", schema.get("required"))
for key, value in schema.get("properties", {}).items():
if key.startswith("override") or key in ("amount", "mode", "cycles"):
print(key, json.dumps(value, sort_keys=True))
print("allOf:", json.dumps(schema.get("allOf"), sort_keys=True))
print("--- exact JSON schema checks ---")
budget = schemas["Budget"]
request = schemas["BudgetOverrideRequest"]
checks = {
"request.amount.exclusiveMinimum": request["properties"]["amount"].get("exclusiveMinimum"),
"request.amount.minimum": request["properties"]["amount"].get("minimum"),
"request.cycles.minimum": request["properties"]["cycles"].get("minimum"),
"request.anyOf": request.get("anyOf"),
"request.oneOf": request.get("oneOf"),
"request.allOf": request.get("allOf"),
"budget.override_mode.enum": budget["properties"]["override_mode"].get("enum"),
"budget.allOf": budget.get("allOf"),
}
for key, value in checks.items():
print(f"{key}: {json.dumps(value, sort_keys=True)}")
PY
printf '%s\n' '--- serialization tags for the Budget response fields ---'
sed -n '23,70p' framework/configstore/tables/budget.go
printf '%s\n' '--- all governance OpenAPI source references ---'
rg -n 'Budget:|BudgetOverrideRequest:|override_amount:|override_mode:|override_cycles_remaining:|override_cycles_total:|override_anchor_reset:' \
docs/openapi/schemas/management/governance.yaml docs/openapi/openapi.yaml docs/openapi/openapi.jsonRepository: maximhq/bifrost
Length of output: 6301
Align budget override schemas with the runtime lifecycle.
- Add
exclusiveMinimum: 0toBudgetOverrideRequest.amount. - Add OpenAPI 3.1 conditional rules:
cyclesis required and positive formode: cycles; it is omitted or0formode: forever. - In
Budget, model the empty mode asoverride_mode: "". Require zero inactive override values and omit onlyoverride_anchor_reset. Require positive active amounts and valid finite-cycle fields. - Update
docs/openapi/schemas/management/governance.yamland regeneratedocs/openapi/openapi.json. Removeomitemptyfrom inactive response fields if the API must serialize their zero values.
📍 Affects 1 file
docs/openapi/openapi.json#L82481-L82505(this comment)docs/openapi/openapi.json#L82289-L82312
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/openapi/openapi.json` around lines 82481 - 82505, Update
BudgetOverrideRequest in docs/openapi/schemas/management/governance.yaml with
exclusiveMinimum: 0 for amount and OpenAPI 3.1 conditional schemas requiring
positive cycles for mode "cycles" and omitted-or-zero cycles for mode "forever";
regenerate docs/openapi/openapi.json at both listed ranges. Update Budget to
represent inactive mode as override_mode: "", require zero inactive override
values while omitting only override_anchor_reset, and enforce positive active
amounts plus valid finite-cycle fields; remove omitempty from inactive response
fields when needed to serialize their zero values.
Source: Path instructions
| virtual-keys-budget-override: | ||
| put: | ||
| operationId: updateVirtualKeyBudgetOverride | ||
| summary: Set virtual key budget override | ||
| description: | | ||
| Sets or replaces the spending override on one of a virtual key's budgets. The override is additive — | ||
| while it is active the budget is enforced against `max_limit + override_amount` — and it leaves the | ||
| budget's base limit, current usage, and reset schedule untouched. | ||
|
|
||
| Use `mode: cycles` with a `cycles` count to grant extra spend for a finite number of reset windows | ||
| (the current window counts as the first), or `mode: forever` to keep the override until it is deleted. | ||
| A finite grant is anchored to the budget's current reset window, so every node in a cluster derives the | ||
| same number of remaining cycles and a config reload cannot resurrect a spent one. | ||
| tags: | ||
| - Governance | ||
| parameters: | ||
| - name: vk_id | ||
| in: path | ||
| required: true | ||
| description: Virtual key ID | ||
| schema: | ||
| type: string | ||
| - name: budget_id | ||
| in: path | ||
| required: true | ||
| description: ID of a budget owned by the virtual key | ||
| schema: | ||
| type: string | ||
| requestBody: | ||
| required: true | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: '../../schemas/management/governance.yaml#/BudgetOverrideRequest' | ||
| security: | ||
| - ManagementBearerAuth: [] | ||
| responses: | ||
| '200': | ||
| description: Budget override applied successfully | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: '../../schemas/management/governance.yaml#/BudgetOverrideResponse' | ||
| '400': | ||
| $ref: '../../openapi.yaml#/components/responses/BadRequest' | ||
| '404': | ||
| description: Virtual key or budget not found | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: '../../schemas/inference/common.yaml#/BifrostError' | ||
| '500': | ||
| $ref: '../../openapi.yaml#/components/responses/InternalError' |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== BudgetOverrideRequest / BudgetOverrideResponse schema =="
fd -t f 'governance.yaml' docs/openapi/schemas | xargs -I{} rg -n -A 25 'BudgetOverrideRequest:|BudgetOverrideResponse:|OverrideMode|override_mode|override_amount|override_cycles|override_anchor' {}
echo "== openapi.json parity check =="
fd -t f 'openapi.json' docs/openapi | xargs -I{} rg -n 'virtual-keys-budget-override|BudgetOverrideRequest|BudgetOverrideResponse|override_amount|override_mode|override_cycles|override_anchor' {}Repository: maximhq/bifrost
Length of output: 5690
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== Stack and changed-file context =="
git status --short
git branch --show-current
git diff --stat
echo "== YAML schema definitions =="
cat -n docs/openapi/schemas/management/governance.yaml | sed -n '1,75p;150,200p'
echo "== OpenAPI JSON operation and schemas =="
python3 - <<'PY'
import json
from pathlib import Path
p = Path("docs/openapi/openapi.json")
doc = json.loads(p.read_text())
path = doc["paths"].get("/v1/management/virtual-keys/{vk_id}/budgets/{budget_id}/override")
print("operation:")
print(json.dumps(path, indent=2, sort_keys=True) if path else "NOT FOUND")
schemas = doc.get("components", {}).get("schemas", {})
for name in ("BudgetOverrideRequest", "BudgetOverrideResponse", "Budget"):
print(f"\n{name}:")
print(json.dumps(schemas.get(name, "NOT FOUND"), indent=2, sort_keys=True))
PY
echo "== Documentation navigation references =="
rg -n -C 3 'API Reference|openapi\.json|Governance|governance' docs/docs.json docs -g 'docs.json' -g '*.mdx' -g '*.md' | head -200Repository: maximhq/bifrost
Length of output: 24688
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== Existing budget-override conventions =="
rg -n -C 8 'override|budget.*mode|cycles|anchor|remaining|total' transports/config.schema.json | head -240
echo "== OpenAPI paths containing the override operation =="
python3 - <<'PY'
import json
from pathlib import Path
doc = json.loads(Path("docs/openapi/openapi.json").read_text())
for path, item in doc.get("paths", {}).items():
if "override" in path.lower():
print(path)
for method, operation in item.items():
if isinstance(operation, dict):
print(" ", method, operation.get("operationId"))
PY
echo "== Schema constraint keywords =="
rg -n -C 5 'BudgetOverrideRequest|BudgetOverrideResponse|override_amount|override_mode|override_cycles_remaining|override_cycles_total|override_anchor_reset|oneOf|allOf|anyOf|minimum|exclusiveMinimum|finite' docs/openapi/schemas/management/governance.yaml docs/openapi/openapi.json | head -320Repository: maximhq/bifrost
Length of output: 13266
🏁 Script executed:
#!/bin/bash
set -u
echo "== OpenAPI paths containing the override operation =="
python3 - <<'PY'
import json
from pathlib import Path
doc = json.loads(Path("docs/openapi/openapi.json").read_text())
found = False
for path, item in doc.get("paths", {}).items():
if "override" in path.lower():
found = True
print(path)
for method, operation in item.items():
if isinstance(operation, dict):
print(" ", method, operation.get("operationId"))
if not found:
print("NO OVERRIDE PATH FOUND")
PY
echo "== OpenAPI override schema constraints =="
rg -n -C 6 'BudgetOverrideRequest|BudgetOverrideResponse|override_amount|override_mode|override_cycles_remaining|override_cycles_total|override_anchor_reset|oneOf|allOf|anyOf|minimum|exclusiveMinimum|finite' \
docs/openapi/schemas/management/governance.yaml docs/openapi/openapi.json || true
echo "== YAML operation identity =="
rg -n -C 4 'virtual-keys-budget-override|updateVirtualKeyBudgetOverride|BudgetOverrideRequest|BudgetOverrideResponse' docs/openapi/paths/management/governance.yamlRepository: maximhq/bifrost
Length of output: 50372
🏁 Script executed:
#!/bin/bash
set -u
echo "== Generated JSON operation =="
python3 - <<'PY'
import json
from pathlib import Path
doc = json.loads(Path("docs/openapi/openapi.json").read_text())
op = doc["paths"]["/api/governance/virtual-keys/{vk_id}/budgets/{budget_id}/override"]["put"]
print(json.dumps({
"operationId": op.get("operationId"),
"summary": op.get("summary"),
"request_schema": op["requestBody"]["content"]["application/json"]["schema"],
"response_schema": op["responses"]["200"]["content"]["application/json"]["schema"],
}, indent=2))
PY
echo "== Runtime budget override symbols =="
rg -n -l 'BudgetOverrideRequest|override_cycles_total|override_anchor_reset|override_mode|override_amount' --glob '!docs/openapi/openapi.json' --glob '!docs/openapi/schemas/management/governance.yaml' . | head -80
echo "== Runtime validation and mode handling =="
rg -n -C 5 'BudgetOverrideRequest|override_cycles_total|override_anchor_reset|override_mode|override_amount|cycles.*forever|forever.*cycles' --glob '*.go' . | head -320Repository: maximhq/bifrost
Length of output: 25923
Add the missing budget override constraints to both OpenAPI sources.
BudgetOverrideRequest does not enforce a positive finite amount or mode-dependent cycles rules. Its unconditional minimum: 1 conflicts with the documented forever case where cycles may be 0. Budget does not enforce inactive zero values, the absent anchor, or override_cycles_total >= override_cycles_remaining. The JSON file mirrors these incomplete definitions.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/openapi/paths/management/governance.yaml` around lines 268 - 320, Update
BudgetOverrideRequest in both OpenAPI schema sources to require a positive
finite amount and enforce mode-dependent cycles: cycles mode must use a positive
count, while forever permits cycles 0; remove the unconditional minimum that
rejects this case. Update Budget to require inactive override fields to be zero,
omit the anchor when inactive, and enforce override_cycles_total >=
override_cycles_remaining, keeping the JSON definition synchronized with the
YAML schema.
| override_amount: | ||
| type: number | ||
| description: Additional spend added on top of `max_limit` while the override is active. Omitted when no override is set. | ||
| override_mode: | ||
| type: string | ||
| description: | | ||
| How long the override stays active. `cycles` keeps it active for a finite number of | ||
| reset windows; `forever` keeps it active until it is removed. Omitted when no override is set. | ||
| enum: | ||
| - cycles | ||
| - forever | ||
| override_cycles_remaining: | ||
| type: integer | ||
| description: | | ||
| Reset windows the override is still valid for, including the current one. Positive only | ||
| for `cycles` mode; recomputed from the original grant on every reset, never decremented in place. | ||
| override_cycles_total: | ||
| type: integer | ||
| description: Number of reset windows the current `cycles` override was granted for. Immutable for the life of the grant. | ||
| override_anchor_reset: | ||
| type: string | ||
| format: date-time | ||
| description: Reset-window boundary at which the current `cycles` override was granted. Immutable for the life of the grant. |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Make the inactive override state match the governance schema.
Lines 35 and 40 state that inactive override_amount and override_mode are omitted. The governance convention requires inactive override values to reset to zero, use the empty mode, and omit only override_anchor_reset.
A response that serializes the empty mode does not validate against the current enum. Document and model the zero-value inactive fields consistently.
As per path instructions, check parity with config.schema.json; it requires zero-valued inactive overrides and an omitted anchor.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/openapi/schemas/management/governance.yaml` around lines 33 - 55, The
governance schema must document inactive overrides as zero-valued rather than
omitted, with an empty override mode and only override_anchor_reset omitted.
Update the property descriptions and enum/model definitions around
override_amount, override_mode, override_cycles_remaining, and
override_cycles_total, ensuring the inactive empty mode is accepted consistently
with config.schema.json while retaining the existing active-mode values.
Source: Path instructions
| amount: | ||
| type: number | ||
| description: Additional spend in dollars added on top of `max_limit` while the override is active. Must be greater than 0 and finite. | ||
| mode: | ||
| type: string | ||
| description: | | ||
| `cycles` keeps the override active for `cycles` reset windows starting with the current one. | ||
| `forever` keeps it active until it is removed with a DELETE. | ||
| enum: | ||
| - cycles | ||
| - forever | ||
| cycles: | ||
| type: integer | ||
| description: | | ||
| Number of reset windows the override stays active for, counting the current window as the first. | ||
| Required and must be greater than 0 when `mode` is `cycles`; must be omitted or 0 when `mode` is `forever`. | ||
| minimum: 1 |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
# Inspect the OpenAPI version before choosing conditional-schema syntax.
rg -n -C2 '^openapi:' docs/openapi/openapi.yaml
# Compare the YAML source, published JSON bundle, and transport schema contract.
rg -n -C8 \
'BudgetOverrideRequest|override_amount|override_mode|override_cycles_remaining|override_cycles_total|override_anchor_reset' \
docs/openapi/schemas/management/governance.yaml \
docs/openapi/openapi.json \
transports/config.schema.jsonRepository: maximhq/bifrost
Length of output: 21858
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
sed -n '157,187p' docs/openapi/schemas/management/governance.yaml
sed -n '82481,82512p' docs/openapi/openapi.json
rg -n -C6 \
'BudgetOverrideRequest|override.*cycles|override.*amount|mode.*forever|cycles.*mode' \
--glob '!docs/openapi/openapi.json' \
--glob '!docs/openapi/schemas/management/governance.yaml' .Repository: maximhq/bifrost
Length of output: 50373
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
sed -n '41,86p' ui/components/budgetOverrideDialog.tsx
sed -n '1268,1282p' ui/lib/types/schemas.ts
rg -n -C10 \
'func .*SetOverride|SetOverride\(|BudgetOverrideMode|override amount|cycles must' \
--glob '*.go' \
--glob '!**/*_test.go' \
transports plugins configstoreRepository: maximhq/bifrost
Length of output: 7165
Encode the mode-dependent constraints in BudgetOverrideRequest.
Set amount.exclusiveMinimum: 0. Use oneOf or if/then so cycles is required with minimum: 1 only for mode: cycles. Omit cycles for mode: forever, matching the UI, Go request type, and documentation examples. Update docs/openapi/openapi.json to match.
The current global minimum: 1 rejects the documented cycles: 0 form for forever, and the schema does not enforce a positive amount.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/openapi/schemas/management/governance.yaml` around lines 167 - 183,
Update BudgetOverrideRequest so amount uses exclusiveMinimum: 0, and replace the
global cycles minimum with mode-dependent oneOf or if/then constraints: require
cycles with minimum 1 for mode cycles, while omitting cycles for mode forever.
Apply the same schema changes to docs/openapi/openapi.json.
Source: Path instructions
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
## Summary
Adds documentation and OpenAPI specs for budget overrides on virtual-key budgets. An override temporarily raises a budget's effective spending limit by adding an `override_amount` on top of the base `max_limit`, without touching the base limit, current usage, or reset schedule. Overrides can be granted for a finite number of reset cycles or indefinitely, and are managed via `PUT`/`DELETE` on `/api/governance/virtual-keys/{vk_id}/budgets/{budget_id}/override`.
## Changes
- Added a **Budget overrides** section to `budget-and-limits.mdx` explaining the `effective_max_limit = max_limit + override_amount` enforcement model and linking to the virtual keys walkthrough.
- Expanded the override section in `virtual-keys.mdx` with full API usage examples for `PUT` (both `cycles` and `forever` modes) and `DELETE`, a sample JSON response, and behavioral notes covering immutability of the base limit, cycle anchoring, and cluster consistency.
- Registered `PUT` and `DELETE` endpoints for `/api/governance/virtual-keys/{vk_id}/budgets/{budget_id}/override` in the OpenAPI spec (both JSON and YAML), including request/response schemas (`BudgetOverrideRequest`, `BudgetOverrideResponse`) and new override fields on the `Budget` schema (`override_amount`, `override_mode`, `override_cycles_remaining`, `override_cycles_total`, `override_anchor_reset`).
## Type of change
- [ ] Bug fix
- [ ] Feature
- [ ] Refactor
- [x] Documentation
- [ ] Chore/CI
## Affected areas
- [ ] Core (Go)
- [ ] Transports (HTTP)
- [ ] Providers/Integrations
- [ ] Plugins
- [ ] UI (React)
- [x] Docs
## How to test
1. Navigate to the **Budget overrides** section in `budget-and-limits.mdx` and confirm the formula and cross-link render correctly.
2. Navigate to the override API section in `virtual-keys.mdx` and verify all code blocks, the sample response, and the behavioral notes display as expected.
3. Load the OpenAPI spec and confirm the two new endpoints appear under the **Governance** tag with correct request/response schemas and that the `Budget` schema includes the five new override fields.
## Breaking changes
- [ ] Yes
- [x] No
## Related issues
## Security considerations
The new endpoints require `ManagementBearerAuth`, consistent with all other governance management endpoints. No new auth surface is introduced.
## Checklist
- [ ] I read `docs/contributing/README.md` and followed the guidelines
- [ ] I added/updated tests where appropriate
- [x] I updated documentation where needed
- [ ] I verified builds succeed (Go and UI)
- [ ] I verified the CI pipeline passes locally if applicable
## Summary
Adds documentation and OpenAPI specs for budget overrides on virtual-key budgets. An override temporarily raises a budget's effective spending limit by adding an `override_amount` on top of the base `max_limit`, without touching the base limit, current usage, or reset schedule. Overrides can be granted for a finite number of reset cycles or indefinitely, and are managed via `PUT`/`DELETE` on `/api/governance/virtual-keys/{vk_id}/budgets/{budget_id}/override`.
## Changes
- Added a **Budget overrides** section to `budget-and-limits.mdx` explaining the `effective_max_limit = max_limit + override_amount` enforcement model and linking to the virtual keys walkthrough.
- Expanded the override section in `virtual-keys.mdx` with full API usage examples for `PUT` (both `cycles` and `forever` modes) and `DELETE`, a sample JSON response, and behavioral notes covering immutability of the base limit, cycle anchoring, and cluster consistency.
- Registered `PUT` and `DELETE` endpoints for `/api/governance/virtual-keys/{vk_id}/budgets/{budget_id}/override` in the OpenAPI spec (both JSON and YAML), including request/response schemas (`BudgetOverrideRequest`, `BudgetOverrideResponse`) and new override fields on the `Budget` schema (`override_amount`, `override_mode`, `override_cycles_remaining`, `override_cycles_total`, `override_anchor_reset`).
## Type of change
- [ ] Bug fix
- [ ] Feature
- [ ] Refactor
- [x] Documentation
- [ ] Chore/CI
## Affected areas
- [ ] Core (Go)
- [ ] Transports (HTTP)
- [ ] Providers/Integrations
- [ ] Plugins
- [ ] UI (React)
- [x] Docs
## How to test
1. Navigate to the **Budget overrides** section in `budget-and-limits.mdx` and confirm the formula and cross-link render correctly.
2. Navigate to the override API section in `virtual-keys.mdx` and verify all code blocks, the sample response, and the behavioral notes display as expected.
3. Load the OpenAPI spec and confirm the two new endpoints appear under the **Governance** tag with correct request/response schemas and that the `Budget` schema includes the five new override fields.
## Breaking changes
- [ ] Yes
- [x] No
## Related issues
## Security considerations
The new endpoints require `ManagementBearerAuth`, consistent with all other governance management endpoints. No new auth surface is introduced.
## Checklist
- [ ] I read `docs/contributing/README.md` and followed the guidelines
- [ ] I added/updated tests where appropriate
- [x] I updated documentation where needed
- [ ] I verified builds succeed (Go and UI)
- [ ] I verified the CI pipeline passes locally if applicable

Summary
Adds documentation and OpenAPI specs for budget overrides on virtual-key budgets. An override temporarily raises a budget's effective spending limit by adding an
override_amounton top of the basemax_limit, without touching the base limit, current usage, or reset schedule. Overrides can be granted for a finite number of reset cycles or indefinitely, and are managed viaPUT/DELETEon/api/governance/virtual-keys/{vk_id}/budgets/{budget_id}/override.Changes
budget-and-limits.mdxexplaining theeffective_max_limit = max_limit + override_amountenforcement model and linking to the virtual keys walkthrough.virtual-keys.mdxwith full API usage examples forPUT(bothcyclesandforevermodes) andDELETE, a sample JSON response, and behavioral notes covering immutability of the base limit, cycle anchoring, and cluster consistency.PUTandDELETEendpoints for/api/governance/virtual-keys/{vk_id}/budgets/{budget_id}/overridein the OpenAPI spec (both JSON and YAML), including request/response schemas (BudgetOverrideRequest,BudgetOverrideResponse) and new override fields on theBudgetschema (override_amount,override_mode,override_cycles_remaining,override_cycles_total,override_anchor_reset).Type of change
Affected areas
How to test
budget-and-limits.mdxand confirm the formula and cross-link render correctly.virtual-keys.mdxand verify all code blocks, the sample response, and the behavioral notes display as expected.Budgetschema includes the five new override fields.Breaking changes
Related issues
Security considerations
The new endpoints require
ManagementBearerAuth, consistent with all other governance management endpoints. No new auth surface is introduced.Checklist
docs/contributing/README.mdand followed the guidelines