mirror of
https://github.com/openai/codex.git
synced 2026-11-08 08:37:30 +00:00
[app-server] Include reset-credit details in rate limits (#30395)
## Why Supported clients currently receive only a reset-credit count from `account/rateLimits/read`. The redemption UI and other app-server clients need each available credit's expiry and ID so they can explain what will expire and consume the credit a user selected. This information belongs on the existing rate-limit read surface rather than a second app-server list RPC that clients would need to coordinate. ## What changed - extend `rateLimitResetCredits` on `account/rateLimits/read` with nullable `credits` detail rows - fetch usage and reset-credit details concurrently; if the detail request fails, times out, or cannot be parsed, preserve the usage response and return `credits: null` - expose each credit's ID, reset type, status, grant time, expiry time, title, and description - add an optional nullable `creditId` to `account/rateLimitResetCredit/consume`; omitting it preserves the existing automatic-selection behavior - forward a selected credit ID to the Codex backend and update the app-server documentation and generated schemas The TUI consumer is stacked in #30488. ## Validation - `just test -p codex-app-server-protocol` (251 passed) - `just test -p codex-backend-client` (16 passed) - `just test -p codex-app-server rate_limit` (18 passed) Part of #29618.
This commit is contained in:
24 files changed
+967
-53
No files matched your search
@@ -556,6 +556,13 @@
|
||||
},
|
||||
"ConsumeAccountRateLimitResetCreditParams": {
|
||||
"properties": {
|
||||
"creditId": {
|
||||
"description": "Opaque reset-credit identifier to redeem. When omitted, the backend selects the next available credit.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"idempotencyKey": {
|
||||
"description": "Identifies one logical reset attempt. A UUID is recommended; reuse the same value when retrying that attempt.",
|
||||
"type": "string"
|
||||
|
||||
+81
@@ -8688,6 +8688,13 @@
|
||||
"ConsumeAccountRateLimitResetCreditParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"creditId": {
|
||||
"description": "Opaque reset-credit identifier to redeem. When omitted, the backend selects the next available credit.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"idempotencyKey": {
|
||||
"description": "Identifies one logical reset attempt. A UUID is recommended; reuse the same value when retrying that attempt.",
|
||||
"type": "string"
|
||||
@@ -14533,11 +14540,78 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"RateLimitResetCredit": {
|
||||
"properties": {
|
||||
"description": {
|
||||
"description": "Backend-provided display description for this credit, or `null` when unavailable.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"expiresAt": {
|
||||
"description": "Unix timestamp in seconds when the credit expires, or `null` if it does not expire.",
|
||||
"format": "int64",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"grantedAt": {
|
||||
"description": "Unix timestamp in seconds when the credit was granted.",
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"description": "Opaque backend identifier for this reset credit.",
|
||||
"type": "string"
|
||||
},
|
||||
"resetType": {
|
||||
"$ref": "#/definitions/v2/RateLimitResetType"
|
||||
},
|
||||
"status": {
|
||||
"$ref": "#/definitions/v2/RateLimitResetCreditStatus"
|
||||
},
|
||||
"title": {
|
||||
"description": "Backend-provided display title for this credit, or `null` when unavailable.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"grantedAt",
|
||||
"id",
|
||||
"resetType",
|
||||
"status"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"RateLimitResetCreditStatus": {
|
||||
"enum": [
|
||||
"available",
|
||||
"redeeming",
|
||||
"redeemed",
|
||||
"unknown"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"RateLimitResetCreditsSummary": {
|
||||
"properties": {
|
||||
"availableCount": {
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"credits": {
|
||||
"description": "Detail rows for available reset credits, when the backend provides them.\n\n`null` means only `availableCount` is known, while an empty array means details were fetched and no available credits were returned. The backend may cap this list, so its length can be less than `availableCount`.",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v2/RateLimitResetCredit"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -14545,6 +14619,13 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"RateLimitResetType": {
|
||||
"enum": [
|
||||
"codexRateLimits",
|
||||
"unknown"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"RateLimitSnapshot": {
|
||||
"properties": {
|
||||
"credits": {
|
||||
|
||||
+81
@@ -4928,6 +4928,13 @@
|
||||
"ConsumeAccountRateLimitResetCreditParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"creditId": {
|
||||
"description": "Opaque reset-credit identifier to redeem. When omitted, the backend selects the next available credit.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"idempotencyKey": {
|
||||
"description": "Identifies one logical reset attempt. A UUID is recommended; reuse the same value when retrying that attempt.",
|
||||
"type": "string"
|
||||
@@ -10937,11 +10944,78 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"RateLimitResetCredit": {
|
||||
"properties": {
|
||||
"description": {
|
||||
"description": "Backend-provided display description for this credit, or `null` when unavailable.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"expiresAt": {
|
||||
"description": "Unix timestamp in seconds when the credit expires, or `null` if it does not expire.",
|
||||
"format": "int64",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"grantedAt": {
|
||||
"description": "Unix timestamp in seconds when the credit was granted.",
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"description": "Opaque backend identifier for this reset credit.",
|
||||
"type": "string"
|
||||
},
|
||||
"resetType": {
|
||||
"$ref": "#/definitions/RateLimitResetType"
|
||||
},
|
||||
"status": {
|
||||
"$ref": "#/definitions/RateLimitResetCreditStatus"
|
||||
},
|
||||
"title": {
|
||||
"description": "Backend-provided display title for this credit, or `null` when unavailable.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"grantedAt",
|
||||
"id",
|
||||
"resetType",
|
||||
"status"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"RateLimitResetCreditStatus": {
|
||||
"enum": [
|
||||
"available",
|
||||
"redeeming",
|
||||
"redeemed",
|
||||
"unknown"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"RateLimitResetCreditsSummary": {
|
||||
"properties": {
|
||||
"availableCount": {
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"credits": {
|
||||
"description": "Detail rows for available reset credits, when the backend provides them.\n\n`null` means only `availableCount` is known, while an empty array means details were fetched and no available credits were returned. The backend may cap this list, so its length can be less than `availableCount`.",
|
||||
"items": {
|
||||
"$ref": "#/definitions/RateLimitResetCredit"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -10949,6 +11023,13 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"RateLimitResetType": {
|
||||
"enum": [
|
||||
"codexRateLimits",
|
||||
"unknown"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"RateLimitSnapshot": {
|
||||
"properties": {
|
||||
"credits": {
|
||||
|
||||
+7
@@ -1,6 +1,13 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"creditId": {
|
||||
"description": "Opaque reset-credit identifier to redeem. When omitted, the backend selects the next available credit.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"idempotencyKey": {
|
||||
"description": "Identifies one logical reset attempt. A UUID is recommended; reuse the same value when retrying that attempt.",
|
||||
"type": "string"
|
||||
|
||||
+74
@@ -49,11 +49,78 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"RateLimitResetCredit": {
|
||||
"properties": {
|
||||
"description": {
|
||||
"description": "Backend-provided display description for this credit, or `null` when unavailable.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"expiresAt": {
|
||||
"description": "Unix timestamp in seconds when the credit expires, or `null` if it does not expire.",
|
||||
"format": "int64",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"grantedAt": {
|
||||
"description": "Unix timestamp in seconds when the credit was granted.",
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"description": "Opaque backend identifier for this reset credit.",
|
||||
"type": "string"
|
||||
},
|
||||
"resetType": {
|
||||
"$ref": "#/definitions/RateLimitResetType"
|
||||
},
|
||||
"status": {
|
||||
"$ref": "#/definitions/RateLimitResetCreditStatus"
|
||||
},
|
||||
"title": {
|
||||
"description": "Backend-provided display title for this credit, or `null` when unavailable.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"grantedAt",
|
||||
"id",
|
||||
"resetType",
|
||||
"status"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"RateLimitResetCreditStatus": {
|
||||
"enum": [
|
||||
"available",
|
||||
"redeeming",
|
||||
"redeemed",
|
||||
"unknown"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"RateLimitResetCreditsSummary": {
|
||||
"properties": {
|
||||
"availableCount": {
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"credits": {
|
||||
"description": "Detail rows for available reset credits, when the backend provides them.\n\n`null` means only `availableCount` is known, while an empty array means details were fetched and no available credits were returned. The backend may cap this list, so its length can be less than `availableCount`.",
|
||||
"items": {
|
||||
"$ref": "#/definitions/RateLimitResetCredit"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -61,6 +128,13 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"RateLimitResetType": {
|
||||
"enum": [
|
||||
"codexRateLimits",
|
||||
"unknown"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"RateLimitSnapshot": {
|
||||
"properties": {
|
||||
"credits": {
|
||||
|
||||
Generated
+6
-1
@@ -7,4 +7,9 @@ export type ConsumeAccountRateLimitResetCreditParams = {
|
||||
* Identifies one logical reset attempt. A UUID is recommended; reuse the same value when
|
||||
* retrying that attempt.
|
||||
*/
|
||||
idempotencyKey: string, };
|
||||
idempotencyKey: string,
|
||||
/**
|
||||
* Opaque reset-credit identifier to redeem. When omitted, the backend selects the next
|
||||
* available credit.
|
||||
*/
|
||||
creditId?: string | null, };
|
||||
@@ -0,0 +1,27 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { RateLimitResetCreditStatus } from "./RateLimitResetCreditStatus";
|
||||
import type { RateLimitResetType } from "./RateLimitResetType";
|
||||
|
||||
export type RateLimitResetCredit = {
|
||||
/**
|
||||
* Opaque backend identifier for this reset credit.
|
||||
*/
|
||||
id: string, resetType: RateLimitResetType, status: RateLimitResetCreditStatus,
|
||||
/**
|
||||
* Unix timestamp in seconds when the credit was granted.
|
||||
*/
|
||||
grantedAt: number,
|
||||
/**
|
||||
* Unix timestamp in seconds when the credit expires, or `null` if it does not expire.
|
||||
*/
|
||||
expiresAt: number | null,
|
||||
/**
|
||||
* Backend-provided display title for this credit, or `null` when unavailable.
|
||||
*/
|
||||
title: string | null,
|
||||
/**
|
||||
* Backend-provided display description for this credit, or `null` when unavailable.
|
||||
*/
|
||||
description: string | null, };
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type RateLimitResetCreditStatus = "available" | "redeeming" | "redeemed" | "unknown";
|
||||
+10
-1
@@ -1,5 +1,14 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { RateLimitResetCredit } from "./RateLimitResetCredit";
|
||||
|
||||
export type RateLimitResetCreditsSummary = { availableCount: bigint, };
|
||||
export type RateLimitResetCreditsSummary = { availableCount: bigint,
|
||||
/**
|
||||
* Detail rows for available reset credits, when the backend provides them.
|
||||
*
|
||||
* `null` means only `availableCount` is known, while an empty array means details were fetched
|
||||
* and no available credits were returned. The backend may cap this list, so its length can be
|
||||
* less than `availableCount`.
|
||||
*/
|
||||
credits: Array<RateLimitResetCredit> | null, };
|
||||
@@ -0,0 +1,5 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type RateLimitResetType = "codexRateLimits" | "unknown";
|
||||
@@ -335,7 +335,10 @@ export type { ProcessOutputDeltaNotification } from "./ProcessOutputDeltaNotific
|
||||
export type { ProcessOutputStream } from "./ProcessOutputStream";
|
||||
export type { ProcessTerminalSize } from "./ProcessTerminalSize";
|
||||
export type { RateLimitReachedType } from "./RateLimitReachedType";
|
||||
export type { RateLimitResetCredit } from "./RateLimitResetCredit";
|
||||
export type { RateLimitResetCreditStatus } from "./RateLimitResetCreditStatus";
|
||||
export type { RateLimitResetCreditsSummary } from "./RateLimitResetCreditsSummary";
|
||||
export type { RateLimitResetType } from "./RateLimitResetType";
|
||||
export type { RateLimitSnapshot } from "./RateLimitSnapshot";
|
||||
export type { RateLimitWindow } from "./RateLimitWindow";
|
||||
export type { RawResponseItemCompletedNotification } from "./RawResponseItemCompletedNotification";
|
||||
|
||||
@@ -284,6 +284,52 @@ pub struct GetAccountRateLimitsResponse {
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct RateLimitResetCreditsSummary {
|
||||
pub available_count: i64,
|
||||
/// Detail rows for available reset credits, when the backend provides them.
|
||||
///
|
||||
/// `null` means only `availableCount` is known, while an empty array means details were fetched
|
||||
/// and no available credits were returned. The backend may cap this list, so its length can be
|
||||
/// less than `availableCount`.
|
||||
pub credits: Option<Vec<RateLimitResetCredit>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct RateLimitResetCredit {
|
||||
/// Opaque backend identifier for this reset credit.
|
||||
pub id: String,
|
||||
pub reset_type: RateLimitResetType,
|
||||
pub status: RateLimitResetCreditStatus,
|
||||
/// Unix timestamp in seconds when the credit was granted.
|
||||
#[ts(type = "number")]
|
||||
pub granted_at: i64,
|
||||
/// Unix timestamp in seconds when the credit expires, or `null` if it does not expire.
|
||||
#[ts(type = "number | null")]
|
||||
pub expires_at: Option<i64>,
|
||||
/// Backend-provided display title for this credit, or `null` when unavailable.
|
||||
pub title: Option<String>,
|
||||
/// Backend-provided display description for this credit, or `null` when unavailable.
|
||||
pub description: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/", rename_all = "camelCase")]
|
||||
pub enum RateLimitResetType {
|
||||
CodexRateLimits,
|
||||
#[serde(other)]
|
||||
Unknown,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/", rename_all = "camelCase")]
|
||||
pub enum RateLimitResetCreditStatus {
|
||||
Available,
|
||||
Redeeming,
|
||||
Redeemed,
|
||||
#[serde(other)]
|
||||
Unknown,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
@@ -293,6 +339,10 @@ pub struct ConsumeAccountRateLimitResetCreditParams {
|
||||
/// Identifies one logical reset attempt. A UUID is recommended; reuse the same value when
|
||||
/// retrying that attempt.
|
||||
pub idempotency_key: String,
|
||||
/// Opaque reset-credit identifier to redeem. When omitted, the backend selects the next
|
||||
/// available credit.
|
||||
#[ts(optional = nullable)]
|
||||
pub credit_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
|
||||
Reference in new issue
Block a user