mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-08-03 19:12:04 +08:00
feat(providers): add Volcengine Ark usage query with AK/SK signing
Query coding-plan / agent-plan usage for Volcengine Ark via the control-plane OpenAPI (open.volcengineapi.com), which requires account-level AccessKey signing rather than the inference API key. - Implement Volcengine Signature V4 (an AWS SigV4 variant: fixed canonical header order, "HMAC-SHA256" algorithm without the AWS4 prefix, scope ending in "request", service "ark") in services/coding_plan.rs - Auto-detect the plan by probing GetAFPUsage (Agent Plan, AFP five-hour/weekly/monthly quotas) first, falling back to GetCodingPlanUsage (Coding Plan, session/weekly/monthly percentages); a single credential covers whichever plan the account holds - Parse the real response shape: the window label lives in the `Level` field; guard ResetTimestamp <= 0 (session returns -1) - Store account-level credentials on UsageScript (accessKeyId / secretAccessKey), threaded through both the test command and the TOKEN_PLAN auto-refresh path - Add an independent AK/SK input block with a detailed hint pointing to the Volcengine console -> API Access Keys - Add the `monthly` tier label (frontend TIER_I18N_KEYS + tray TIER_LABEL_GROUPS + subscription service) - Sync zh / en / ja / zh-TW locales and the usage-query docs
This commit is contained in:
+34
-1
@@ -19,6 +19,8 @@ const W_TIER_NAMES: &[&str] = &[
|
||||
crate::services::subscription::TIER_SEVEN_DAY_OPUS,
|
||||
crate::services::subscription::TIER_SEVEN_DAY_SONNET,
|
||||
];
|
||||
// 火山方舟 Agent/Coding Plan 的月窗口(5h/周/月 三档)。
|
||||
const M_TIER_NAMES: &[&str] = &[crate::services::subscription::TIER_MONTHLY];
|
||||
const GEMINI_PRO_TIER_NAMES: &[&str] = &[crate::services::subscription::TIER_GEMINI_PRO];
|
||||
const GEMINI_FLASH_TIER_NAMES: &[&str] = &[crate::services::subscription::TIER_GEMINI_FLASH];
|
||||
const GEMINI_FLASH_LITE_TIER_NAMES: &[&str] =
|
||||
@@ -26,6 +28,7 @@ const GEMINI_FLASH_LITE_TIER_NAMES: &[&str] =
|
||||
const TIER_LABEL_GROUPS: &[(&str, &[&str])] = &[
|
||||
("h", H_TIER_NAMES),
|
||||
("w", W_TIER_NAMES),
|
||||
("m", M_TIER_NAMES),
|
||||
("p", GEMINI_PRO_TIER_NAMES),
|
||||
("f", GEMINI_FLASH_TIER_NAMES),
|
||||
("l", GEMINI_FLASH_LITE_TIER_NAMES),
|
||||
@@ -878,7 +881,7 @@ mod tests {
|
||||
use crate::provider::{UsageData, UsageResult};
|
||||
use crate::services::subscription::{
|
||||
CredentialStatus, QuotaTier, SubscriptionQuota, TIER_FIVE_HOUR, TIER_GEMINI_FLASH,
|
||||
TIER_GEMINI_FLASH_LITE, TIER_GEMINI_PRO, TIER_SEVEN_DAY, TIER_SEVEN_DAY_OPUS,
|
||||
TIER_GEMINI_FLASH_LITE, TIER_GEMINI_PRO, TIER_MONTHLY, TIER_SEVEN_DAY, TIER_SEVEN_DAY_OPUS,
|
||||
TIER_SEVEN_DAY_SONNET, TIER_WEEKLY_LIMIT,
|
||||
};
|
||||
|
||||
@@ -1094,6 +1097,36 @@ mod tests {
|
||||
assert!(s.contains("w50%"), "expected w50% in {s}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn script_summary_token_plan_volcengine_three_tiers_with_monthly() {
|
||||
// 火山方舟 Agent Plan 回 5h/周/月三档,托盘应包含 m(月)窗口,
|
||||
// 不再静默丢弃。
|
||||
let r = usage_result(
|
||||
true,
|
||||
vec![
|
||||
usage_data(Some(TIER_FIVE_HOUR), 25.0),
|
||||
usage_data(Some(TIER_WEEKLY_LIMIT), 30.0),
|
||||
usage_data(Some(TIER_MONTHLY), 42.0),
|
||||
],
|
||||
);
|
||||
let s = format_script_summary(&r).expect("should format");
|
||||
assert!(s.contains("h25%"), "expected h25% in {s}");
|
||||
assert!(s.contains("w30%"), "expected w30% in {s}");
|
||||
assert!(s.contains("m42%"), "expected m42% in {s}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn script_summary_token_plan_monthly_only_renders_label_not_raw_name() {
|
||||
// 仅月窗口激活时不应回落到原始 "monthly" 机器名,而是走 m 标签。
|
||||
let r = usage_result(true, vec![usage_data(Some(TIER_MONTHLY), 60.0)]);
|
||||
let s = format_script_summary(&r).expect("should format");
|
||||
assert!(s.contains("m60%"), "expected m60% in {s}");
|
||||
assert!(
|
||||
!s.contains("monthly"),
|
||||
"raw tier name should not leak into label: {s}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn script_summary_official_subscription_claude_uses_h_and_w_labels() {
|
||||
let r = usage_result(
|
||||
|
||||
Reference in New Issue
Block a user