Skip to content

Commit 19bdf69

Browse files
owenlin0JeffCarpenter
authored andcommitted
[app-server] send account/rateLimits/updated notifications (openai#5477)
Codex will now send an `account/rateLimits/updated` notification whenever the user's rate limits are updated. This is implemented by just transforming the existing TokenCount event.
1 parent b6273d4 commit 19bdf69

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed

codex-rs/app-server-protocol/src/protocol.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,11 @@ pub struct AuthStatusChangeNotification {
875875
#[serde(tag = "method", content = "params", rename_all = "camelCase")]
876876
#[strum(serialize_all = "camelCase")]
877877
pub enum ServerNotification {
878+
#[serde(rename = "account/rateLimits/updated")]
879+
#[ts(rename = "account/rateLimits/updated")]
880+
#[strum(serialize = "account/rateLimits/updated")]
881+
AccountRateLimitsUpdated(RateLimitSnapshot),
882+
878883
/// Authentication status changed
879884
AuthStatusChange(AuthStatusChangeNotification),
880885

@@ -888,6 +893,7 @@ pub enum ServerNotification {
888893
impl ServerNotification {
889894
pub fn to_params(self) -> Result<serde_json::Value, serde_json::Error> {
890895
match self {
896+
ServerNotification::AccountRateLimitsUpdated(params) => serde_json::to_value(params),
891897
ServerNotification::AuthStatusChange(params) => serde_json::to_value(params),
892898
ServerNotification::LoginChatGptComplete(params) => serde_json::to_value(params),
893899
ServerNotification::SessionConfigured(params) => serde_json::to_value(params),

codex-rs/app-server/src/codex_message_processor.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1436,6 +1436,15 @@ async fn apply_bespoke_event_handling(
14361436
on_exec_approval_response(event_id, rx, conversation).await;
14371437
});
14381438
}
1439+
EventMsg::TokenCount(token_count_event) => {
1440+
if let Some(rate_limits) = token_count_event.rate_limits {
1441+
outgoing
1442+
.send_server_notification(ServerNotification::AccountRateLimitsUpdated(
1443+
rate_limits,
1444+
))
1445+
.await;
1446+
}
1447+
}
14391448
// If this is a TurnAborted, reply to any pending interrupt requests.
14401449
EventMsg::TurnAborted(turn_aborted_event) => {
14411450
let pending = {

codex-rs/app-server/src/outgoing_message.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ pub(crate) struct OutgoingError {
142142
#[cfg(test)]
143143
mod tests {
144144
use codex_app_server_protocol::LoginChatGptCompleteNotification;
145+
use codex_protocol::protocol::RateLimitSnapshot;
146+
use codex_protocol::protocol::RateLimitWindow;
145147
use pretty_assertions::assert_eq;
146148
use serde_json::json;
147149
use uuid::Uuid;
@@ -171,4 +173,34 @@ mod tests {
171173
"ensure the strum macros serialize the method field correctly"
172174
);
173175
}
176+
177+
#[test]
178+
fn verify_account_rate_limits_notification_serialization() {
179+
let notification = ServerNotification::AccountRateLimitsUpdated(RateLimitSnapshot {
180+
primary: Some(RateLimitWindow {
181+
used_percent: 25.0,
182+
window_minutes: Some(15),
183+
resets_at: Some(123),
184+
}),
185+
secondary: None,
186+
});
187+
188+
let jsonrpc_notification = OutgoingMessage::AppServerNotification(notification);
189+
assert_eq!(
190+
json!({
191+
"method": "account/rateLimits/updated",
192+
"params": {
193+
"primary": {
194+
"used_percent": 25.0,
195+
"window_minutes": 15,
196+
"resets_at": 123,
197+
},
198+
"secondary": null,
199+
},
200+
}),
201+
serde_json::to_value(jsonrpc_notification)
202+
.expect("ensure the notification serializes correctly"),
203+
"ensure the notification serializes correctly"
204+
);
205+
}
174206
}

0 commit comments

Comments
 (0)