mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-05 00:47:48 +08:00
增加 Codex 重置次数功能
This commit is contained in:
@@ -16,7 +16,8 @@ pub use presets::{
|
||||
pub use provider::{ProviderPoolAdapter, ProviderPoolMemberInput};
|
||||
pub use providers::{
|
||||
build_antigravity_pool_quota_request, build_chatgpt_web_pool_quota_request,
|
||||
build_codex_pool_quota_request, build_gemini_cli_pool_quota_request,
|
||||
build_codex_pool_quota_request, build_codex_pool_reset_credit_consume_request,
|
||||
build_codex_pool_reset_credits_request, build_gemini_cli_pool_quota_request,
|
||||
build_kiro_pool_quota_request, build_windsurf_pool_model_configs_request,
|
||||
build_windsurf_pool_model_configs_request_with_base_url, build_windsurf_pool_quota_request,
|
||||
build_windsurf_pool_quota_request_with_base_url, build_windsurf_pool_rate_limit_request,
|
||||
@@ -27,7 +28,8 @@ pub use providers::{
|
||||
DefaultProviderPoolAdapter, GeminiCliProviderPoolAdapter, GrokProviderPoolAdapter,
|
||||
KiroPoolQuotaAuthInput, KiroProviderPoolAdapter, UnsupportedQuotaProviderPoolAdapter,
|
||||
ANTIGRAVITY_FETCH_AVAILABLE_MODELS_PATH, CHATGPT_WEB_CONVERSATION_INIT_PATH,
|
||||
CHATGPT_WEB_DEFAULT_BASE_URL, CODEX_WHAM_USAGE_URL, GEMINI_CLI_RETRIEVE_USER_QUOTA_PATH,
|
||||
CHATGPT_WEB_DEFAULT_BASE_URL, CODEX_WHAM_RESET_CREDITS_CONSUME_URL,
|
||||
CODEX_WHAM_RESET_CREDITS_URL, CODEX_WHAM_USAGE_URL, GEMINI_CLI_RETRIEVE_USER_QUOTA_PATH,
|
||||
GEMINI_CLI_USER_AGENT, KIRO_USAGE_LIMITS_PATH, KIRO_USAGE_SDK_VERSION,
|
||||
WINDSURF_MODEL_CONFIGS_PATH, WINDSURF_RATE_LIMIT_PATH, WINDSURF_USER_STATUS_PATH,
|
||||
};
|
||||
@@ -215,6 +217,65 @@ mod tests {
|
||||
assert_eq!(spec.model_name.as_deref(), Some("codex-wham-usage"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn codex_reset_credits_request_uses_wham_detail_endpoint() {
|
||||
let spec = build_codex_pool_reset_credits_request(
|
||||
"key-1",
|
||||
Some(("authorization".to_string(), "Bearer access".to_string())),
|
||||
None,
|
||||
Some(&json!({
|
||||
"plan_type": "plus",
|
||||
"account_id": "acct-1"
|
||||
})),
|
||||
)
|
||||
.expect("spec should build");
|
||||
|
||||
assert_eq!(spec.method, "GET");
|
||||
assert_eq!(spec.url, CODEX_WHAM_RESET_CREDITS_URL);
|
||||
assert_eq!(
|
||||
spec.headers.get("authorization").map(String::as_str),
|
||||
Some("Bearer access")
|
||||
);
|
||||
assert_eq!(
|
||||
spec.headers.get("chatgpt-account-id").map(String::as_str),
|
||||
Some("acct-1")
|
||||
);
|
||||
assert_eq!(spec.model_name.as_deref(), Some("codex-wham-reset-credits"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn codex_reset_credit_consume_request_posts_redeem_request_id() {
|
||||
let spec = build_codex_pool_reset_credit_consume_request(
|
||||
"key-1",
|
||||
Some(("authorization".to_string(), "Bearer access".to_string())),
|
||||
None,
|
||||
None,
|
||||
"8ae6f1c7-7e9e-4f5d-9b8a-000000000000",
|
||||
)
|
||||
.expect("spec should build");
|
||||
|
||||
assert_eq!(spec.method, "POST");
|
||||
assert_eq!(spec.url, CODEX_WHAM_RESET_CREDITS_CONSUME_URL);
|
||||
assert_eq!(spec.content_type.as_deref(), Some("application/json"));
|
||||
assert_eq!(
|
||||
spec.json_body
|
||||
.as_ref()
|
||||
.and_then(|body| body.get("redeem_request_id")),
|
||||
Some(&json!("8ae6f1c7-7e9e-4f5d-9b8a-000000000000"))
|
||||
);
|
||||
assert_eq!(
|
||||
spec.json_body
|
||||
.as_ref()
|
||||
.and_then(|body| body.as_object())
|
||||
.map(|body| body.len()),
|
||||
Some(1)
|
||||
);
|
||||
assert_eq!(
|
||||
spec.model_name.as_deref(),
|
||||
Some("codex-wham-reset-credit-consume")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn codex_quota_request_skips_account_header_for_free_accounts() {
|
||||
let spec = build_codex_pool_quota_request(
|
||||
|
||||
@@ -17,6 +17,10 @@ use crate::quota::{
|
||||
use crate::quota_refresh::ProviderPoolQuotaRequestSpec;
|
||||
|
||||
pub const CODEX_WHAM_USAGE_URL: &str = "https://chatgpt.com/backend-api/wham/usage";
|
||||
pub const CODEX_WHAM_RESET_CREDITS_URL: &str =
|
||||
"https://chatgpt.com/backend-api/wham/rate-limit-reset-credits";
|
||||
pub const CODEX_WHAM_RESET_CREDITS_CONSUME_URL: &str =
|
||||
"https://chatgpt.com/backend-api/wham/rate-limit-reset-credits/consume";
|
||||
const PLACEHOLDER_API_KEY: &str = "__placeholder__";
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
@@ -68,12 +72,11 @@ impl ProviderPoolAdapter for CodexProviderPoolAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_codex_pool_quota_request(
|
||||
key_id: &str,
|
||||
fn build_codex_wham_headers(
|
||||
resolved_oauth_auth: Option<(String, String)>,
|
||||
decrypted_api_key: Option<&str>,
|
||||
auth_config: Option<&Value>,
|
||||
) -> Result<ProviderPoolQuotaRequestSpec, String> {
|
||||
) -> Result<BTreeMap<String, String>, String> {
|
||||
let mut headers = BTreeMap::new();
|
||||
headers.insert("accept".to_string(), "application/json".to_string());
|
||||
let auth_config_headers = auth_config
|
||||
@@ -120,6 +123,17 @@ pub fn build_codex_pool_quota_request(
|
||||
);
|
||||
}
|
||||
|
||||
Ok(headers)
|
||||
}
|
||||
|
||||
pub fn build_codex_pool_quota_request(
|
||||
key_id: &str,
|
||||
resolved_oauth_auth: Option<(String, String)>,
|
||||
decrypted_api_key: Option<&str>,
|
||||
auth_config: Option<&Value>,
|
||||
) -> Result<ProviderPoolQuotaRequestSpec, String> {
|
||||
let headers = build_codex_wham_headers(resolved_oauth_auth, decrypted_api_key, auth_config)?;
|
||||
|
||||
Ok(ProviderPoolQuotaRequestSpec {
|
||||
request_id: format!("codex-quota:{key_id}"),
|
||||
provider_name: "codex".to_string(),
|
||||
@@ -136,6 +150,64 @@ pub fn build_codex_pool_quota_request(
|
||||
})
|
||||
}
|
||||
|
||||
pub fn build_codex_pool_reset_credits_request(
|
||||
key_id: &str,
|
||||
resolved_oauth_auth: Option<(String, String)>,
|
||||
decrypted_api_key: Option<&str>,
|
||||
auth_config: Option<&Value>,
|
||||
) -> Result<ProviderPoolQuotaRequestSpec, String> {
|
||||
let headers = build_codex_wham_headers(resolved_oauth_auth, decrypted_api_key, auth_config)?;
|
||||
|
||||
Ok(ProviderPoolQuotaRequestSpec {
|
||||
request_id: format!("codex-reset-credits:{key_id}"),
|
||||
provider_name: "codex".to_string(),
|
||||
quota_kind: "codex_reset_credits".to_string(),
|
||||
method: "GET".to_string(),
|
||||
url: CODEX_WHAM_RESET_CREDITS_URL.to_string(),
|
||||
headers,
|
||||
content_type: None,
|
||||
json_body: None,
|
||||
client_api_format: "openai:responses".to_string(),
|
||||
provider_api_format: "openai:responses".to_string(),
|
||||
model_name: Some("codex-wham-reset-credits".to_string()),
|
||||
accept_invalid_certs: false,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn build_codex_pool_reset_credit_consume_request(
|
||||
key_id: &str,
|
||||
resolved_oauth_auth: Option<(String, String)>,
|
||||
decrypted_api_key: Option<&str>,
|
||||
auth_config: Option<&Value>,
|
||||
redeem_request_id: &str,
|
||||
) -> Result<ProviderPoolQuotaRequestSpec, String> {
|
||||
let redeem_request_id = redeem_request_id.trim();
|
||||
if redeem_request_id.is_empty() {
|
||||
return Err("缺少 Codex reset credit 幂等请求 ID".to_string());
|
||||
}
|
||||
|
||||
let mut headers =
|
||||
build_codex_wham_headers(resolved_oauth_auth, decrypted_api_key, auth_config)?;
|
||||
headers.insert("content-type".to_string(), "application/json".to_string());
|
||||
|
||||
Ok(ProviderPoolQuotaRequestSpec {
|
||||
request_id: format!("codex-reset-credit-consume:{key_id}:{redeem_request_id}"),
|
||||
provider_name: "codex".to_string(),
|
||||
quota_kind: "codex_reset_credit_consume".to_string(),
|
||||
method: "POST".to_string(),
|
||||
url: CODEX_WHAM_RESET_CREDITS_CONSUME_URL.to_string(),
|
||||
headers,
|
||||
content_type: Some("application/json".to_string()),
|
||||
json_body: Some(serde_json::json!({
|
||||
"redeem_request_id": redeem_request_id,
|
||||
})),
|
||||
client_api_format: "openai:responses".to_string(),
|
||||
provider_api_format: "openai:responses".to_string(),
|
||||
model_name: Some("codex-wham-reset-credit-consume".to_string()),
|
||||
accept_invalid_certs: false,
|
||||
})
|
||||
}
|
||||
|
||||
fn codex_window_reset_elapsed(bucket: &Map<String, Value>, prefix: &str) -> bool {
|
||||
let Some(now_unix_secs) = provider_pool_current_unix_secs() else {
|
||||
return false;
|
||||
|
||||
@@ -19,7 +19,11 @@ pub use chatgpt_web::{
|
||||
CHATGPT_WEB_DEFAULT_BASE_URL,
|
||||
};
|
||||
pub use codex::CodexProviderPoolAdapter;
|
||||
pub use codex::{build_codex_pool_quota_request, CODEX_WHAM_USAGE_URL};
|
||||
pub use codex::{
|
||||
build_codex_pool_quota_request, build_codex_pool_reset_credit_consume_request,
|
||||
build_codex_pool_reset_credits_request, CODEX_WHAM_RESET_CREDITS_CONSUME_URL,
|
||||
CODEX_WHAM_RESET_CREDITS_URL, CODEX_WHAM_USAGE_URL,
|
||||
};
|
||||
pub use default::DefaultProviderPoolAdapter;
|
||||
pub use gemini_cli::GeminiCliProviderPoolAdapter;
|
||||
pub use gemini_cli::{
|
||||
|
||||
Reference in New Issue
Block a user