mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-08 18:37:46 +08:00
Add provider key cycle stats reset handling
This commit is contained in:
@@ -322,7 +322,11 @@ fn admin_pool_codex_window_usage_bounds(
|
||||
let reset_at = admin_pool_json_to_u64(window.get("reset_at"))?;
|
||||
let window_minutes = admin_pool_json_to_u64(window.get("window_minutes"))?;
|
||||
let window_seconds = window_minutes.checked_mul(60)?;
|
||||
let start = reset_at.checked_sub(window_seconds)?;
|
||||
let window_start = reset_at.checked_sub(window_seconds)?;
|
||||
let usage_reset_at = admin_pool_json_to_u64(window.get("usage_reset_at"))
|
||||
.filter(|reset_at_override| *reset_at_override < reset_at)
|
||||
.unwrap_or(window_start);
|
||||
let start = window_start.max(usage_reset_at);
|
||||
(start < reset_at).then_some((start, reset_at))
|
||||
}
|
||||
|
||||
@@ -1226,3 +1230,41 @@ pub(super) fn build_admin_pool_key_payload(
|
||||
|
||||
serde_json::Value::Object(payload)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde_json::json;
|
||||
|
||||
#[test]
|
||||
fn codex_window_usage_bounds_honor_manual_usage_reset_at() {
|
||||
let window = json!({
|
||||
"code": "5h",
|
||||
"reset_at": 20_000,
|
||||
"window_minutes": 300,
|
||||
"usage_reset_at": 9_000,
|
||||
});
|
||||
let window = window.as_object().expect("window object");
|
||||
|
||||
assert_eq!(
|
||||
admin_pool_codex_window_usage_bounds(window),
|
||||
Some((9_000, 20_000))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn codex_window_usage_bounds_ignore_reset_before_window_start() {
|
||||
let window = json!({
|
||||
"code": "weekly",
|
||||
"reset_at": 700_000,
|
||||
"window_minutes": 10_080,
|
||||
"usage_reset_at": 1,
|
||||
});
|
||||
let window = window.as_object().expect("window object");
|
||||
|
||||
assert_eq!(
|
||||
admin_pool_codex_window_usage_bounds(window),
|
||||
Some((95_200, 700_000))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,23 +255,34 @@ pub(super) async fn build_admin_pool_list_keys_response(
|
||||
};
|
||||
let codex_window_usage_requests =
|
||||
pool_payloads::build_admin_pool_codex_window_usage_requests(&provider.provider_type, &keys);
|
||||
let codex_window_usage_by_key: pool_payloads::AdminPoolCodexWindowUsageByKey =
|
||||
if codex_window_usage_requests.is_empty() {
|
||||
pool_payloads::AdminPoolCodexWindowUsageByKey::new()
|
||||
} else {
|
||||
state
|
||||
.app()
|
||||
.summarize_usage_by_provider_api_key_windows(&codex_window_usage_requests)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|usage| {
|
||||
(
|
||||
(usage.provider_api_key_id.clone(), usage.window_code.clone()),
|
||||
usage,
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
let mut codex_window_usage_by_key = codex_window_usage_requests
|
||||
.iter()
|
||||
.map(|request| {
|
||||
(
|
||||
(
|
||||
request.provider_api_key_id.clone(),
|
||||
request.window_code.clone(),
|
||||
),
|
||||
aether_data_contracts::repository::usage::StoredProviderApiKeyWindowUsageSummary {
|
||||
provider_api_key_id: request.provider_api_key_id.clone(),
|
||||
window_code: request.window_code.clone(),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect::<pool_payloads::AdminPoolCodexWindowUsageByKey>();
|
||||
if !codex_window_usage_requests.is_empty() {
|
||||
for usage in state
|
||||
.app()
|
||||
.summarize_usage_by_provider_api_key_windows(&codex_window_usage_requests)
|
||||
.await?
|
||||
{
|
||||
codex_window_usage_by_key.insert(
|
||||
(usage.provider_api_key_id.clone(), usage.window_code.clone()),
|
||||
usage,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let items = keys
|
||||
.into_iter()
|
||||
|
||||
@@ -37,7 +37,7 @@ pub(crate) struct AdminPoolKeySort {
|
||||
impl Default for AdminPoolKeySort {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
field: AdminPoolKeySortField::Default,
|
||||
field: AdminPoolKeySortField::ImportedAt,
|
||||
direction: AdminPoolKeySortDirection::Desc,
|
||||
}
|
||||
}
|
||||
@@ -117,7 +117,8 @@ pub(crate) fn parse_admin_pool_key_sort(query: Option<&str>) -> Result<AdminPool
|
||||
.filter(|value| !value.is_empty())
|
||||
.as_deref()
|
||||
{
|
||||
None | Some("default") | Some("name") => AdminPoolKeySortField::Default,
|
||||
None | Some("default") => AdminPoolKeySortField::ImportedAt,
|
||||
Some("name") => AdminPoolKeySortField::Default,
|
||||
Some("imported_at") | Some("created_at") => AdminPoolKeySortField::ImportedAt,
|
||||
Some("last_used_at") | Some("last_used") => AdminPoolKeySortField::LastUsedAt,
|
||||
Some(_) => {
|
||||
|
||||
Reference in New Issue
Block a user