Skip to main content

gproxy_protocol/wire/openai/codex/
usage.rs

1//! Codex account usage contracts, not the public OpenAI organization API.
2//! Sources: samples/codex/codex-rs/backend-client/src/client/{task_usage,plan_history}.rs.
3//! Credit strings and JSON numbers retain upstream precision; missing amounts
4//! remain unknown. These services do not introduce inference OperationKeys.
5use crate::{Rest, WireRequest, WireResponse};
6use serde::{Deserialize, Serialize};
7use serde_json::Number;
8
9#[derive(
10    Debug,
11    Clone,
12    PartialEq,
13    Serialize,
14    Deserialize,
15    gproxy_protocol_macros::WireBuilder,
16    gproxy_protocol_macros::DeclaredFields,
17)]
18#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
19#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
20pub struct TaskUsageRequestBody {
21    pub threads: Vec<TaskUsageThread>,
22    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
23    pub rest: Rest,
24}
25
26#[derive(
27    Debug,
28    Clone,
29    PartialEq,
30    Serialize,
31    Deserialize,
32    gproxy_protocol_macros::WireBuilder,
33    gproxy_protocol_macros::DeclaredFields,
34)]
35#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
36#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
37pub struct TaskUsageThread {
38    pub thread_id: String,
39    pub created_at: Option<String>,
40    pub descendant_thread_ids: Vec<String>,
41    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
42    pub rest: Rest,
43}
44
45#[derive(
46    Debug,
47    Clone,
48    PartialEq,
49    Serialize,
50    Deserialize,
51    gproxy_protocol_macros::WireBuilder,
52    gproxy_protocol_macros::DeclaredFields,
53)]
54#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
55#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
56pub struct TaskUsageResponseBody {
57    pub data_as_of: Option<String>,
58    pub threads: Vec<TaskUsage>,
59    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
60    pub rest: Rest,
61}
62
63#[derive(
64    Debug,
65    Clone,
66    PartialEq,
67    Serialize,
68    Deserialize,
69    gproxy_protocol_macros::WireBuilder,
70    gproxy_protocol_macros::DeclaredFields,
71)]
72#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
73#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
74pub struct TaskUsage {
75    pub thread_id: String,
76    pub data_status: TaskUsageStatus,
77    pub usage_source: String,
78    pub five_hour_limit_percent: Option<Number>,
79    pub weekly_limit_percent: Option<Number>,
80    pub balance_usage_credits: Option<String>,
81    pub groups: Vec<TaskUsageGroup>,
82    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
83    pub rest: Rest,
84}
85
86#[derive(
87    Debug,
88    Clone,
89    Copy,
90    PartialEq,
91    Eq,
92    Serialize,
93    Deserialize,
94    gproxy_protocol_macros::DeclaredFields,
95)]
96#[serde(rename_all = "snake_case")]
97#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
98#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
99pub enum TaskUsageStatus {
100    Available,
101    Partial,
102    Unavailable,
103}
104
105#[derive(
106    Debug,
107    Clone,
108    PartialEq,
109    Serialize,
110    Deserialize,
111    gproxy_protocol_macros::WireBuilder,
112    gproxy_protocol_macros::DeclaredFields,
113)]
114#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
115#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
116pub struct TaskUsageGroup {
117    pub product_experience: Option<String>,
118    pub model: Option<String>,
119    pub reasoning_effort: Option<String>,
120    pub speed: Option<String>,
121    pub five_hour_limit_percent: Option<Number>,
122    pub weekly_limit_percent: Option<Number>,
123    pub balance_usage_credits: Option<String>,
124    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
125    pub rest: Rest,
126}
127
128#[derive(
129    Debug,
130    Clone,
131    PartialEq,
132    Serialize,
133    Deserialize,
134    gproxy_protocol_macros::WireBuilder,
135    gproxy_protocol_macros::DeclaredFields,
136)]
137#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
138#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
139pub struct PlanLimitHistory {
140    pub data_as_of: Option<String>,
141    pub coverage_start: Option<String>,
142    pub coverage_complete: bool,
143    #[serde(default = "approximate_by_default")]
144    pub approximate: bool,
145    pub boundary_tolerance_seconds: Option<u32>,
146    pub periods: Vec<PlanLimitPeriod>,
147    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
148    pub rest: Rest,
149}
150
151fn approximate_by_default() -> bool {
152    true
153}
154
155#[derive(
156    Debug,
157    Clone,
158    PartialEq,
159    Serialize,
160    Deserialize,
161    gproxy_protocol_macros::WireBuilder,
162    gproxy_protocol_macros::DeclaredFields,
163)]
164#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
165#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
166pub struct PlanLimitPeriod {
167    pub id: String,
168    pub window_minutes: u32,
169    pub plan_type: String,
170    pub starts_at: String,
171    pub ends_at: String,
172    pub accounting_complete: bool,
173    pub used_basis_points: Option<Number>,
174    pub breakdowns: Option<Vec<PlanLimitBreakdown>>,
175    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
176    pub rest: Rest,
177}
178
179#[derive(
180    Debug,
181    Clone,
182    PartialEq,
183    Serialize,
184    Deserialize,
185    gproxy_protocol_macros::WireBuilder,
186    gproxy_protocol_macros::DeclaredFields,
187)]
188#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
189#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
190pub struct PlanLimitBreakdown {
191    pub dimension: String,
192    pub rows: Vec<PlanLimitValue>,
193    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
194    pub rest: Rest,
195}
196
197#[derive(
198    Debug,
199    Clone,
200    PartialEq,
201    Serialize,
202    Deserialize,
203    gproxy_protocol_macros::WireBuilder,
204    gproxy_protocol_macros::DeclaredFields,
205)]
206#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
207#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
208pub struct PlanLimitValue {
209    pub key: String,
210    pub basis_points: Number,
211    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
212    pub rest: Rest,
213}
214
215pub type TaskUsageRequest = WireRequest<TaskUsageRequestBody>;
216pub type TaskUsageResponse = WireResponse<TaskUsageResponseBody>;
217pub type PlanLimitHistoryRequest = WireRequest<()>;
218pub type PlanLimitHistoryResponse = WireResponse<PlanLimitHistory>;